summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java53
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java65
4 files changed, 121 insertions, 0 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java
index 1ce9ac2275f..6d8fd553502 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java
@@ -18,6 +18,7 @@ public enum ValidationId {
contentClusterRemoval("content-cluster-removal"), // Removal (or id change) of content clusters
deploymentRemoval("deployment-removal"), // Removal of production zones from deployment.xml
skipAutomaticTenantUpgradeTests("skip-automatic-tenant-upgrade-test"), // Skip platform supplied staging tests
+ globalDocumentChange("global-document-change"), // Changing global attribute for document types in content clusters
configModelVersionMismatch("config-model-version-mismatch"), // Internal use
skipOldConfigModels("skip-old-config-models"), // Internal use
forceAutomaticTenantUpgradeTests("force-automatic-tenant-upgrade-test"); // Internal use
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
index 50e93789159..523ced52306 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
@@ -13,6 +13,7 @@ import com.yahoo.vespa.model.application.validation.change.ConfigValueChangeVali
import com.yahoo.vespa.model.application.validation.change.ContainerRestartValidator;
import com.yahoo.vespa.model.application.validation.change.ContentClusterRemovalValidator;
import com.yahoo.vespa.model.application.validation.change.ContentTypeRemovalValidator;
+import com.yahoo.vespa.model.application.validation.change.GlobalDocumentChangeValidator;
import com.yahoo.vespa.model.application.validation.change.IndexedSearchClusterChangeValidator;
import com.yahoo.vespa.model.application.validation.change.IndexingModeChangeValidator;
import com.yahoo.vespa.model.application.validation.change.StartupCommandChangeValidator;
@@ -72,6 +73,7 @@ public class Validation {
Instant now) {
ChangeValidator[] validators = new ChangeValidator[] {
new IndexingModeChangeValidator(),
+ new GlobalDocumentChangeValidator(),
new IndexedSearchClusterChangeValidator(),
new StreamingSearchClusterChangeValidator(),
new ConfigValueChangeValidator(logger),
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java
new file mode 100644
index 00000000000..37d63154cab
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidator.java
@@ -0,0 +1,53 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation.change;
+
+import com.yahoo.config.application.api.ValidationId;
+import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.model.api.ConfigChangeAction;
+import com.yahoo.documentmodel.NewDocumentType;
+import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.content.cluster.ContentCluster;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class that fails via exception if global attribute changes for a document
+ * type in a content cluster unless corresponding override is present.
+ */
+public class GlobalDocumentChangeValidator implements ChangeValidator {
+
+ @Override
+ public List<ConfigChangeAction> validate(VespaModel currentModel, VespaModel nextModel,
+ ValidationOverrides overrides, Instant now) {
+ if (!overrides.allows(ValidationId.globalDocumentChange.value(), now)) {
+ for (Map.Entry<String, ContentCluster> currentEntry : currentModel.getContentClusters().entrySet()) {
+ ContentCluster nextCluster = nextModel.getContentClusters().get(currentEntry.getKey());
+ if (nextCluster == null) continue;
+
+ validateContentCluster(currentEntry.getValue(), nextCluster);
+ }
+ }
+ return new ArrayList<>();
+ }
+
+ private void validateContentCluster(ContentCluster currentCluster, ContentCluster nextCluster) {
+ for (Map.Entry<String, NewDocumentType> currentEntry : currentCluster.getDocumentDefinitions().entrySet()) {
+ String clusterName = currentCluster.getName();
+ String documentTypeName = currentEntry.getKey();
+ NewDocumentType currentDocumentType = currentEntry.getValue();
+ NewDocumentType nextDocumentType = nextCluster.getDocumentDefinitions().get(documentTypeName);
+ if (nextDocumentType != null) {
+ boolean currentIsGlobal = currentCluster.isGloballyDistributed(currentDocumentType);
+ boolean nextIsGlobal = nextCluster.isGloballyDistributed(nextDocumentType);
+ if (currentIsGlobal != nextIsGlobal) {
+ throw new IllegalStateException(String.format("Document type %s in cluster %s changed global from %s to %s",
+ documentTypeName, clusterName, currentIsGlobal, nextIsGlobal));
+ }
+ }
+ }
+ }
+}
+
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java
new file mode 100644
index 00000000000..5e3b8361c75
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/GlobalDocumentChangeValidatorTest.java
@@ -0,0 +1,65 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation.change;
+
+import com.yahoo.config.model.api.ConfigChangeAction;
+import com.yahoo.config.model.api.ConfigChangeRefeedAction;
+import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.application.validation.ValidationTester;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * Test that global attribute changes are detected by change validator.
+ */
+public class GlobalDocumentChangeValidatorTest {
+
+ @Test
+ public void testChangGlobalAttribute() throws IOException, SAXException {
+ testChangeGlobalAttribute(true, false, false, null);
+ testChangeGlobalAttribute(true, true, true, null);
+ testChangeGlobalAttribute(false, false, true, null);
+ testChangeGlobalAttribute(false, true, false, null);
+ testChangeGlobalAttribute(true, false, true, globalDocumentValidationOverrides);
+ testChangeGlobalAttribute(true, true, false, globalDocumentValidationOverrides);
+ }
+
+ private void testChangeGlobalAttribute(boolean allowed, boolean oldGlobal, boolean newGlobal, String validationOverrides) {
+ ValidationTester tester = new ValidationTester();
+ VespaModel oldModel = tester.deploy(null, getServices(oldGlobal), validationOverrides).getFirst();
+ try {
+ List<ConfigChangeAction> changeActions =
+ tester.deploy(oldModel, getServices(newGlobal), validationOverrides).getSecond();
+ assertTrue(allowed);
+ } catch (IllegalStateException e) {
+ assertFalse(allowed);
+ assertEquals("Document type music in cluster default changed global from " + oldGlobal + " to " + newGlobal,
+ e.getMessage());
+ }
+ }
+ private static final String getServices(boolean isGlobal) {
+ return "<services version='1.0'>" +
+ " <content id='default' version='1.0'>" +
+ " <redundancy>1</redundancy>" +
+ " <documents>" +
+ " <document type='music' mode='index' global='" +
+ isGlobal + "'/>" +
+ " </documents>" +
+ " <nodes count='1'/>" +
+ " </content>" +
+ "</services>";
+ }
+
+ private static final String globalDocumentValidationOverrides =
+ "<validation-overrides>\n" +
+ " <allow until='2000-01-14' comment='test override'>global-document-change</allow>\n" +
+ "</validation-overrides>\n";
+
+}