You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by jk...@apache.org on 2023/03/07 16:35:00 UTC

[unomi] branch UNOMI-737-indices-reduction-migration updated: UNOMI-737: add integration test

This is an automated email from the ASF dual-hosted git repository.

jkevan pushed a commit to branch UNOMI-737-indices-reduction-migration
in repository https://gitbox.apache.org/repos/asf/unomi.git


The following commit(s) were added to refs/heads/UNOMI-737-indices-reduction-migration by this push:
     new 0b5fb09d2 UNOMI-737: add integration test
0b5fb09d2 is described below

commit 0b5fb09d2ca10b6180c5a5d4377c5d2e401b53dc
Author: Kevan <ke...@jahia.com>
AuthorDate: Tue Mar 7 17:34:48 2023 +0100

    UNOMI-737: add integration test
---
 .../test/java/org/apache/unomi/itests/BaseIT.java  |   6 -
 .../unomi/itests/migration/Migrate16xTo220IT.java  |  25 +--
 .../ElasticSearchPersistenceServiceImpl.java       | 191 +++++++++++----------
 .../unomi/persistence/spi/PersistenceService.java  |  24 +--
 .../services/impl/profiles/ProfileServiceImpl.java |  46 +----
 5 files changed, 117 insertions(+), 175 deletions(-)

diff --git a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
index 1f5ebf1a4..7e4e20cfa 100644
--- a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
@@ -214,12 +214,6 @@ public abstract class BaseIT extends KarafTestSupport {
         refreshPersistence();
     }
 
