Skip to content

Commit 6f6df95

Browse files
committed
Init commit: same as cps/prohibit-_project-mappings branch
1 parent f60be16 commit 6f6df95

File tree

5 files changed

+82
-2
lines changed

5 files changed

+82
-2
lines changed

server/src/main/java/org/elasticsearch/index/mapper/MapperRegistry.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,29 @@ public final class MapperRegistry {
3131
private final Map<String, MetadataFieldMapper.TypeParser> metadataMapperParsers6x;
3232
private final Map<String, MetadataFieldMapper.TypeParser> metadataMapperParsers5x;
3333
private final Function<String, FieldPredicate> fieldFilter;
34+
private final RootObjectMapperNamespaceValidator namespaceValidator;
3435

36+
// MP TODO: remove this? Or keep?
3537
public MapperRegistry(
3638
Map<String, Mapper.TypeParser> mapperParsers,
3739
Map<String, RuntimeField.Parser> runtimeFieldParsers,
3840
Map<String, MetadataFieldMapper.TypeParser> metadataMapperParsers,
3941
Function<String, FieldPredicate> fieldFilter
42+
) {
43+
// MP TODO: remove this no-op RootObjectMapperNamespaceValidator once we know how all this is going to work
44+
this(mapperParsers, runtimeFieldParsers, metadataMapperParsers, fieldFilter, new RootObjectMapperNamespaceValidator() {
45+
@Override
46+
public void validateNamespace(ObjectMapper.Subobjects subobjects, Mapper mapper) {}
47+
});
48+
}
49+
50+
// MP TODO: need to move/create tests to use this
51+
public MapperRegistry(
52+
Map<String, Mapper.TypeParser> mapperParsers,
53+
Map<String, RuntimeField.Parser> runtimeFieldParsers,
54+
Map<String, MetadataFieldMapper.TypeParser> metadataMapperParsers,
55+
Function<String, FieldPredicate> fieldFilter,
56+
RootObjectMapperNamespaceValidator namespaceValidator
4057
) {
4158
this.mapperParsers = Collections.unmodifiableMap(new LinkedHashMap<>(mapperParsers));
4259
this.runtimeFieldParsers = runtimeFieldParsers;
@@ -50,6 +67,7 @@ public MapperRegistry(
5067
metadata5x.put(LegacyTypeFieldMapper.NAME, LegacyTypeFieldMapper.PARSER);
5168
this.metadataMapperParsers5x = metadata5x;
5269
this.fieldFilter = fieldFilter;
70+
this.namespaceValidator = namespaceValidator;
5371
}
5472

5573
/**
@@ -72,6 +90,10 @@ public Map<String, RuntimeField.Parser> getRuntimeFieldParsers() {
7290
return runtimeFieldParsers;
7391
}
7492

93+
public RootObjectMapperNamespaceValidator getNamespaceValidator() {
94+
return namespaceValidator;
95+
}
96+
7597
/**
7698
* Return a map of the meta mappers that have been registered. The
7799
* returned map uses the name of the field as a key.

server/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,12 +548,17 @@ public final Optional<SourceKeepMode> sourceKeepMode() {
548548
}
549549

550550
@Override
551-
public void validate(MappingLookup mappers) {
551+
public final void validate(MappingLookup mappers) {
552552
for (Mapper mapper : this.mappers.values()) {
553553
mapper.validate(mappers);
554+
validateSubField(mapper, mappers);
554555
}
555556
}
556557

558+
protected void validateSubField(Mapper mapper, MappingLookup mappers) {
559+
mapper.validate(mappers);
560+
}
561+
557562
protected MapperMergeContext createChildContext(MapperMergeContext mapperMergeContext, String name) {
558563
return mapperMergeContext.createChildContext(name, dynamic);
559564
}

server/src/main/java/org/elasticsearch/index/mapper/RootObjectMapper.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,4 +540,21 @@ private static boolean processField(
540540
public int getTotalFieldsCount() {
541541
return super.getTotalFieldsCount() - 1 + runtimeFields.size();
542542
}
543+
544+
// MP TODO: - this needs to move to a serverless class, right?
545+
private static final String RESERVED_NAMESPACE = "_project";
546+
547+
@Override
548+
protected void validateSubField(Mapper mapper, MappingLookup mappers) {
549+
if (subobjects() == Subobjects.ENABLED) {
550+
if (mapper.leafName().equals(RESERVED_NAMESPACE)) {
551+
throw new IllegalArgumentException("Reserved Namespace. Fields may not start with " + RESERVED_NAMESPACE);
552+
}
553+
} else {
554+
if (mapper.leafName().startsWith(RESERVED_NAMESPACE)) {
555+
throw new IllegalArgumentException("Reserved Namespace. Fields may not start with " + RESERVED_NAMESPACE);
556+
}
557+
}
558+
super.validateSubField(mapper, mappers);
559+
}
543560
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.index.mapper;
11+
12+
/**
13+
* TODO: DOCUMENT ME
14+
*/
15+
public interface RootObjectMapperNamespaceValidator {
16+
void validateNamespace(ObjectMapper.Subobjects subobjects, Mapper mapper);
17+
}

server/src/main/java/org/elasticsearch/indices/IndicesModule.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.elasticsearch.index.mapper.ObjectMapper;
5858
import org.elasticsearch.index.mapper.PassThroughObjectMapper;
5959
import org.elasticsearch.index.mapper.RangeType;
60+
import org.elasticsearch.index.mapper.RootObjectMapperNamespaceValidator;
6061
import org.elasticsearch.index.mapper.RoutingFieldMapper;
6162
import org.elasticsearch.index.mapper.RuntimeField;
6263
import org.elasticsearch.index.mapper.SeqNoFieldMapper;
@@ -94,12 +95,30 @@
9495
public class IndicesModule extends AbstractModule {
9596
private final MapperRegistry mapperRegistry;
9697

98+
// TODO: this needs to be loaded from serverless somehow
99+
private static final String RESERVED_NAMESPACE = "_project";
100+
97101
public IndicesModule(List<MapperPlugin> mapperPlugins) {
98102
this.mapperRegistry = new MapperRegistry(
99103
getMappers(mapperPlugins),
100104
getRuntimeFields(mapperPlugins),
101105
getMetadataMappers(mapperPlugins),
102-
getFieldFilter(mapperPlugins)
106+
getFieldFilter(mapperPlugins),
107+
new RootObjectMapperNamespaceValidator() {
108+
@Override
109+
public void validateNamespace(ObjectMapper.Subobjects subobjects, Mapper mapper) {
110+
// TODO: in the future, this will be a no-op on stateful and loaded somehow dynamically in serverless
111+
if (subobjects == ObjectMapper.Subobjects.ENABLED) {
112+
if (mapper.leafName().equals(RESERVED_NAMESPACE)) {
113+
throw new IllegalArgumentException("xx reserved namespace: [" + RESERVED_NAMESPACE + ']');
114+
}
115+
} else {
116+
if (mapper.leafName().startsWith(RESERVED_NAMESPACE)) {
117+
throw new IllegalArgumentException("xx reserved namespace: [" + RESERVED_NAMESPACE + ']');
118+
}
119+
}
120+
}
121+
}
103122
);
104123
}
105124

0 commit comments

Comments
 (0)