public void retain(IndexSet indexSet, IndexLifetimeConfig config, RetentionExecutor.RetentionAction action, String actionName) {
        final Map<String, Set<String>> deflectorIndices = indexSet.getAllIndexAliases();

        // Account for DST and time zones in determining age
        final DateTime now = clock.nowUTC();
        final long cutoffSoft = now.minus(config.indexLifetimeMin()).getMillis();
        final long cutoffHard = now.minus(config.indexLifetimeMax()).getMillis();
        final int removeCount = (int) deflectorIndices.keySet()
                .stream()
                .filter(indexName -> !indices.isReopened(indexName))
                .filter(indexName -> !hasCurrentWriteAlias(indexSet, deflectorIndices, indexName))
                .filter(indexName -> exceedsAgeLimit(indexName, cutoffSoft, cutoffHard))
                .count();

        if (LOG.isDebugEnabled()) {
            var debug = deflectorIndices.keySet().stream()
                    .collect(Collectors.toMap(k -> k, k -> Map.of(
                            "isReopened", indices.isReopened(k),
                            "hasCurrentWriteAlias", hasCurrentWriteAlias(indexSet, deflectorIndices, k),
                            "exceedsAgeLimit", exceedsAgeLimit(k, cutoffSoft, cutoffHard),
                            "closingDate", indices.indexClosingDate(k),
                            "creationDate", indices.indexCreationDate(k)
                    )));
            Joiner.MapJoiner mapJoiner = Joiner.on("\n").withKeyValueSeparator("=");
            LOG.debug("Debug info retain for indexSet <{}>: (min {}, max {}) removeCount: {} details: <{}>",
                    indexSet.getIndexPrefix(), config.indexLifetimeMin(), config.indexLifetimeMax(),
                    removeCount, mapJoiner.join(debug));
        }

        if (removeCount > 0) {
            final String msg = "Running retention for " + removeCount + " aged-out indices.";
            LOG.info(msg);
            activityWriter.write(new Activity(msg, TimeBasedRetentionExecutor.class));

            retentionExecutor.runRetention(indexSet, removeCount, action, actionName);
        }
    }
@Test
    public void retainTimeBased() {
        underTest.retain(indexSet, getIndexLifetimeConfig(10, 12), action, "action");

        verify(action, times(1)).retain(retainedIndexName.capture(), eq(indexSet));
        assertThat(retainedIndexName.getValue()).containsExactly("test_1", "test_2", "test_3");
    }