summaryrefslogtreecommitdiffstats
path: root/config-provisioning
diff options
context:
space:
mode:
authorMartin Polden <martin.polden@gmail.com>2017-02-07 14:29:17 +0100
committerMartin Polden <martin.polden@gmail.com>2017-02-10 12:27:38 +0100
commit3f1a4bbdc43c97fb93ead93725bc2619862f2e13 (patch)
treeda82efdac6e3d86befb3557f942919c269ceb6c5 /config-provisioning
parentd9869e2188e7e09de5d734a028de57854f51100d (diff)
Add retired field to Flavor config
Diffstat (limited to 'config-provisioning')
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java14
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java22
-rw-r--r--config-provisioning/src/main/resources/configdefinitions/flavors.def3
-rw-r--r--config-provisioning/src/test/java/com/yahoo/config/provision/NodeFlavorsTest.java80
4 files changed, 113 insertions, 6 deletions
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java
index 835325bc0f8..fff1d53b50e 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java
@@ -23,6 +23,7 @@ public class Flavor {
private final double minMainMemoryAvailableGb;
private final double minDiskAvailableGb;
private final String description;
+ private final boolean retired;
private List<Flavor> replacesFlavors;
/**
@@ -39,6 +40,7 @@ public class Flavor {
this.minMainMemoryAvailableGb = flavorConfig.minMainMemoryAvailableGb();
this.minDiskAvailableGb = flavorConfig.minDiskAvailableGb();
this.description = flavorConfig.description();
+ this.retired = flavorConfig.retired();
}
/** Returns the unique identity of this flavor */
@@ -62,6 +64,11 @@ public class Flavor {
public String getDescription() { return description; }
+ /** Returns whether the flavor is retired */
+ public boolean isRetired() {
+ return retired;
+ }
+
public Type getType() { return type; }
/**
@@ -97,7 +104,12 @@ public class Flavor {
* (by being the same), or by directly or indirectly replacing it
*/
public boolean satisfies(Flavor flavor) {
- if (this.equals(flavor)) return true;
+ if (this.equals(flavor)) {
+ return true;
+ }
+ if (this.retired) {
+ return false;
+ }
for (Flavor replaces : replacesFlavors)
if (replaces.satisfies(flavor))
return true;
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java
index 9451e47cbc3..ae2e5710d2e 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java
@@ -3,6 +3,7 @@ package com.yahoo.config.provision;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
+import com.yahoo.config.provisioning.FlavorsConfig;
import java.util.Collection;
import java.util.HashMap;
@@ -11,8 +12,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
-import com.yahoo.config.provisioning.FlavorsConfig;
-
/**
* All the available node flavors.
*
@@ -38,9 +37,8 @@ public class NodeFlavors {
/** Returns the flavor with the given name or throws an IllegalArgumentException if it does not exist */
public Flavor getFlavorOrThrow(String flavorName) {
- Optional<Flavor> flavor = getFlavor(flavorName);
- if ( flavor.isPresent()) return flavor.get();
- throw new IllegalArgumentException("Unknown flavor '" + flavorName + "'. Flavors are " + canonicalFlavorNames());
+ return getFlavor(flavorName).orElseThrow(() -> new IllegalArgumentException("Unknown flavor '" + flavorName +
+ "'. Flavors are " + canonicalFlavorNames()));
}
private List<String> canonicalFlavorNames() {
@@ -65,7 +63,21 @@ public class NodeFlavors {
}
flavor.freeze();
}
+ // Third pass, ensure that retired flavors have a replacement
+ for (Flavor flavor : flavors.values()) {
+ if (flavor.isRetired() && !hasReplacement(flavors.values(), flavor)) {
+ throw new IllegalStateException(
+ String.format("Flavor '%s' is retired, but has no replacement", flavor.name())
+ );
+ }
+ }
return flavors.values();
}
+ private static boolean hasReplacement(Collection<Flavor> flavors, Flavor flavor) {
+ return flavors.stream()
+ .filter(f -> !f.equals(flavor))
+ .anyMatch(f -> f.satisfies(flavor));
+ }
+
}
diff --git a/config-provisioning/src/main/resources/configdefinitions/flavors.def b/config-provisioning/src/main/resources/configdefinitions/flavors.def
index 26006c25df8..edcd957c0b2 100644
--- a/config-provisioning/src/main/resources/configdefinitions/flavors.def
+++ b/config-provisioning/src/main/resources/configdefinitions/flavors.def
@@ -39,3 +39,6 @@ flavor[].minDiskAvailableGb double default=0.0
# Human readable free text for description of node.
flavor[].description string default=""
+
+# The flavor is retired and should no longer be used.
+flavor[].retired bool default=false
diff --git a/config-provisioning/src/test/java/com/yahoo/config/provision/NodeFlavorsTest.java b/config-provisioning/src/test/java/com/yahoo/config/provision/NodeFlavorsTest.java
new file mode 100644
index 00000000000..3b55c05c7c6
--- /dev/null
+++ b/config-provisioning/src/test/java/com/yahoo/config/provision/NodeFlavorsTest.java
@@ -0,0 +1,80 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.config.provision;
+
+import com.yahoo.config.provisioning.FlavorsConfig;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+
+public class NodeFlavorsTest {
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void testReplacesWithBadValue() {
+ FlavorsConfig.Builder builder = new FlavorsConfig.Builder();
+ List<FlavorsConfig.Flavor.Builder> flavorBuilderList = new ArrayList<>();
+ FlavorsConfig.Flavor.Builder flavorBuilder = new FlavorsConfig.Flavor.Builder();
+ FlavorsConfig.Flavor.Replaces.Builder flavorReplacesBuilder = new FlavorsConfig.Flavor.Replaces.Builder();
+ flavorReplacesBuilder.name("non-existing-config");
+ flavorBuilder.name("strawberry").cost(2).replaces.add(flavorReplacesBuilder);
+ flavorBuilderList.add(flavorBuilder);
+ builder.flavor(flavorBuilderList);
+ FlavorsConfig config = new FlavorsConfig(builder);
+ exception.expect(IllegalStateException.class);
+ exception.expectMessage("Replaces for strawberry pointing to a non existing flavor: non-existing-config");
+ new NodeFlavors(config);
+ }
+
+ @Test
+ public void testConfigParsing() {
+ FlavorsConfig.Builder builder = new FlavorsConfig.Builder();
+ List<FlavorsConfig.Flavor.Builder> flavorBuilderList = new ArrayList<>();
+ {
+ FlavorsConfig.Flavor.Builder flavorBuilder = new FlavorsConfig.Flavor.Builder();
+ FlavorsConfig.Flavor.Replaces.Builder flavorReplacesBuilder = new FlavorsConfig.Flavor.Replaces.Builder();
+ flavorReplacesBuilder.name("banana");
+ flavorBuilder.name("strawberry").cost(2).replaces.add(flavorReplacesBuilder);
+ flavorBuilderList.add(flavorBuilder);
+ }
+ {
+ FlavorsConfig.Flavor.Builder flavorBuilder = new FlavorsConfig.Flavor.Builder();
+ flavorBuilder.name("banana").cost(3);
+ flavorBuilderList.add(flavorBuilder);
+ }
+ builder.flavor(flavorBuilderList);
+ FlavorsConfig config = new FlavorsConfig(builder);
+ NodeFlavors nodeFlavors = new NodeFlavors(config);
+ assertThat(nodeFlavors.getFlavor("banana").get().cost(), is(3));
+ }
+
+ @Test
+ public void testRetiredFlavorWithoutReplacement() {
+ FlavorsConfig.Builder builder = new FlavorsConfig.Builder();
+ List<FlavorsConfig.Flavor.Builder> flavorBuilderList = new ArrayList<>();
+ {
+ FlavorsConfig.Flavor.Builder flavorBuilder = new FlavorsConfig.Flavor.Builder();
+ flavorBuilder.name("retired").retired(true);
+ flavorBuilderList.add(flavorBuilder);
+ }
+ {
+ FlavorsConfig.Flavor.Builder flavorBuilder = new FlavorsConfig.Flavor.Builder();
+ flavorBuilder.name("chocolate");
+ flavorBuilderList.add(flavorBuilder);
+ }
+ builder.flavor(flavorBuilderList);
+ FlavorsConfig config = new FlavorsConfig(builder);
+ exception.expect(IllegalStateException.class);
+ exception.expectMessage("Flavor 'retired' is retired, but has no replacement");
+ new NodeFlavors(config);
+ }
+
+}