|
19 | 19 |
|
20 | 20 | package org.elasticsearch.cluster.metadata;
|
21 | 21 |
|
| 22 | +import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; |
22 | 23 | import org.elasticsearch.action.admin.indices.mapping.put.PutMappingClusterStateUpdateRequest;
|
23 | 24 | import org.elasticsearch.cluster.ClusterState;
|
24 | 25 | import org.elasticsearch.cluster.ClusterStateTaskExecutor;
|
25 | 26 | import org.elasticsearch.cluster.service.ClusterService;
|
| 27 | +import org.elasticsearch.common.Strings; |
26 | 28 | import org.elasticsearch.common.compress.CompressedXContent;
|
| 29 | +import org.elasticsearch.common.xcontent.XContentBuilder; |
| 30 | +import org.elasticsearch.common.xcontent.XContentFactory; |
27 | 31 | import org.elasticsearch.index.Index;
|
28 | 32 | import org.elasticsearch.index.IndexService;
|
29 | 33 | import org.elasticsearch.index.mapper.MapperService;
|
|
34 | 38 | import java.util.Collection;
|
35 | 39 | import java.util.Collections;
|
36 | 40 |
|
| 41 | +import static org.hamcrest.CoreMatchers.containsString; |
37 | 42 | import static org.hamcrest.Matchers.equalTo;
|
38 | 43 | import static org.hamcrest.Matchers.not;
|
39 | 44 |
|
@@ -134,4 +139,77 @@ public void testMappingUpdateAccepts_docAsType() throws Exception {
|
134 | 139 | Collections.singletonMap("foo",
|
135 | 140 | Collections.singletonMap("type", "keyword"))), mappingMetaData.sourceAsMap());
|
136 | 141 | }
|
| 142 | + |
| 143 | + public void testForbidMultipleTypes() throws Exception { |
| 144 | + CreateIndexRequestBuilder createIndexRequest = client().admin().indices() |
| 145 | + .prepareCreate("test") |
| 146 | + .addMapping(MapperService.SINGLE_MAPPING_NAME); |
| 147 | + IndexService indexService = createIndex("test", createIndexRequest); |
| 148 | + |
| 149 | + MetaDataMappingService mappingService = getInstanceFromNode(MetaDataMappingService.class); |
| 150 | + ClusterService clusterService = getInstanceFromNode(ClusterService.class); |
| 151 | + |
| 152 | + PutMappingClusterStateUpdateRequest request = new PutMappingClusterStateUpdateRequest() |
| 153 | + .type("other_type") |
| 154 | + .indices(new Index[] {indexService.index()}) |
| 155 | + .source(Strings.toString(XContentFactory.jsonBuilder() |
| 156 | + .startObject() |
| 157 | + .startObject("other_type").endObject() |
| 158 | + .endObject())); |
| 159 | + ClusterStateTaskExecutor.ClusterTasksResult<PutMappingClusterStateUpdateRequest> result = |
| 160 | + mappingService.putMappingExecutor.execute(clusterService.state(), Collections.singletonList(request)); |
| 161 | + assertThat(result.executionResults.size(), equalTo(1)); |
| 162 | + |
| 163 | + ClusterStateTaskExecutor.TaskResult taskResult = result.executionResults.values().iterator().next(); |
| 164 | + assertFalse(taskResult.isSuccess()); |
| 165 | + assertThat(taskResult.getFailure().getMessage(), containsString( |
| 166 | + "Rejecting mapping update to [test] as the final mapping would have more than 1 type: ")); |
| 167 | + } |
| 168 | + |
| 169 | + /** |
| 170 | + * This test checks that the multi-type validation is done before we do any other kind of validation |
| 171 | + * on the mapping that's added, see https://github.com/elastic/elasticsearch/issues/29313 |
| 172 | + */ |
| 173 | + public void testForbidMultipleTypesWithConflictingMappings() throws Exception { |
| 174 | + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject() |
| 175 | + .startObject(MapperService.SINGLE_MAPPING_NAME) |
| 176 | + .startObject("properties") |
| 177 | + .startObject("field1") |
| 178 | + .field("type", "text") |
| 179 | + .endObject() |
| 180 | + .endObject() |
| 181 | + .endObject() |
| 182 | + .endObject(); |
| 183 | + |
| 184 | + CreateIndexRequestBuilder createIndexRequest = client().admin().indices() |
| 185 | + .prepareCreate("test") |
| 186 | + .addMapping(MapperService.SINGLE_MAPPING_NAME, mapping); |
| 187 | + IndexService indexService = createIndex("test", createIndexRequest); |
| 188 | + |
| 189 | + MetaDataMappingService mappingService = getInstanceFromNode(MetaDataMappingService.class); |
| 190 | + ClusterService clusterService = getInstanceFromNode(ClusterService.class); |
| 191 | + |
| 192 | + String conflictingMapping = Strings.toString(XContentFactory.jsonBuilder().startObject() |
| 193 | + .startObject("other_type") |
| 194 | + .startObject("properties") |
| 195 | + .startObject("field1") |
| 196 | + .field("type", "keyword") |
| 197 | + .endObject() |
| 198 | + .endObject() |
| 199 | + .endObject() |
| 200 | + .endObject()); |
| 201 | + |
| 202 | + PutMappingClusterStateUpdateRequest request = new PutMappingClusterStateUpdateRequest() |
| 203 | + .type("other_type") |
| 204 | + .indices(new Index[] {indexService.index()}) |
| 205 | + .source(conflictingMapping); |
| 206 | + ClusterStateTaskExecutor.ClusterTasksResult<PutMappingClusterStateUpdateRequest> result = |
| 207 | + mappingService.putMappingExecutor.execute(clusterService.state(), Collections.singletonList(request)); |
| 208 | + assertThat(result.executionResults.size(), equalTo(1)); |
| 209 | + |
| 210 | + ClusterStateTaskExecutor.TaskResult taskResult = result.executionResults.values().iterator().next(); |
| 211 | + assertFalse(taskResult.isSuccess()); |
| 212 | + assertThat(taskResult.getFailure().getMessage(), containsString( |
| 213 | + "Rejecting mapping update to [test] as the final mapping would have more than 1 type: ")); |
| 214 | + } |
137 | 215 | }
|
0 commit comments