|
19 | 19 | package org.elasticsearch.action.admin.indices.datastream; |
20 | 20 |
|
21 | 21 | import org.elasticsearch.ResourceNotFoundException; |
| 22 | +import org.elasticsearch.Version; |
22 | 23 | import org.elasticsearch.action.ActionRequestValidationException; |
23 | 24 | import org.elasticsearch.action.admin.indices.datastream.DeleteDataStreamAction.Request; |
24 | 25 | import org.elasticsearch.cluster.ClusterName; |
25 | 26 | import org.elasticsearch.cluster.ClusterState; |
26 | 27 | import org.elasticsearch.cluster.metadata.DataStream; |
| 28 | +import org.elasticsearch.cluster.metadata.IndexMetadata; |
27 | 29 | import org.elasticsearch.cluster.metadata.Metadata; |
| 30 | +import org.elasticsearch.cluster.metadata.MetadataDeleteIndexService; |
| 31 | +import org.elasticsearch.common.collect.Tuple; |
28 | 32 | import org.elasticsearch.common.io.stream.Writeable; |
| 33 | +import org.elasticsearch.common.settings.Settings; |
| 34 | +import org.elasticsearch.index.Index; |
29 | 35 | import org.elasticsearch.test.AbstractWireSerializingTestCase; |
30 | 36 |
|
31 | | -import java.util.Collections; |
32 | | -import java.util.Map; |
| 37 | +import java.util.ArrayList; |
| 38 | +import java.util.List; |
| 39 | +import java.util.Locale; |
| 40 | +import java.util.Set; |
| 41 | +import java.util.stream.Collectors; |
33 | 42 |
|
34 | 43 | import static org.hamcrest.Matchers.containsString; |
35 | 44 | import static org.hamcrest.Matchers.equalTo; |
| 45 | +import static org.mockito.Matchers.any; |
| 46 | +import static org.mockito.Mockito.mock; |
| 47 | +import static org.mockito.Mockito.when; |
36 | 48 |
|
37 | 49 | public class DeleteDataStreamRequestTests extends AbstractWireSerializingTestCase<Request> { |
38 | 50 |
|
@@ -62,21 +74,93 @@ public void testValidateRequestWithoutName() { |
62 | 74 |
|
63 | 75 | public void testDeleteDataStream() { |
64 | 76 | final String dataStreamName = "my-data-stream"; |
65 | | - DataStream existingDataStream = new DataStream(dataStreamName, "timestamp", Collections.emptyList()); |
66 | | - ClusterState cs = ClusterState.builder(new ClusterName("_name")) |
67 | | - .metadata(Metadata.builder().dataStreams(Map.of(dataStreamName, existingDataStream)).build()).build(); |
68 | | - DeleteDataStreamAction.Request req = new DeleteDataStreamAction.Request(dataStreamName); |
| 77 | + final List<String> otherIndices = randomSubsetOf(List.of("foo", "bar", "baz")); |
| 78 | + |
| 79 | + ClusterState cs = getClusterState( |
| 80 | + List.of(new Tuple<>(dataStreamName, List.of( |
| 81 | + String.format(Locale.ROOT, "%s-%06d", dataStreamName, 1), |
| 82 | + String.format(Locale.ROOT, "%s-%06d", dataStreamName, 2)))), |
| 83 | + otherIndices); |
69 | 84 |
|
70 | | - ClusterState newState = DeleteDataStreamAction.TransportAction.removeDataStream(cs, req); |
| 85 | + DeleteDataStreamAction.Request req = new DeleteDataStreamAction.Request(dataStreamName); |
| 86 | + ClusterState newState = DeleteDataStreamAction.TransportAction.removeDataStream(getMetadataDeleteIndexService(), cs, req); |
71 | 87 | assertThat(newState.metadata().dataStreams().size(), equalTo(0)); |
| 88 | + assertThat(newState.metadata().indices().size(), equalTo(otherIndices.size())); |
| 89 | + for (String indexName : otherIndices) { |
| 90 | + assertThat(newState.metadata().indices().get(indexName).getIndex().getName(), equalTo(indexName)); |
| 91 | + } |
72 | 92 | } |
73 | 93 |
|
74 | 94 | public void testDeleteNonexistentDataStream() { |
75 | 95 | final String dataStreamName = "my-data-stream"; |
76 | 96 | ClusterState cs = ClusterState.builder(new ClusterName("_name")).build(); |
77 | 97 | DeleteDataStreamAction.Request req = new DeleteDataStreamAction.Request(dataStreamName); |
78 | 98 | ResourceNotFoundException e = expectThrows(ResourceNotFoundException.class, |
79 | | - () -> DeleteDataStreamAction.TransportAction.removeDataStream(cs, req)); |
| 99 | + () -> DeleteDataStreamAction.TransportAction.removeDataStream(getMetadataDeleteIndexService(), cs, req)); |
80 | 100 | assertThat(e.getMessage(), containsString("data_streams matching [" + dataStreamName + "] not found")); |
81 | 101 | } |
| 102 | + |
| 103 | + @SuppressWarnings("unchecked") |
| 104 | + private static MetadataDeleteIndexService getMetadataDeleteIndexService() { |
| 105 | + MetadataDeleteIndexService s = mock(MetadataDeleteIndexService.class); |
| 106 | + when(s.deleteIndices(any(ClusterState.class), any(Set.class))) |
| 107 | + .thenAnswer(mockInvocation -> { |
| 108 | + ClusterState currentState = (ClusterState) mockInvocation.getArguments()[0]; |
| 109 | + Set<Index> indices = (Set<Index>) mockInvocation.getArguments()[1]; |
| 110 | + |
| 111 | + final Metadata.Builder b = Metadata.builder(currentState.metadata()); |
| 112 | + for (Index index : indices) { |
| 113 | + b.remove(index.getName()); |
| 114 | + } |
| 115 | + |
| 116 | + return ClusterState.builder(currentState).metadata(b.build()).build(); |
| 117 | + }); |
| 118 | + |
| 119 | + return s; |
| 120 | + } |
| 121 | + |
| 122 | + /** |
| 123 | + * Constructs {@code ClusterState} with the specified data streams and indices. |
| 124 | + * |
| 125 | + * @param dataStreamAndIndexNames The names of the data streams to create with their respective backing indices |
| 126 | + * @param indexNames The names of indices to create that do not back any data streams |
| 127 | + */ |
| 128 | + private static ClusterState getClusterState(List<Tuple<String, List<String>>> dataStreamAndIndexNames, List<String> indexNames) { |
| 129 | + Metadata.Builder builder = Metadata.builder(); |
| 130 | + |
| 131 | + List<IndexMetadata> allIndices = new ArrayList<>(); |
| 132 | + for (Tuple<String, List<String>> dsTuple : dataStreamAndIndexNames) { |
| 133 | + List<IndexMetadata> backingIndices = new ArrayList<>(); |
| 134 | + for (String indexName : dsTuple.v2()) { |
| 135 | + backingIndices.add(createIndexMetadata(indexName, true)); |
| 136 | + } |
| 137 | + allIndices.addAll(backingIndices); |
| 138 | + |
| 139 | + DataStream ds = new DataStream(dsTuple.v1(), "@timestamp", |
| 140 | + backingIndices.stream().map(IndexMetadata::getIndex).collect(Collectors.toList())); |
| 141 | + builder.put(ds); |
| 142 | + } |
| 143 | + |
| 144 | + for (String indexName : indexNames) { |
| 145 | + allIndices.add(createIndexMetadata(indexName, false)); |
| 146 | + } |
| 147 | + |
| 148 | + for (IndexMetadata index : allIndices) { |
| 149 | + builder.put(index, false); |
| 150 | + } |
| 151 | + |
| 152 | + return ClusterState.builder(new ClusterName("_name")).metadata(builder).build(); |
| 153 | + } |
| 154 | + |
| 155 | + private static IndexMetadata createIndexMetadata(String name, boolean hidden) { |
| 156 | + Settings.Builder b = Settings.builder() |
| 157 | + .put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT) |
| 158 | + .put("index.hidden", hidden); |
| 159 | + |
| 160 | + return IndexMetadata.builder(name) |
| 161 | + .settings(b) |
| 162 | + .numberOfShards(1) |
| 163 | + .numberOfReplicas(1) |
| 164 | + .build(); |
| 165 | + } |
82 | 166 | } |
0 commit comments