@Override
    public void cycle() {
        if (!getConfig().isWritable()) {
            LOG.debug("Not cycling non-writable index set <{}> ({})", getConfig().id(), getConfig().title());
            return;
        }

        int oldTargetNumber;

        try {
            oldTargetNumber = getNewestIndexNumber();
        } catch (NoTargetIndexException ex) {
            oldTargetNumber = -1;
        }
        final int newTargetNumber = oldTargetNumber + 1;

        final String newTarget = buildIndexName(newTargetNumber);
        final String oldTarget = buildIndexName(oldTargetNumber);

        if (oldTargetNumber == -1) {
            LOG.info("Cycling from <none> to <{}>.", newTarget);
        } else {
            LOG.info("Cycling from <{}> to <{}>.", oldTarget, newTarget);
        }

        // Create new index.
        LOG.info("Creating target index <{}>.", newTarget);
        if (!indices.create(newTarget, this)) {
            throw new RuntimeException("Could not create new target index <" + newTarget + ">.");
        }

        LOG.info("Waiting for allocation of index <{}>.", newTarget);
        final HealthStatus healthStatus = indices.waitForRecovery(newTarget);
        checkIfHealthy(healthStatus, (status) -> new RuntimeException("New target index did not become healthy (target index: <" + newTarget + ">)"));
        LOG.debug("Health status of index <{}>: {}", newTarget, healthStatus);

        addDeflectorIndexRange(newTarget);
        LOG.info("Index <{}> has been successfully allocated.", newTarget);

        // Point deflector to new index.
        final String indexAlias = getWriteIndexAlias();
        LOG.info("Pointing index alias <{}> to new index <{}>.", indexAlias, newTarget);

        final Activity activity = new Activity(IndexSet.class);
        if (oldTargetNumber == -1) {
            // Only pointing, not cycling.
            pointTo(newTarget);
            activity.setMessage("Cycled index alias <" + indexAlias + "> from <none> to <" + newTarget + ">.");
        } else {
            // Re-pointing from existing old index to the new one.
            LOG.debug("Switching over index alias <{}>.", indexAlias);
            pointTo(newTarget, oldTarget);
            setIndexReadOnlyAndCalculateRange(oldTarget);
            activity.setMessage("Cycled index alias <" + indexAlias + "> from <" + oldTarget + "> to <" + newTarget + ">.");
        }

        LOG.info("Successfully pointed index alias <{}> to index <{}>.", indexAlias, newTarget);

        activityWriter.write(activity);
        auditEventSender.success(AuditActor.system(nodeId), ES_WRITE_INDEX_UPDATE, ImmutableMap.of("indexName", newTarget));
    }
@Test
    public void cycleThrowsRuntimeExceptionIfIndexCreationFailed() {
        final Map<String, Set<String>> indexNameAliases = ImmutableMap.of();

        when(indices.getIndexNamesAndAliases(anyString())).thenReturn(indexNameAliases);
        when(indices.create("graylog_0", mongoIndexSet)).thenReturn(false);

        expectedException.expect(RuntimeException.class);
        expectedException.expectMessage("Could not create new target index <graylog_0>.");

        final MongoIndexSet mongoIndexSet = createIndexSet(config);
        mongoIndexSet.cycle();
    }