|
@@ -13,6 +13,7 @@ import org.elasticsearch.client.AdminClient;
|
|
|
import org.elasticsearch.client.Client;
|
|
|
import org.elasticsearch.client.IndicesAdminClient;
|
|
|
import org.elasticsearch.cluster.ClusterChangedEvent;
|
|
|
+import org.elasticsearch.cluster.ClusterModule;
|
|
|
import org.elasticsearch.cluster.ClusterName;
|
|
|
import org.elasticsearch.cluster.ClusterState;
|
|
|
import org.elasticsearch.cluster.block.ClusterBlocks;
|
|
@@ -21,20 +22,36 @@ import org.elasticsearch.cluster.metadata.MetaData;
|
|
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
|
|
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
|
|
import org.elasticsearch.cluster.service.ClusterService;
|
|
|
+import org.elasticsearch.common.ParseField;
|
|
|
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.util.concurrent.EsExecutors;
|
|
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
|
|
+import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
|
|
+import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
|
|
+import org.elasticsearch.common.xcontent.XContentParser;
|
|
|
+import org.elasticsearch.common.xcontent.XContentType;
|
|
|
import org.elasticsearch.gateway.GatewayService;
|
|
|
import org.elasticsearch.test.ESTestCase;
|
|
|
import org.elasticsearch.threadpool.ThreadPool;
|
|
|
+import org.elasticsearch.xpack.core.indexlifecycle.DeleteAction;
|
|
|
+import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata;
|
|
|
+import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
|
|
|
+import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy;
|
|
|
+import org.elasticsearch.xpack.core.indexlifecycle.LifecycleType;
|
|
|
+import org.elasticsearch.xpack.core.indexlifecycle.TimeseriesLifecycleType;
|
|
|
+import org.elasticsearch.xpack.core.indexlifecycle.action.PutLifecycleAction;
|
|
|
import org.elasticsearch.xpack.core.watcher.support.WatcherIndexTemplateRegistryField;
|
|
|
import org.junit.Before;
|
|
|
import org.mockito.ArgumentCaptor;
|
|
|
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Collections;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
import static org.elasticsearch.mock.orig.Mockito.verify;
|
|
|
import static org.elasticsearch.mock.orig.Mockito.when;
|
|
@@ -50,6 +67,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
|
|
|
public class WatcherIndexTemplateRegistryTests extends ESTestCase {
|
|
|
|
|
|
private WatcherIndexTemplateRegistry registry;
|
|
|
+ private NamedXContentRegistry xContentRegistry;
|
|
|
private Client client;
|
|
|
|
|
|
@Before
|
|
@@ -72,7 +90,13 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase {
|
|
|
}).when(indicesAdminClient).putTemplate(any(PutIndexTemplateRequest.class), any(ActionListener.class));
|
|
|
|
|
|
ClusterService clusterService = mock(ClusterService.class);
|
|
|
- registry = new WatcherIndexTemplateRegistry(clusterService, threadPool, client);
|
|
|
+ List<NamedXContentRegistry.Entry> entries = new ArrayList<>(ClusterModule.getNamedXWriteables());
|
|
|
+ entries.addAll(Arrays.asList(
|
|
|
+ new NamedXContentRegistry.Entry(LifecycleType.class, new ParseField(TimeseriesLifecycleType.TYPE),
|
|
|
+ (p) -> TimeseriesLifecycleType.INSTANCE),
|
|
|
+ new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse)));
|
|
|
+ xContentRegistry = new NamedXContentRegistry(entries);
|
|
|
+ registry = new WatcherIndexTemplateRegistry(clusterService, threadPool, client, xContentRegistry);
|
|
|
}
|
|
|
|
|
|
public void testThatNonExistingTemplatesAreAddedImmediately() {
|
|
@@ -91,6 +115,44 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase {
|
|
|
verify(client.admin().indices(), times(4)).putTemplate(argumentCaptor.capture(), anyObject());
|
|
|
}
|
|
|
|
|
|
+ public void testThatNonExistingPoliciesAreAddedImmediately() {
|
|
|
+ DiscoveryNode node = new DiscoveryNode("node", ESTestCase.buildNewFakeTransportAddress(), Version.CURRENT);
|
|
|
+ DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build();
|
|
|
+
|
|
|
+ ClusterChangedEvent event = createClusterChangedEvent(Collections.emptyList(), nodes);
|
|
|
+ registry.clusterChanged(event);
|
|
|
+ verify(client, times(1)).execute(eq(PutLifecycleAction.INSTANCE), anyObject(), anyObject());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPolicyAlreadyExists() {
|
|
|
+ DiscoveryNode node = new DiscoveryNode("node", ESTestCase.buildNewFakeTransportAddress(), Version.CURRENT);
|
|
|
+ DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build();
|
|
|
+
|
|
|
+ Map<String, LifecyclePolicy> policyMap = new HashMap<>();
|
|
|
+ LifecyclePolicy policy = registry.loadWatcherHistoryPolicy();
|
|
|
+ policyMap.put(policy.getName(), policy);
|
|
|
+ ClusterChangedEvent event = createClusterChangedEvent(Collections.emptyList(), policyMap, nodes);
|
|
|
+ registry.clusterChanged(event);
|
|
|
+ verify(client, times(0)).execute(eq(PutLifecycleAction.INSTANCE), anyObject(), anyObject());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPolicyAlreadyExistsButDiffers() throws IOException {
|
|
|
+ DiscoveryNode node = new DiscoveryNode("node", ESTestCase.buildNewFakeTransportAddress(), Version.CURRENT);
|
|
|
+ DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build();
|
|
|
+
|
|
|
+ Map<String, LifecyclePolicy> policyMap = new HashMap<>();
|
|
|
+ String policyStr = "{\"phases\":{\"delete\":{\"min_age\":\"1m\",\"actions\":{\"delete\":{}}}}}";
|
|
|
+ LifecyclePolicy policy = registry.loadWatcherHistoryPolicy();
|
|
|
+ try (XContentParser parser = XContentType.JSON.xContent()
|
|
|
+ .createParser(xContentRegistry, LoggingDeprecationHandler.THROW_UNSUPPORTED_OPERATION, policyStr)) {
|
|
|
+ LifecyclePolicy different = LifecyclePolicy.parse(parser, policy.getName());
|
|
|
+ policyMap.put(policy.getName(), different);
|
|
|
+ ClusterChangedEvent event = createClusterChangedEvent(Collections.emptyList(), policyMap, nodes);
|
|
|
+ registry.clusterChanged(event);
|
|
|
+ verify(client, times(0)).execute(eq(PutLifecycleAction.INSTANCE), anyObject(), anyObject());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public void testThatTemplatesExist() {
|
|
|
assertThat(WatcherIndexTemplateRegistry.validate(createClusterState(".watch-history")), is(false));
|
|
|
assertThat(WatcherIndexTemplateRegistry.validate(createClusterState(".watch-history", ".triggered_watches", ".watches")),
|
|
@@ -141,6 +203,12 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase {
|
|
|
}
|
|
|
|
|
|
private ClusterChangedEvent createClusterChangedEvent(List<String> existingTemplateNames, DiscoveryNodes nodes) {
|
|
|
+ return createClusterChangedEvent(existingTemplateNames, Collections.emptyMap(), nodes);
|
|
|
+ }
|
|
|
+
|
|
|
+ private ClusterChangedEvent createClusterChangedEvent(List<String> existingTemplateNames,
|
|
|
+ Map<String, LifecyclePolicy> existingPolicies,
|
|
|
+ DiscoveryNodes nodes) {
|
|
|
ClusterChangedEvent event = mock(ClusterChangedEvent.class);
|
|
|
when(event.localNodeMaster()).thenReturn(nodes.isLocalNodeElectedMaster());
|
|
|
ClusterState cs = mock(ClusterState.class);
|
|
@@ -158,6 +226,10 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase {
|
|
|
}
|
|
|
|
|
|
when(metaData.getTemplates()).thenReturn(indexTemplates.build());
|
|
|
+
|
|
|
+ IndexLifecycleMetadata ilmMeta = mock(IndexLifecycleMetadata.class);
|
|
|
+ when(ilmMeta.getPolicies()).thenReturn(existingPolicies);
|
|
|
+ when(metaData.custom(anyObject())).thenReturn(ilmMeta);
|
|
|
when(cs.metaData()).thenReturn(metaData);
|
|
|
|
|
|
return event;
|