summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-lib/src/main/java/com/yahoo/config/ConfigInstance.java94
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigInstanceBuilder.java117
3 files changed, 119 insertions, 95 deletions
diff --git a/config-lib/src/main/java/com/yahoo/config/ConfigInstance.java b/config-lib/src/main/java/com/yahoo/config/ConfigInstance.java
index b47bd17a5ba..43fb52dcd72 100644
--- a/config-lib/src/main/java/com/yahoo/config/ConfigInstance.java
+++ b/config-lib/src/main/java/com/yahoo/config/ConfigInstance.java
@@ -20,8 +20,6 @@ import com.yahoo.config.codegen.LeafCNode;
*/
public abstract class ConfigInstance extends InnerNode {
- private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(ConfigInstance.class.getName());
-
public interface Builder extends ConfigBuilder {
/**
@@ -41,98 +39,6 @@ public abstract class ConfigInstance extends InnerNode {
default void setApplyOnRestart(boolean applyOnRestart) { throw new java.lang.UnsupportedOperationException(); }
- default ConfigInstance buildInstance(InnerCNode targetDef) {
- try {
- if (targetDef != null) applyDef(this, targetDef);
- Class<? extends ConfigInstance> clazz = getConfigClass(getClass());
- return clazz.getConstructor(getClass()).newInstance(this);
- } catch (Exception e) {
- throw new ConfigurationRuntimeException(e);
- }
- }
-
- /**
- * If some fields on the builder are null now, set them from the def. Do recursively.
- * <p>
- * If the targetDef has some schema incompatibilities, they are not handled here
- * (except logging in some cases), but in ConfigInstance.serialize().
- *
- * @param builder a {@link com.yahoo.config.ConfigBuilder}
- * @param targetDef a config definition
- * @throws Exception if applying values form config definitions fails
- */
- static void applyDef(ConfigBuilder builder, InnerCNode targetDef) throws Exception {
- for (Map.Entry<String, CNode> e: targetDef.children().entrySet()) {
- CNode node = e.getValue();
- if (node instanceof LeafCNode) {
- setLeafValueIfUnset(targetDef, builder, (LeafCNode)node);
- } else if (node instanceof InnerCNode) {
- // Is there a private field on the builder that matches this inner node in the def?
- if (hasField(builder.getClass(), node.getName())) {
- Field innerField = builder.getClass().getDeclaredField(node.getName());
- innerField.setAccessible(true);
- Object innerFieldVal = innerField.get(builder);
- if (innerFieldVal instanceof List) {
- // inner array? Check that list elems are ConfigBuilder
- List<?> innerList = (List<?>) innerFieldVal;
- for (Object b : innerList) {
- if (b instanceof ConfigBuilder) {
- applyDef((ConfigBuilder) b, (InnerCNode) node);
- }
- }
- } else if (innerFieldVal instanceof ConfigBuilder) {
- // Struct perhaps
- applyDef((ConfigBuilder) innerFieldVal, (InnerCNode) node);
- } else {
- // Likely a config value mismatch. That is handled in ConfigInstance.serialize() (error message, omit from response.)
- }
- }
- }
- }
- }
-
- private static boolean hasField(Class<?> aClass, String name) {
- for (Field field : aClass.getDeclaredFields()) {
- if (name.equals(field.getName())) {
- return true;
- }
- }
- return false;
- }
-
- private static void setLeafValueIfUnset(InnerCNode targetDef, Object builder, LeafCNode node) throws Exception {
- if (hasField(builder.getClass(), node.getName())) {
- Field field = builder.getClass().getDeclaredField(node.getName());
- field.setAccessible(true);
- Object val = field.get(builder);
- if (val==null) {
- // Not set on builder, if the leaf node has a default value, try the private setter that takes String
- try {
- if (node.getDefaultValue()!=null) {
- Method setter = builder.getClass().getDeclaredMethod(node.getName(), String.class);
- setter.setAccessible(true);
- setter.invoke(builder, node.getDefaultValue().getValue());
- }
- } catch (Exception e) {
- log.log(Level.SEVERE,
- "For config '" + targetDef.getFullName() + "': " +
- "Unable to apply the default value for field '" + node.getName() +
- "' to config Builder (where it wasn't set)",
- e);
- }
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private static Class<? extends ConfigInstance> getConfigClass(Class<? extends ConfigInstance.Builder> builderClass) {
- Class<?> configClass = builderClass.getEnclosingClass();
- if (configClass == null || ! ConfigInstance.class.isAssignableFrom(configClass)) {
- throw new ConfigurationRuntimeException("Builder class " + builderClass + " has enclosing class " + configClass + ", which is not a ConfigInstance");
- }
- return (Class<? extends ConfigInstance>) configClass;
- }
-
}
public interface Producer {}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
index 4b61021bc38..c82431dc8cd 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
@@ -144,7 +144,7 @@ public class Application implements ModelResult {
}
else {
try {
- ConfigInstance instance = builder.buildInstance(def.getCNode());
+ ConfigInstance instance = ConfigInstanceBuilder.buildInstance(builder, def.getCNode());
payload = ConfigPayload.fromInstance(instance);
} catch (ConfigurationRuntimeException e) {
// This can happen in cases where services ask for config that no longer exist before they have been able
@@ -218,4 +218,5 @@ public class Application implements ModelResult {
public Set<String> allConfigIds() {
return model.allConfigIds();
}
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigInstanceBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigInstanceBuilder.java
new file mode 100644
index 00000000000..389e8394c9e
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ConfigInstanceBuilder.java
@@ -0,0 +1,117 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.server.application;
+
+import com.yahoo.config.ConfigBuilder;
+import com.yahoo.config.ConfigInstance;
+import com.yahoo.config.ConfigurationRuntimeException;
+import com.yahoo.config.codegen.CNode;
+import com.yahoo.config.codegen.InnerCNode;
+import com.yahoo.config.codegen.LeafCNode;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+
+/**
+ * Builds a ConfigInstance from a ConfigInstance.Builder.
+ * (Put here not in ConfigInstance.Builder temporarily to work around dependency problems.)
+ */
+class ConfigInstanceBuilder {
+
+ private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(ConfigInstanceBuilder.class.getName());
+
+ static ConfigInstance buildInstance(ConfigInstance.Builder builder, InnerCNode targetDef) {
+ try {
+ if (targetDef != null) applyDef(builder, targetDef);
+ Class<? extends ConfigInstance> clazz = getConfigClass(builder.getClass());
+ return clazz.getConstructor(builder.getClass()).newInstance(builder);
+ } catch (Exception e) {
+ throw new ConfigurationRuntimeException(e);
+ }
+ }
+
+ /**
+ * If some fields on the builder are null now, set them from the def. Do recursively.
+ * <p>
+ * If the targetDef has some schema incompatibilities, they are not handled here
+ * (except logging in some cases), but in ConfigInstance.serialize().
+ *
+ * @param builder a {@link com.yahoo.config.ConfigBuilder}
+ * @param targetDef a config definition
+ * @throws Exception if applying values form config definitions fails
+ */
+ static void applyDef(ConfigBuilder builder, InnerCNode targetDef) throws Exception {
+ for (Map.Entry<String, CNode> e: targetDef.children().entrySet()) {
+ CNode node = e.getValue();
+ if (node instanceof LeafCNode) {
+ setLeafValueIfUnset(targetDef, builder, (LeafCNode)node);
+ } else if (node instanceof InnerCNode) {
+ // Is there a private field on the builder that matches this inner node in the def?
+ if (hasField(builder.getClass(), node.getName())) {
+ Field innerField = builder.getClass().getDeclaredField(node.getName());
+ innerField.setAccessible(true);
+ Object innerFieldVal = innerField.get(builder);
+ if (innerFieldVal instanceof List) {
+ // inner array? Check that list elems are ConfigBuilder
+ List<?> innerList = (List<?>) innerFieldVal;
+ for (Object b : innerList) {
+ if (b instanceof ConfigBuilder) {
+ applyDef((ConfigBuilder) b, (InnerCNode) node);
+ }
+ }
+ } else if (innerFieldVal instanceof ConfigBuilder) {
+ // Struct perhaps
+ applyDef((ConfigBuilder) innerFieldVal, (InnerCNode) node);
+ } else {
+ // Likely a config value mismatch. That is handled in ConfigInstance.serialize() (error message, omit from response.)
+ }
+ }
+ }
+ }
+ }
+
+ private static boolean hasField(Class<?> aClass, String name) {
+ for (Field field : aClass.getDeclaredFields()) {
+ if (name.equals(field.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void setLeafValueIfUnset(InnerCNode targetDef, Object builder, LeafCNode node) throws Exception {
+ if (hasField(builder.getClass(), node.getName())) {
+ Field field = builder.getClass().getDeclaredField(node.getName());
+ field.setAccessible(true);
+ Object val = field.get(builder);
+ if (val==null) {
+ // Not set on builder, if the leaf node has a default value, try the private setter that takes String
+ try {
+ if (node.getDefaultValue()!=null) {
+ Method setter = builder.getClass().getDeclaredMethod(node.getName(), String.class);
+ setter.setAccessible(true);
+ setter.invoke(builder, node.getDefaultValue().getValue());
+ }
+ } catch (Exception e) {
+ log.log(Level.SEVERE,
+ "For config '" + targetDef.getFullName() + "': " +
+ "Unable to apply the default value for field '" + node.getName() +
+ "' to config Builder (where it wasn't set)",
+ e);
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Class<? extends ConfigInstance> getConfigClass(Class<? extends ConfigInstance.Builder> builderClass) {
+ Class<?> configClass = builderClass.getEnclosingClass();
+ if (configClass == null || ! ConfigInstance.class.isAssignableFrom(configClass)) {
+ throw new ConfigurationRuntimeException("Builder class " + builderClass + " has enclosing class " + configClass + ", which is not a ConfigInstance");
+ }
+ return (Class<? extends ConfigInstance>) configClass;
+ }
+
+}