mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2024-11-30 12:34:01 -06:00
allow param defs to expand config models
This commit is contained in:
parent
d1541f0dd2
commit
0631f4aa05
@ -22,6 +22,7 @@ import io.nosqlbench.nb.api.errors.BasicError;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ConfigModel implements NBConfigModel {
|
public class ConfigModel implements NBConfigModel {
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
private final List<Param<?>> params = new ArrayList<>();
|
private final List<Param<?>> params = new ArrayList<>();
|
||||||
private Param<?> lastAdded = null;
|
private Param<?> lastAdded = null;
|
||||||
private final Class<?> ofType;
|
private final Class<?> ofType;
|
||||||
|
private final List<NBConfigModelExpander> expanders = new ArrayList<>();
|
||||||
|
|
||||||
private ConfigModel(Class<?> ofType, Param<?>... params) {
|
private ConfigModel(Class<?> ofType, Param<?>... params) {
|
||||||
this.ofType = ofType;
|
this.ofType = ofType;
|
||||||
@ -40,6 +42,7 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
public static ConfigModel of(Class<?> ofType, Param<?>... params) {
|
public static ConfigModel of(Class<?> ofType, Param<?>... params) {
|
||||||
return new ConfigModel(ofType, params);
|
return new ConfigModel(ofType, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConfigModel of(Class<?> ofType) {
|
public static ConfigModel of(Class<?> ofType) {
|
||||||
return new ConfigModel(ofType);
|
return new ConfigModel(ofType);
|
||||||
}
|
}
|
||||||
@ -47,7 +50,7 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
public static NBConfiguration defacto(ActivityDef def) {
|
public static NBConfiguration defacto(ActivityDef def) {
|
||||||
ConfigModel configModel = new ConfigModel(Object.class);
|
ConfigModel configModel = new ConfigModel(Object.class);
|
||||||
for (Map.Entry<String, Object> entry : def.getParams().entrySet()) {
|
for (Map.Entry<String, Object> entry : def.getParams().entrySet()) {
|
||||||
configModel.add(Param.defaultTo(entry.getKey(),entry.getValue().toString()));
|
configModel.add(Param.defaultTo(entry.getKey(), entry.getValue().toString()));
|
||||||
}
|
}
|
||||||
return configModel.apply(def.getParams());
|
return configModel.apply(def.getParams());
|
||||||
}
|
}
|
||||||
@ -61,6 +64,13 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a param that, when present in a runtime configuration, will cause the config
|
||||||
|
* model to be expanded dynamically. This is for scenarios in which you have external
|
||||||
|
* configurable resources or templates which contain their own models that can
|
||||||
|
* only be known at runtime.
|
||||||
|
*/
|
||||||
|
|
||||||
public NBConfigModel asReadOnly() {
|
public NBConfigModel asReadOnly() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -140,14 +150,19 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBConfiguration extractConfig(Map<String, ?> sharedConfig) {
|
public NBConfiguration extractConfig(Map<String, ?> sharedConfig) {
|
||||||
|
NBConfiguration matchedConfig = matchConfig(sharedConfig);
|
||||||
|
matchedConfig.getMap().keySet().forEach(sharedConfig::remove);
|
||||||
|
return new NBConfiguration(this, matchedConfig.getMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBConfiguration matchConfig(Map<String, ?> sharedConfig) {
|
||||||
LinkedHashMap<String, Object> extracted = new LinkedHashMap<>();
|
LinkedHashMap<String, Object> extracted = new LinkedHashMap<>();
|
||||||
for (String providedCfgField : sharedConfig.keySet()) {
|
for (String providedCfgField : sharedConfig.keySet()) {
|
||||||
if (getNamedParams().containsKey(providedCfgField)) {
|
if (getNamedParams().containsKey(providedCfgField)) {
|
||||||
extracted.put(providedCfgField, sharedConfig.get(providedCfgField));
|
extracted.put(providedCfgField, sharedConfig.get(providedCfgField));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extracted.keySet().forEach(sharedConfig::remove);
|
|
||||||
|
|
||||||
return new NBConfiguration(this, extracted);
|
return new NBConfiguration(this, extracted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +171,11 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
return extractConfig(cfg.getMap());
|
return extractConfig(cfg.getMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBConfiguration matchConfig(NBConfiguration cfg) {
|
||||||
|
return matchConfig(cfg.getMap());
|
||||||
|
}
|
||||||
|
|
||||||
private void assertDistinctSynonyms(Map<String, ?> config) {
|
private void assertDistinctSynonyms(Map<String, ?> config) {
|
||||||
List<String> names = new ArrayList<>();
|
List<String> names = new ArrayList<>();
|
||||||
for (Param<?> param : getParams()) {
|
for (Param<?> param : getParams()) {
|
||||||
@ -173,10 +193,12 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBConfiguration apply(Map<String, ?> config) {
|
public NBConfiguration apply(Map<String, ?> config) {
|
||||||
|
ConfigModel expanded = expand(this, config);
|
||||||
|
|
||||||
assertValidConfig(config);
|
assertValidConfig(config);
|
||||||
LinkedHashMap<String, Object> validConfig = new LinkedHashMap<>();
|
LinkedHashMap<String, Object> validConfig = new LinkedHashMap<>();
|
||||||
|
|
||||||
for (Param<?> param : params) {
|
for (Param<?> param : expanded.params) {
|
||||||
Class<?> type = param.getType();
|
Class<?> type = param.getType();
|
||||||
List<String> found = new ArrayList<>();
|
List<String> found = new ArrayList<>();
|
||||||
String activename = null;
|
String activename = null;
|
||||||
@ -188,7 +210,7 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (activename==null) {
|
if (activename == null) {
|
||||||
activename = param.getNames().get(0);
|
activename = param.getNames().get(0);
|
||||||
}
|
}
|
||||||
if (cval == null && param.isRequired()) {
|
if (cval == null && param.isRequired()) {
|
||||||
@ -205,9 +227,28 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void assertValidConfig(Map<String, ?> config) {
|
public void assertValidConfig(Map<String, ?> config) {
|
||||||
assertRequiredFields(config);
|
ConfigModel expanded = expand(this, config);
|
||||||
assertNoExtraneousFields(config);
|
expanded.assertRequiredFields(config);
|
||||||
assertDistinctSynonyms(config);
|
expanded.assertNoExtraneousFields(config);
|
||||||
|
expanded.assertDistinctSynonyms(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigModel expand(ConfigModel configModel, Map<String, ?> config) {
|
||||||
|
List<Param<?>> expanders = configModel.params.stream()
|
||||||
|
.filter(p -> p.getExpander()!=null).toList();
|
||||||
|
|
||||||
|
for (Param<?> expandingParameter : expanders) {
|
||||||
|
for (String name : expandingParameter.getNames()) {
|
||||||
|
if (config.containsKey(name)) {
|
||||||
|
Object triggeringValue = config.get(name);
|
||||||
|
expandingParameter.validate(triggeringValue);
|
||||||
|
NBConfigModelExpander expander = expandingParameter.getExpander();
|
||||||
|
NBConfigModel newModel = expander.apply(triggeringValue);
|
||||||
|
configModel = configModel.add(newModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return configModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -274,4 +315,14 @@ public class ConfigModel implements NBConfigModel {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("[").append(
|
||||||
|
params.stream().map(p -> p.getNames().get(0)).collect(Collectors.joining(",")))
|
||||||
|
.append("]");
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.nosqlbench.adapter.diag.optasks;
|
package io.nosqlbench.nb.api.config.standard;
|
||||||
|
|
||||||
import io.nosqlbench.nb.api.config.standard.NBConfigurable;
|
public interface NBConfigModelExpander {
|
||||||
|
NBConfigModel apply(Object value);
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
public interface DiagOpTask extends BiFunction<Long,Map<String,Object>, Map<String,Object>>, NBConfigurable {
|
|
||||||
}
|
}
|
@ -34,19 +34,22 @@ public class Param<T> {
|
|||||||
private final T defaultValue;
|
private final T defaultValue;
|
||||||
public boolean required;
|
public boolean required;
|
||||||
private Pattern regex;
|
private Pattern regex;
|
||||||
|
private final NBConfigModelExpander expander;
|
||||||
|
|
||||||
public Param(
|
public Param(
|
||||||
List<String> names,
|
List<String> names,
|
||||||
Class<? extends T> type,
|
Class<? extends T> type,
|
||||||
String description,
|
String description,
|
||||||
boolean required,
|
boolean required,
|
||||||
T defaultValue
|
T defaultValue,
|
||||||
|
NBConfigModelExpander expander
|
||||||
) {
|
) {
|
||||||
this.names = names;
|
this.names = names;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.required = required;
|
this.required = required;
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValue = defaultValue;
|
||||||
|
this.expander = expander;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +81,7 @@ public class Param<T> {
|
|||||||
* @param <V> Generic type for inference.
|
* @param <V> Generic type for inference.
|
||||||
*/
|
*/
|
||||||
public static <V> Param<V> optional(List<String> names, Class<V> type) {
|
public static <V> Param<V> optional(List<String> names, Class<V> type) {
|
||||||
return new Param<V>(names, type, null, false, null);
|
return new Param<V>(names, type, null, false, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,7 +95,7 @@ public class Param<T> {
|
|||||||
* @param <V> Generic type for inference.
|
* @param <V> Generic type for inference.
|
||||||
*/
|
*/
|
||||||
public static <V> Param<V> optional(List<String> names, Class<V> type, String description) {
|
public static <V> Param<V> optional(List<String> names, Class<V> type, String description) {
|
||||||
return new Param<V>(names, type, description, false, null);
|
return new Param<V>(names, type, description, false, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -106,7 +109,7 @@ public class Param<T> {
|
|||||||
* @param <V> Generic type for inference.
|
* @param <V> Generic type for inference.
|
||||||
*/
|
*/
|
||||||
public static <V> Param<V> optional(String name, Class<V> type) {
|
public static <V> Param<V> optional(String name, Class<V> type) {
|
||||||
return new Param<V>(List.of(name), type, null, false, null);
|
return new Param<V>(List.of(name), type, null, false, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,7 +123,7 @@ public class Param<T> {
|
|||||||
* @param <V> Generic type for inference.
|
* @param <V> Generic type for inference.
|
||||||
*/
|
*/
|
||||||
public static <V> Param<V> optional(String name, Class<V> type, String description) {
|
public static <V> Param<V> optional(String name, Class<V> type, String description) {
|
||||||
return new Param<V>(List.of(name), type, description, false, null);
|
return new Param<V>(List.of(name), type, description, false, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,7 +136,7 @@ public class Param<T> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static <V> Param<V> defaultTo(String name, V defaultValue) {
|
public static <V> Param<V> defaultTo(String name, V defaultValue) {
|
||||||
return new Param<V>(List.of(name), (Class<V>) defaultValue.getClass(), null, true, defaultValue);
|
return new Param<V>(List.of(name), (Class<V>) defaultValue.getClass(), null, true, defaultValue, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,7 +149,7 @@ public class Param<T> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static <V> Param<V> defaultTo(String name, V defaultValue, String description) {
|
public static <V> Param<V> defaultTo(String name, V defaultValue, String description) {
|
||||||
return new Param<V>(List.of(name), (Class<V>) defaultValue.getClass(), description, true, defaultValue);
|
return new Param<V>(List.of(name), (Class<V>) defaultValue.getClass(), description, true, defaultValue, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,15 +162,15 @@ public class Param<T> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static <V> Param<V> defaultTo(List<String> names, V defaultValue) {
|
public static <V> Param<V> defaultTo(List<String> names, V defaultValue) {
|
||||||
return new Param<V>(names, (Class<V>) defaultValue.getClass(), null, true, defaultValue);
|
return new Param<V>(names, (Class<V>) defaultValue.getClass(), null, true, defaultValue, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <V> Param<V> required(String name, Class<V> type) {
|
public static <V> Param<V> required(String name, Class<V> type) {
|
||||||
return new Param<V>(List.of(name), type, null, true, null);
|
return new Param<V>(List.of(name), type, null, true, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <V> Param<V> required(List<String> names, Class<V> type) {
|
public static <V> Param<V> required(List<String> names, Class<V> type) {
|
||||||
return new Param<V>(names, type, null, true, null);
|
return new Param<V>(names, type, null, true, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -228,7 +231,6 @@ public class Param<T> {
|
|||||||
|
|
||||||
public CheckResult<T> validate(Object value) {
|
public CheckResult<T> validate(Object value) {
|
||||||
|
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
if (isRequired()) {
|
if (isRequired()) {
|
||||||
return CheckResult.INVALID(this, null, "Value is null but " + this.getNames() + " is required");
|
return CheckResult.INVALID(this, null, "Value is null but " + this.getNames() + " is required");
|
||||||
@ -255,6 +257,15 @@ public class Param<T> {
|
|||||||
return CheckResult.VALID(this, value, "All validators passed for field '" + getNames() + "'");
|
return CheckResult.VALID(this, value, "All validators passed for field '" + getNames() + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public NBConfigModelExpander getExpander() {
|
||||||
|
return this.expander;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Param<T> expand(NBConfigModelExpander expander) {
|
||||||
|
return new Param<>(names, type, description, required, defaultValue, expander);
|
||||||
|
}
|
||||||
|
|
||||||
public final static class CheckResult<T> {
|
public final static class CheckResult<T> {
|
||||||
public final Param<T> element;
|
public final Param<T> element;
|
||||||
public final Object value;
|
public final Object value;
|
||||||
|
Loading…
Reference in New Issue
Block a user