-    protected void recreateIndex(final String itemType) {
-        if (persistenceService.removeIndex(itemType)) {
-            persistenceService.createIndex(itemType);
-        }
-    }
-
     protected void refreshPersistence() throws InterruptedException {
         persistenceService.refresh();
         Thread.sleep(1000);
diff --git a/itests/src/test/java/org/apache/unomi/itests/migration/Migrate16xTo220IT.java b/itests/src/test/java/org/apache/unomi/itests/migration/Migrate16xTo220IT.java
index 9ddbd941a..7dc321268 100644
--- a/itests/src/test/java/org/apache/unomi/itests/migration/Migrate16xTo220IT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/migration/Migrate16xTo220IT.java
@@ -38,12 +38,11 @@ public class Migrate16xTo220IT extends BaseIT {
 
     private int eventCount = 0;
     private int sessionCount = 0;
-    private int systemItemsCount = 0;
 
     private static final int NUMBER_DUPLICATE_SESSIONS = 3;
-    private static final List<String> oldSystemItemsIndices = Arrays.asList("actionType", "campaign", "campaignevent", "goal",
-            "userList", "propertyType", "scope", "conditionType", "rule", "scoring", "segment", "groovyAction", "topic",
-            "patch", "jsonSchema", "importConfig", "exportConfig", "rulestats");
+    private static final List<String> oldSystemItemsIndices = Arrays.asList("context-actiontype", "context-campaign", "context-campaignevent", "context-goal",
+            "context-userlist", "context-propertytype", "context-scope", "context-conditiontype", "context-rule", "context-scoring", "context-segment", "context-groovyaction", "context-topic",
+            "context-patch", "context-jsonschema", "context-importconfig", "context-exportconfig", "context-rulestats");
 
     @Override
     @Before
@@ -113,12 +112,12 @@ public class Migrate16xTo220IT extends BaseIT {
 
         int newEventcount = 0;
         for (String eventIndex : MigrationUtils.getIndexesPrefixedBy(httpClient, "http://localhost:9400", "context-event-0")) {
-            newEventcount += countItems(eventIndex, null);
+            newEventcount += countItems(httpClient, eventIndex, null);
         }
 
         int newSessioncount = 0;
         for (String sessionIndex : MigrationUtils.getIndexesPrefixedBy(httpClient, "http://localhost:9400", "context-session-0")) {
-            newSessioncount += countItems(sessionIndex, null);
+            newSessioncount += countItems(httpClient, sessionIndex, null);
         }
         Assert.assertEquals(eventCount, newEventcount);
         Assert.assertEquals(sessionCount - NUMBER_DUPLICATE_SESSIONS, newSessioncount);
@@ -132,10 +131,6 @@ public class Migrate16xTo220IT extends BaseIT {
         for (String oldSystemItemsIndex : oldSystemItemsIndices) {
             Assert.assertFalse(MigrationUtils.indexExists(httpClient, "http://localhost:9400", oldSystemItemsIndex));
         }
-
-        // check counts
-        Assert.assertEquals("Expect same number of system items (rules, segments, etc ...) after 2_2_0 migration",
-                systemItemsCount, countItems("context-systemitems", null));
     }
 
     /**
@@ -319,22 +314,18 @@ public class Migrate16xTo220IT extends BaseIT {
     private void initCounts(CloseableHttpClient httpClient) {
         try {
             for (String eventIndex : MigrationUtils.getIndexesPrefixedBy(httpClient, "http://localhost:9400", "context-event-date")) {
-                eventCount += countItems(eventIndex, resourceAsString("migration/must_not_match_some_eventype_body.json"));
+                eventCount += countItems(httpClient, eventIndex, resourceAsString("migration/must_not_match_some_eventype_body.json"));
             }
 
             for (String sessionIndex : MigrationUtils.getIndexesPrefixedBy(httpClient, "http://localhost:9400", "context-session-date")) {
-                sessionCount += countItems(sessionIndex, null);
-            }
-
-            for (String oldSystemItemsIndex : oldSystemItemsIndices) {
-                systemItemsCount += countItems(oldSystemItemsIndex, null);
+                sessionCount += countItems(httpClient, sessionIndex, null);
             }
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
 
-    private int countItems(String index, String requestBody) throws IOException {
+    private int countItems(CloseableHttpClient httpClient, String index, String requestBody) throws IOException {
         if (requestBody == null) {
             requestBody = resourceAsString("migration/must_not_match_some_eventype_body.json");
         }
diff --git a/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java b/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
index 381f1a139..f0929887b 100644
--- a/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
+++ b/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
@@ -151,8 +151,6 @@ import java.security.cert.X509Certificate;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import static org.elasticsearch.index.query.QueryBuilders.termQuery;
 
@@ -1256,78 +1254,81 @@ public class ElasticSearchPersistenceServiceImpl implements PersistenceService,
     public <T extends Item> boolean removeByQuery(final Condition query, final Class<T> clazz) {
         Boolean result = new InClassLoaderExecute<Boolean>(metricsService, this.getClass().getName() + ".removeByQuery", this.bundleContext, this.fatalIllegalStateErrors, throwExceptions) {
             protected Boolean execute(Object... args) throws Exception {
-                try {
-                    String itemType = Item.getItemType(clazz);
-                    QueryBuilder queryBuilder = conditionESQueryBuilderDispatcher.getQueryBuilder(query);
-                    final DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(getIndexNameForQuery(itemType))
-                            .setQuery(isItemTypeSharingIndex(itemType) ? wrapWithItemTypeQuery(itemType, queryBuilder) : queryBuilder)
-                            // Setting slices to auto will let Elasticsearch choose the number of slices to use.
-                            // This setting will use one slice per shard, up to a certain limit.
-                            // The delete request will be more efficient and faster than no slicing.
-                            .setSlices(AbstractBulkByScrollRequest.AUTO_SLICES)
-                            // Elasticsearch takes a snapshot of the index when you hit delete by query request and uses the _version of the documents to process the request.
-                            // If a document gets updated in the meantime, it will result in a version conflict error and the delete operation will fail.
-                            // So we explicitly set the conflict strategy to proceed in case of version conflict.
-                            .setAbortOnVersionConflict(false)
-                            // Remove by Query is mostly used for purge and cleaning up old data
-                            // It's mostly used in jobs/timed tasks so we don't really care about long request
-                            // So we increase default timeout of 1min to 10min
-                            .setTimeout(TimeValue.timeValueMinutes(removeByQueryTimeoutInMinutes));
-
-                    BulkByScrollResponse bulkByScrollResponse = client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
-
-                    if (bulkByScrollResponse == null) {
-                        logger.error("Remove by query: no response returned for query: {}", query);
-                        return false;
-                    }
+                QueryBuilder queryBuilder = conditionESQueryBuilderDispatcher.getQueryBuilder(query);
+                return removeByQuery(queryBuilder, clazz);
+            }
+        }.catchingExecuteInClassLoader(true);
+        if (result == null) {
+            return false;
+        } else {
+            return result;
+        }
+    }
 
-                    if (bulkByScrollResponse.isTimedOut()) {
-                        logger.warn("Remove by query: timed out because took more than {} minutes for query: {}", removeByQueryTimeoutInMinutes, query);
-                    }
+    public <T extends Item> boolean removeByQuery(QueryBuilder queryBuilder, final Class<T> clazz) throws Exception {
+        try {
+            String itemType = Item.getItemType(clazz);
+            final DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(getIndexNameForQuery(itemType))
+                    .setQuery(isItemTypeSharingIndex(itemType) ? wrapWithItemTypeQuery(itemType, queryBuilder) : queryBuilder)
+                    // Setting slices to auto will let Elasticsearch choose the number of slices to use.
+                    // This setting will use one slice per shard, up to a certain limit.
+                    // The delete request will be more efficient and faster than no slicing.
+                    .setSlices(AbstractBulkByScrollRequest.AUTO_SLICES)
+                    // Elasticsearch takes a snapshot of the index when you hit delete by query request and uses the _version of the documents to process the request.
+                    // If a document gets updated in the meantime, it will result in a version conflict error and the delete operation will fail.
+                    // So we explicitly set the conflict strategy to proceed in case of version conflict.
+                    .setAbortOnVersionConflict(false)
+                    // Remove by Query is mostly used for purge and cleaning up old data
+                    // It's mostly used in jobs/timed tasks so we don't really care about long request
+                    // So we increase default timeout of 1min to 10min
+                    .setTimeout(TimeValue.timeValueMinutes(removeByQueryTimeoutInMinutes));
+
+            BulkByScrollResponse bulkByScrollResponse = client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
+
+            if (bulkByScrollResponse == null) {
+                logger.error("Remove by query: no response returned for query: {}", queryBuilder);
+                return false;
+            }
 
-                    if ((bulkByScrollResponse.getSearchFailures() != null && bulkByScrollResponse.getSearchFailures().size() > 0) ||
-                            bulkByScrollResponse.getBulkFailures() != null && bulkByScrollResponse.getBulkFailures().size() > 0) {
-                        logger.warn("Remove by query: we found some failure during the process of query: {}", query);
+            if (bulkByScrollResponse.isTimedOut()) {
+                logger.warn("Remove by query: timed out because took more than {} minutes for query: {}", removeByQueryTimeoutInMinutes, queryBuilder);
+            }
 
-                        if (bulkByScrollResponse.getSearchFailures() != null && bulkByScrollResponse.getSearchFailures().size() > 0) {
-                            for (ScrollableHitSource.SearchFailure searchFailure : bulkByScrollResponse.getSearchFailures()) {
-                                logger.warn("Remove by query, search failure: {}", searchFailure.toString());
-                            }
-                        }
+            if ((bulkByScrollResponse.getSearchFailures() != null && bulkByScrollResponse.getSearchFailures().size() > 0) ||
+                    bulkByScrollResponse.getBulkFailures() != null && bulkByScrollResponse.getBulkFailures().size() > 0) {
+                logger.warn("Remove by query: we found some failure during the process of query: {}", queryBuilder);
 
-                        if (bulkByScrollResponse.getBulkFailures() != null && bulkByScrollResponse.getBulkFailures().size() > 0) {
-                            for (BulkItemResponse.Failure bulkFailure : bulkByScrollResponse.getBulkFailures()) {
-                                logger.warn("Remove by query, bulk failure: {}", bulkFailure.toString());
-                            }
-                        }
+                if (bulkByScrollResponse.getSearchFailures() != null && bulkByScrollResponse.getSearchFailures().size() > 0) {
+                    for (ScrollableHitSource.SearchFailure searchFailure : bulkByScrollResponse.getSearchFailures()) {
+                        logger.warn("Remove by query, search failure: {}", searchFailure.toString());
                     }
+                }
 
-                    if (logger.isDebugEnabled()) {
-                        logger.debug("Remove by query: took {}, deleted docs: {}, batches executed: {}, skipped docs: {}, version conflicts: {}, search retries: {}, bulk retries: {}, for query: {}",
-                                bulkByScrollResponse.getTook().toHumanReadableString(1),
-                                bulkByScrollResponse.getDeleted(),
-                                bulkByScrollResponse.getBatches(),
-                                bulkByScrollResponse.getNoops(),
-                                bulkByScrollResponse.getVersionConflicts(),
-                                bulkByScrollResponse.getSearchRetries(),
-                                bulkByScrollResponse.getBulkRetries(),
-                                query);
+                if (bulkByScrollResponse.getBulkFailures() != null && bulkByScrollResponse.getBulkFailures().size() > 0) {
+                    for (BulkItemResponse.Failure bulkFailure : bulkByScrollResponse.getBulkFailures()) {
+                        logger.warn("Remove by query, bulk failure: {}", bulkFailure.toString());
                     }
-
-                    return true;
-                } catch (Exception e) {
-                    throw new Exception("Cannot remove by query", e);
                 }
             }
-        }.catchingExecuteInClassLoader(true);
-        if (result == null) {
-            return false;
-        } else {
-            return result;
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("Remove by query: took {}, deleted docs: {}, batches executed: {}, skipped docs: {}, version conflicts: {}, search retries: {}, bulk retries: {}, for query: {}",
+                        bulkByScrollResponse.getTook().toHumanReadableString(1),
+                        bulkByScrollResponse.getDeleted(),
+                        bulkByScrollResponse.getBatches(),
+                        bulkByScrollResponse.getNoops(),
+                        bulkByScrollResponse.getVersionConflicts(),
+                        bulkByScrollResponse.getSearchRetries(),
+                        bulkByScrollResponse.getBulkRetries(),
+                        queryBuilder);
+            }
+
+            return true;
+        } catch (Exception e) {
+            throw new Exception("Cannot remove by query", e);
         }
     }
 
-
     public boolean indexTemplateExists(final String templateName) {
         Boolean result = new InClassLoaderExecute<Boolean>(metricsService, this.getClass().getName() + ".indexTemplateExists", this.bundleContext, this.fatalIllegalStateErrors, throwExceptions) {
             protected Boolean execute(Object... args) throws IOException {
@@ -1415,8 +1416,8 @@ public class ElasticSearchPersistenceServiceImpl implements PersistenceService,
         }
     }
 
-    public boolean removeIndex(final String itemType, boolean addPrefix){
-        String index = addPrefix ? getIndex(itemType) : itemType;
+    public boolean removeIndex(final String itemType) {
+        String index = getIndex(itemType);
 
         Boolean result = new InClassLoaderExecute<Boolean>(metricsService, this.getClass().getName() + ".removeIndex", this.bundleContext, this.fatalIllegalStateErrors, throwExceptions) {
             protected Boolean execute(Object... args) throws IOException {
@@ -1436,9 +1437,6 @@ public class ElasticSearchPersistenceServiceImpl implements PersistenceService,
             return result;
         }
     }
-    public boolean removeIndex(final String itemType) {
-        return removeIndex(itemType, true);
-    }
 
     private void internalCreateRolloverTemplate(String itemName) throws IOException {
         String rolloverAlias = indexPrefix + "-" + itemName;
@@ -1890,29 +1888,6 @@ public class ElasticSearchPersistenceServiceImpl implements PersistenceService,
         }
     }
 
-    @Override
-    public Map<String, Long> docCountPerIndex(String... indexes) {
-        return new InClassLoaderExecute<Map<String, Long>>(metricsService, this.getClass().getName() + ".docCountPerIndex", this.bundleContext, this.fatalIllegalStateErrors, throwExceptions) {
-            @Override
-            protected Map<String, Long> execute(Object... args) throws IOException {
-                List<String> indexesForQuery = Stream.of(indexes).map(index -> getIndexNameForQuery(index)).collect(Collectors.toList());
-                String[] itemsArray = new String[indexesForQuery.size()];
-                itemsArray = indexesForQuery.toArray(itemsArray);
-                GetIndexRequest request = new GetIndexRequest(itemsArray);
-                GetIndexResponse getIndexResponse = client.indices().get(request, RequestOptions.DEFAULT);
-
-                Map<String, Long> countPerIndex = new HashMap<>();
-
-                for (String index : getIndexResponse.getIndices()) {
-                    CountRequest countRequest = new CountRequest(index);
-                    CountResponse response = client.count(countRequest, RequestOptions.DEFAULT);
-                    countPerIndex.put(index, response.getCount());
-                }
-                return countPerIndex;
-            }
-        }.catchingExecuteInClassLoader(true);
-    }
-
     private long queryCount(final QueryBuilder filter, final String itemType) {
         return new InClassLoaderExecute<Long>(metricsService, this.getClass().getName() + ".queryCount", this.bundleContext, this.fatalIllegalStateErrors, throwExceptions) {
 
@@ -2392,6 +2367,42 @@ public class ElasticSearchPersistenceServiceImpl implements PersistenceService,
 
     @Override
     public void purge(final Date date) {
+        // nothing, this method is deprecated since 2.2.0
+    }
+
+    @Override
+    public <T extends Item> void purgeTimeBasedItems(int existsNumberOfDays, Class<T> clazz) {
+        new InClassLoaderExecute<Boolean>(metricsService, this.getClass().getName() + ".purgeTimeBasedItems", this.bundleContext, this.fatalIllegalStateErrors, throwExceptions) {
+            protected Boolean execute(Object... args) throws Exception {
+                String itemType = Item.getItemType(clazz);
+
+                if (existsNumberOfDays > 0 && isItemTypeRollingOver(itemType)) {
+                    // First we purge the documents
+                    removeByQuery(QueryBuilders.rangeQuery("timeStamp").lte("now-" + existsNumberOfDays + "d"), clazz);
+
+                    // get count per index for those time based data
+                    TreeMap<String, Long> countsPerIndex = new TreeMap<>();
+                    GetIndexResponse getIndexResponse = client.indices().get(new GetIndexRequest(getIndexNameForQuery(itemType)), RequestOptions.DEFAULT);
+                    for (String index : getIndexResponse.getIndices()) {
+                        countsPerIndex.put(index, client.count(new CountRequest(index), RequestOptions.DEFAULT).getCount());
+                    }
+
+                    // Check for count=0 and remove them
+                    if (countsPerIndex.size() >= 1) {
+                        // do not check the last index, because it's the one used to write documents
+                        countsPerIndex.pollLastEntry();
+
+                        for (Map.Entry<String, Long> indexCount : countsPerIndex.entrySet()) {
+                            if (indexCount.getValue() == 0) {
+                                client.indices().delete(new DeleteIndexRequest(indexCount.getKey()), RequestOptions.DEFAULT);
+                            }
+                        }
+                    }
+                }
+
+                return true;
+            }
+        }.catchingExecuteInClassLoader(true);
     }
 
     @Override
diff --git a/persistence-spi/src/main/java/org/apache/unomi/persistence/spi/PersistenceService.java b/persistence-spi/src/main/java/org/apache/unomi/persistence/spi/PersistenceService.java
index 0e29bd299..29c196a2b 100644
--- a/persistence-spi/src/main/java/org/apache/unomi/persistence/spi/PersistenceService.java
+++ b/persistence-spi/src/main/java/org/apache/unomi/persistence/spi/PersistenceService.java
@@ -677,22 +677,19 @@ public interface PersistenceService {
     <T extends Item> void refreshIndex(Class<T> clazz, Date dateHint);
 
     /**
-     * Purges all data in the context server up to the specified date, not included.
-     *
-     * @param date the date (not included) before which we want to erase all data
+     * deprecated: (use: purgeTimeBasedItems instead)
      */
     @Deprecated
     void purge(Date date);
 
     /**
-     * Retrieves the number of document per indexes.
-     * If the index is a rollover index, each rollover index will be return with its own number of document
-     * For example: with "event" as parameter, the indexes named ...-event-000001, ...-event-000002 and so one will be returned
+     * Purges time based data in the context server up to the specified days number of existence.
+     * (This only works for time based data stored in rolling over indices, it have no effect on other types)
      *
-     * @param indexes names of the indexes to count the documents
-     * @return Map where the key in the index name and the value is the number of document for this index
+     * @param existsNumberOfDays the number of days
+     * @param clazz the item type to be purged
      */
-    Map<String, Long> docCountPerIndex(String... indexes);
+    <T extends Item> void purgeTimeBasedItems(int existsNumberOfDays, Class<T> clazz);
 
     /**
      * Retrieves all items of the specified Item subclass which specified ranged property is within the specified bounds, ordered according to the specified {@code sortBy} String
@@ -745,15 +742,6 @@ public interface PersistenceService {
      */
     boolean removeIndex(final String itemType);
 
-    /**
-     * Removes the index for the specified item type.
-     *
-     * @param itemType the item type
-     * @param addPrefix should add the index prefix to the itemType passed as parameter
-     * @return {@code true} if the operation was successful, {@code false} otherwise
-     */
-    boolean removeIndex(final String itemType, boolean addPrefix);
-
     /**
      * Removes all data associated with the provided scope.
      *
diff --git a/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java
index 7912cc6de..8221f19ff 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java
@@ -370,40 +370,11 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList
         }
     }
 
-    private <T extends Item> void purgeRolloverItems(int existsNumberOfDays, Class<T> clazz) {
-        if (existsNumberOfDays > 0) {
-            String conditionType = null;
-            String itemType = null;
-
-            if (clazz.getName().equals(Event.class.getName())) {
-                conditionType = "eventPropertyCondition";
-                itemType = Event.ITEM_TYPE;
-            } else if (clazz.getName().equals(Session.class.getName())) {
-                conditionType = "sessionPropertyCondition";
-                itemType = Session.ITEM_TYPE;
-            }
-
-            ConditionType propertyConditionType = definitionsService.getConditionType(conditionType);
-            if (propertyConditionType == null) {
-                // definition service not yet fully instantiate
-                return;
-            }
-
-            Condition condition = new Condition(propertyConditionType);
-
-            condition.setParameter("propertyName", "timeStamp");
-            condition.setParameter("comparisonOperator", "lessThanOrEqualTo");
-            condition.setParameter("propertyValueDateExpr", "now-" + existsNumberOfDays + "d");
-            persistenceService.removeByQuery(condition, clazz);
-            deleteEmptyRolloverIndex(itemType);
-        }
-    }
-
     @Override
     public void purgeSessionItems(int existsNumberOfDays) {
         if (existsNumberOfDays > 0) {
             logger.info("Purging: Sessions created since more than {} days", existsNumberOfDays);
-            purgeRolloverItems(existsNumberOfDays, Session.class);
+            persistenceService.purgeTimeBasedItems(existsNumberOfDays, Session.class);
         }
     }
 
@@ -411,7 +382,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList
     public void purgeEventItems(int existsNumberOfDays) {
         if (existsNumberOfDays > 0) {
             logger.info("Purging: Events created since more than {} days", existsNumberOfDays);
-            purgeRolloverItems(existsNumberOfDays, Event.class);
+            persistenceService.purgeTimeBasedItems(existsNumberOfDays, Event.class);
         }
     }
 
@@ -421,19 +392,6 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList
 
     }
 
-    public void deleteEmptyRolloverIndex(String indexName) {
-        TreeMap<String, Long> countsPerIndex = new TreeMap<>(persistenceService.docCountPerIndex(indexName));
-        if (countsPerIndex.size() >= 1) {
-            // do not check the last index, because it's the one used to write documents
-            countsPerIndex.pollLastEntry();
-            countsPerIndex.forEach((index, count) -> {
-                if (count == 0) {
-                    persistenceService.removeIndex(index, false);
-                }
-            });
-        }
-    }
-
     private void initializePurge() {
         logger.info("Purge: Initializing");