summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@oath.com>2017-11-02 15:57:23 +0100
committerValerij Fredriksen <valerijf@oath.com>2017-11-02 15:57:23 +0100
commit1e1b84fbf754e5e90f815a5c2f83ca79865505d5 (patch)
tree325b6a8c11f98878199e080446774012e52b1b7d /config-model
parent1721b453c41d030b7892d86f92740b577a7aaf77 (diff)
parent25a2dc312d6b1b8e8dbefce9e06f9bd4619bd176 (diff)
Merge branch 'master' into freva/instance-validator
# Conflicts: # athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzInstanceProviderService.java # athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzInstanceProviderServiceTest.java
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/ReservedDocumentTypeNameValidator.java42
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java1
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java23
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/content/ReservedDocumentTypeNameValidatorTest.java57
4 files changed, 123 insertions, 0 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/ReservedDocumentTypeNameValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/content/ReservedDocumentTypeNameValidator.java
new file mode 100644
index 00000000000..9f081f7083b
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/ReservedDocumentTypeNameValidator.java
@@ -0,0 +1,42 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.content;
+
+import com.yahoo.documentmodel.NewDocumentType;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class ReservedDocumentTypeNameValidator {
+
+ public static final List<String> ORDERED_RESERVED_NAMES = Collections.unmodifiableList(
+ Arrays.asList("and", "false", "id", "not", "null", "or", "true"));
+ public static final Set<String> RESERVED_NAMES = Collections.unmodifiableSet(new HashSet<>(ORDERED_RESERVED_NAMES));
+
+ public void validate(Map<String, NewDocumentType> documentDefinitions) {
+ List<String> conflictingNames = documentDefinitions.keySet().stream()
+ .filter(this::isReservedName)
+ .collect(Collectors.toList());
+ if (!conflictingNames.isEmpty()) {
+ throw new IllegalArgumentException(makeReservedNameMessage(conflictingNames));
+ }
+ }
+
+ private boolean isReservedName(String name) {
+ return RESERVED_NAMES.contains(name.toLowerCase());
+ }
+
+ private static String asQuotedListString(List<String> list) {
+ return list.stream().map(s -> String.format("'%s'", s)).collect(Collectors.joining(", "));
+ }
+
+ private static String makeReservedNameMessage(List<String> conflictingNames) {
+ return String.format("The following document types conflict with reserved keyword names: %s. Reserved keywords are %s",
+ asQuotedListString(conflictingNames), asQuotedListString(ORDERED_RESERVED_NAMES));
+ }
+
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
index b4f8889690e..c7755d3de5a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
@@ -617,6 +617,7 @@ public class ContentCluster extends AbstractConfigProducer implements StorDistri
throw new IllegalArgumentException("In indexed content cluster '" + search.getClusterName() + "': Using multi-level dispatch setup is not supported when using hierarchical distribution.");
}
}
+ new ReservedDocumentTypeNameValidator().validate(documentDefinitions);
new GlobalDistributionValidator().validate(documentDefinitions, globallyDistributedDocuments, redundancy);
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java
index 2a3dbe002e6..0c41b8ecc0b 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java
@@ -25,7 +25,9 @@ import com.yahoo.vespa.model.content.utils.ContentClusterUtils;
import com.yahoo.vespa.model.content.utils.SearchDefinitionBuilder;
import com.yahoo.vespa.model.test.utils.ApplicationPackageUtils;
import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import java.util.List;
@@ -38,6 +40,8 @@ public class ClusterTest extends ContentBaseTest {
private final static String HOSTS = "<admin version='2.0'><adminserver hostalias='mockhost' /></admin>";
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
ContentCluster parse(String xml) {
xml = HOSTS + xml;
@@ -787,6 +791,25 @@ public class ClusterTest extends ContentBaseTest {
assertTrue(cluster.getSearch().getSearchNodes().get(0).getPreShutdownCommand().isPresent());
}
+ @Test
+ public void reserved_document_name_throws_exception() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The following document types conflict with reserved keyword names: 'true'.");
+
+ String xml = "<content version=\"1.0\" id=\"storage\">" +
+ " <redundancy>1</redundancy>" +
+ " <documents>" +
+ " <document type=\"true\" mode=\"index\"/>" +
+ " </documents>" +
+ " <group>" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
+ " </group>" +
+ "</content>";
+
+ List<String> sds = ApplicationPackageUtils.generateSearchDefinitions("true");
+ new VespaModelCreatorWithMockPkg(null, xml, sds).create();
+ }
+
private ContentCluster createWithZone(String clusterXml, Zone zone) throws Exception {
DeployState.Builder deployStateBuilder = new DeployState.Builder().properties(new DeployProperties.Builder()
.hostedVespa(true)
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ReservedDocumentTypeNameValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ReservedDocumentTypeNameValidatorTest.java
new file mode 100644
index 00000000000..0ad5fb3b0bd
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ReservedDocumentTypeNameValidatorTest.java
@@ -0,0 +1,57 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.content;
+
+import com.yahoo.documentmodel.NewDocumentType;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class ReservedDocumentTypeNameValidatorTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private static Map<String, NewDocumentType> asDocTypeMapping(List<String> typeNames) {
+ return typeNames.stream().collect(Collectors.toMap(Function.identity(), n -> new NewDocumentType(new NewDocumentType.Name(n))));
+ }
+
+ @Test
+ public void exception_thrown_on_reserved_names() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The following document types conflict with reserved keyword names: " +
+ "'and', 'false', 'id', 'not', 'null', 'or', 'true'. " +
+ "Reserved keywords are 'and', 'false', 'id', 'not', 'null', 'or', 'true'");
+
+ // Ensure ordering is consistent for testing
+ Map<String, NewDocumentType> orderedDocTypes = new TreeMap<>(asDocTypeMapping(ReservedDocumentTypeNameValidator.ORDERED_RESERVED_NAMES));
+
+ ReservedDocumentTypeNameValidator validator = new ReservedDocumentTypeNameValidator();
+ validator.validate(orderedDocTypes);
+ }
+
+ @Test
+ public void exception_is_not_thrown_on_unreserved_name() {
+ ReservedDocumentTypeNameValidator validator = new ReservedDocumentTypeNameValidator();
+ validator.validate(asDocTypeMapping(Collections.singletonList("foo")));
+ }
+
+ @Test
+ public void validation_is_case_insensitive() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The following document types conflict with reserved keyword names: " +
+ "'NULL', 'True', 'anD'.");
+
+ ReservedDocumentTypeNameValidator validator = new ReservedDocumentTypeNameValidator();
+ Map<String, NewDocumentType> orderedDocTypes = new TreeMap<>(asDocTypeMapping(Arrays.asList("NULL", "True", "anD")));
+ validator.validate(orderedDocTypes);
+ }
+
+}