parent/child: Fix `_parent.type` validation.
A `_parent` field can only point to a type that doesn't exist yet. The validation that checks this relied on have all mappings in the MapperService. The issue is that this check is performed on the elected master node and it may not have the IndexService at all to perform this check. In that case it creates a temporary IndexService and MapperService to perform mapping validation, but only the mappings that are part of the put index call are created, not the already existing mappings. Because of that the `_parent` field validation can't be performed. By changing the validation to rely on the cluster state's IndexMetaData instead we can get around the issue with the IndexService/MapperService on the elected master node. The IndexMetaData always holds the MappingMetaData instances for all types.
This commit is contained in:
parent
d99b5dfdb4
commit
2fe7cde8d1
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.cluster.metadata;
|
package org.elasticsearch.cluster.metadata;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.cursors.ObjectCursor;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
@ -37,10 +38,10 @@ import org.elasticsearch.common.compress.CompressedXContent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
|
import org.elasticsearch.index.IndexService;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.IndexService;
|
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.indices.IndexMissingException;
|
import org.elasticsearch.indices.IndexMissingException;
|
||||||
import org.elasticsearch.indices.IndicesService;
|
import org.elasticsearch.indices.IndicesService;
|
||||||
|
@ -396,8 +397,11 @@ public class MetaDataMappingService extends AbstractComponent {
|
||||||
// and a put mapping api call, so we don't which type did exist before.
|
// and a put mapping api call, so we don't which type did exist before.
|
||||||
// Also the order of the mappings may be backwards.
|
// Also the order of the mappings may be backwards.
|
||||||
if (Version.indexCreated(indexService.getIndexSettings()).onOrAfter(Version.V_2_0_0) && newMapper.parentFieldMapper().active()) {
|
if (Version.indexCreated(indexService.getIndexSettings()).onOrAfter(Version.V_2_0_0) && newMapper.parentFieldMapper().active()) {
|
||||||
if (indexService.mapperService().types().contains(newMapper.parentFieldMapper().type())) {
|
IndexMetaData indexMetaData = currentState.metaData().index(index);
|
||||||
throw new IllegalArgumentException("can't add a _parent field that points to an already existing type");
|
for (ObjectCursor<MappingMetaData> mapping : indexMetaData.mappings().values()) {
|
||||||
|
if (newMapper.parentFieldMapper().type().equals(mapping.value.type())) {
|
||||||
|
throw new IllegalArgumentException("can't add a _parent field that points to an already existing type");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue