ENT-5109 Harmonize config-common, make everything compile again and harmonize NetworkParameterOverridesSpec. (#6082)

This commit is contained in:
Christian Sailer 2020-03-19 15:43:08 +00:00 committed by GitHub
parent dd7852f2b8
commit 82d9995717
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 326 additions and 302 deletions

View File

@ -21,7 +21,7 @@ object Configuration {
/**
* Describes a [Config] hiding sensitive data.
*/
fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue = { value -> ConfigValueFactory.fromAnyRef(value.toString()) }): ConfigValue?
fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue = { value -> ConfigValueFactory.fromAnyRef(value.toString()) }, options: Options): ConfigValue?
}
object Value {
@ -36,10 +36,11 @@ object Configuration {
*
* @throws ConfigException.Missing if the [Config] does not specify the value.
* @throws ConfigException.WrongType if the [Config] specifies a value of the wrong type.
* @throws ConfigException.BadValue if the [Config] specifies a value of the correct type, but this in unacceptable according to application-level validation rules..
* @throws ConfigException.BadValue if the [Config] specifies a value of the correct type, but this in unacceptable according to
* application-level validation rules.
*/
@Throws(ConfigException.Missing::class, ConfigException.WrongType::class, ConfigException.BadValue::class)
fun valueIn(configuration: Config): TYPE
fun valueIn(configuration: Config, options: Options): TYPE
/**
* Returns whether the value is specified by the [Config].
@ -50,27 +51,28 @@ object Configuration {
* Returns a value out of a [Config] if all is good, or null if no value is present. Otherwise, it throws an exception.
*
* @throws ConfigException.WrongType if the [Config] specifies a value of the wrong type.
* @throws ConfigException.BadValue if the [Config] specifies a value of the correct type, but this in unacceptable according to application-level validation rules..
* @throws ConfigException.BadValue if the [Config] specifies a value of the correct type, but this in unacceptable according to
* application-level validation rules.
*/
@Throws(ConfigException.WrongType::class, ConfigException.BadValue::class)
fun valueInOrNull(configuration: Config): TYPE? {
fun valueInOrNull(configuration: Config, options: Options): TYPE? {
return when {
isSpecifiedBy(configuration) -> valueIn(configuration)
isSpecifiedBy(configuration) -> valueIn(configuration, options)
else -> null
}
}
}
/**
* Able to parse a value from a [Config] and [Configuration.Validation.Options], returning a [Valid] result containing either the value itself, or some [Configuration.Validation.Error]s.
* Able to parse a value from a [Config] and [Configuration.Options], returning a [Valid] result containing either the value itself, or some [Configuration.Validation.Error]s.
*/
interface Parser<VALUE> {
/**
* Returns a [Valid] wrapper either around a valid value extracted from the [Config], or around a set of [Configuration.Validation.Error] with details about what went wrong.
*/
fun parse(configuration: Config, options: Configuration.Validation.Options = Configuration.Validation.Options.defaults): Valid<VALUE>
fun parse(configuration: Config, options: Options = Options.defaults): Valid<VALUE>
}
}
@ -109,11 +111,6 @@ object Configuration {
*/
interface Definition<TYPE> : Configuration.Property.Metadata, Configuration.Validator, Configuration.Value.Extractor<TYPE>, Configuration.Describer, Configuration.Value.Parser<TYPE> {
/**
* Validates target [Config] with default [Configuration.Validation.Options].
*/
fun validate(target: Config): Valid<Config> = validate(target, Configuration.Validation.Options.defaults)
override fun isSpecifiedBy(configuration: Config): Boolean = configuration.hasPath(key)
/**
@ -181,9 +178,8 @@ object Configuration {
fun <MAPPED> map(mappedTypeName: String, convert: (TYPE) -> MAPPED): Standard<MAPPED> = mapValid(mappedTypeName) { value -> valid(convert.invoke(value)) }
}
override fun parse(configuration: Config, options: Configuration.Validation.Options): Validated<TYPE, Validation.Error> {
return validate(configuration, options).mapValid { config -> valid(valueIn(config)) }
override fun parse(configuration: Config, options: Configuration.Options): Validated<TYPE, Validation.Error> {
return validate(configuration, options).mapValid { config -> valid(valueIn(config, options)) }
}
companion object {
@ -199,7 +195,6 @@ object Configuration {
* Returns a [Configuration.Property.Definition.Standard] with value of type [Int].
*/
fun int(key: String, sensitive: Boolean = false): Standard<Int> = long(key, sensitive).mapValid { value ->
try {
valid(Math.toIntExact(value))
} catch (e: ArithmeticException) {
@ -210,18 +205,17 @@ object Configuration {
/**
* Returns a [Configuration.Property.Definition.Standard] with value of type [Boolean].
*/
fun boolean(key: String, sensitive: Boolean = false): Standard<Boolean> = StandardProperty(key, Boolean::class.javaObjectType.simpleName, Config::getBoolean, Config::getBooleanList, sensitive)
fun boolean(key: String, sensitive: Boolean = false): Standard<Boolean> = StandardProperty(key, Boolean::class.javaObjectType.simpleName, { config, path, _ -> config.getBoolean(path) }, { config, path, _ -> config.getBooleanList(path) }, sensitive)
/**
* Returns a [Configuration.Property.Definition.Standard] with value of type [Double].
*/
fun double(key: String, sensitive: Boolean = false): Standard<Double> = StandardProperty(key, Double::class.javaObjectType.simpleName, Config::getDouble, Config::getDoubleList, sensitive)
fun double(key: String, sensitive: Boolean = false): Standard<Double> = StandardProperty(key, Double::class.javaObjectType.simpleName, { config, path, _ -> config.getDouble(path) }, { config, path, _ -> config.getDoubleList(path) }, sensitive)
/**
* Returns a [Configuration.Property.Definition.Standard] with value of type [Float].
*/
fun float(key: String, sensitive: Boolean = false): Standard<Float> = double(key, sensitive).mapValid { value ->
val floatValue = value.toFloat()
if (floatValue.isInfinite() || floatValue.isNaN()) {
invalid<Float, Configuration.Validation.Error>(Configuration.Validation.Error.BadValue.of(key, Float::class.javaObjectType.simpleName, "Provided value exceeds Float range."))
@ -233,24 +227,43 @@ object Configuration {
/**
* Returns a [Configuration.Property.Definition.Standard] with value of type [String].
*/
fun string(key: String, sensitive: Boolean = false): Standard<String> = StandardProperty(key, String::class.java.simpleName, Config::getString, Config::getStringList, sensitive)
fun string(key: String, sensitive: Boolean = false): Standard<String> = StandardProperty(
key,
String::class.java.simpleName,
{ config, path, _ -> config.getString(path) },
{ config, path, _ -> config.getStringList(path) },
sensitive
)
/**
* Returns a [Configuration.Property.Definition.Standard] with value of type [Duration].
*/
fun duration(key: String, sensitive: Boolean = false): Standard<Duration> = StandardProperty(key, Duration::class.java.simpleName, Config::getDuration, Config::getDurationList, sensitive)
fun duration(key: String, sensitive: Boolean = false): Standard<Duration> = StandardProperty(key, Duration::class.java.simpleName, { config, path, _ -> config.getDuration(path) }, { config, path, _ -> config.getDurationList(path) }, sensitive)
/**
* Returns a [Configuration.Property.Definition.Standard] with value of type [ConfigObject].
* It supports an optional [Configuration.Schema], which is used for validation and more when provided.
*/
fun nestedObject(key: String, schema: Schema? = null, sensitive: Boolean = false): Standard<ConfigObject> = StandardProperty(key, ConfigObject::class.java.simpleName, Config::getObject, Config::getObjectList, sensitive, schema)
fun nestedObject(key: String, schema: Schema? = null, sensitive: Boolean = false): Standard<ConfigObject> = StandardProperty(
key,
ConfigObject::class.java.simpleName,
{ config, path, _ -> config.getObject(path) },
{ config, path, _ -> config.getObjectList(path) },
sensitive,
schema
)
/**
* Returns a [Configuration.Property.Definition.Standard] with value of type [ENUM].
* This property expects a value in the configuration matching one of the cases of [ENUM], as text, in uppercase.
*/
fun <ENUM : Enum<ENUM>> enum(key: String, enumClass: KClass<ENUM>, sensitive: Boolean = false): Standard<ENUM> = StandardProperty(key, enumClass.java.simpleName, { conf: Config, propertyKey: String -> conf.getEnum(enumClass.java, propertyKey) }, { conf: Config, propertyKey: String -> conf.getEnumList(enumClass.java, propertyKey) }, sensitive)
fun <ENUM : Enum<ENUM>> enum(key: String, enumClass: KClass<ENUM>, sensitive: Boolean = false): Standard<ENUM> = StandardProperty(
key,
enumClass.java.simpleName,
{ conf: Config, propertyKey: String, _ -> conf.getEnum(enumClass.java, propertyKey) },
{ conf: Config, propertyKey: String, _ -> conf.getEnumList(enumClass.java, propertyKey) },
sensitive
)
}
}
}
@ -275,12 +288,7 @@ object Configuration {
*/
val properties: Set<Property.Definition<*>>
/**
* Validates target [Config] with default [Configuration.Validation.Options].
*/
fun validate(target: Config): Valid<Config> = validate(target, Configuration.Validation.Options.defaults)
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue): ConfigValue
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options): ConfigValue
companion object {
@ -368,35 +376,35 @@ object Configuration {
override fun description() = schema.description()
override fun validate(target: Config, options: Validation.Options) = schema.validate(target, options)
override fun validate(target: Config, options: Options) = schema.validate(target, options)
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue) = schema.describe(configuration, serialiseValue)
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options) = schema.describe(configuration, serialiseValue, options)
final override fun parse(configuration: Config, options: Configuration.Validation.Options): Valid<VALUE> = validate(configuration, options).mapValid(::parseValid)
final override fun parse(configuration: Config, options: Options): Valid<VALUE> = validate(configuration, options).mapValid { parseValid(it, options) }
/**
* Implement to define further mapping and validation logic, assuming the underlying raw [Config] is correct in terms of this [Configuration.Specification].
*/
protected abstract fun parseValid(configuration: Config): Valid<VALUE>
protected abstract fun parseValid(configuration: Config, options: Options): Valid<VALUE>
}
/**
* Validation and processing options.
* @property strict whether to raise unknown property keys as errors.
*/
class Options(val strict: Boolean = false) {
companion object {
/**
* Default [Config] options, without [strict] parsing enabled.
*/
val defaults: Configuration.Options = Options()
}
}
object Validation {
/**
* [Config] validation options.
* @property strict whether to raise unknown property keys as errors.
*/
data class Options(val strict: Boolean) {
companion object {
/**
* Default [Config] validation options, without [strict] parsing enabled.
*/
val defaults: Configuration.Validation.Options = Options(strict = false)
}
}
/**
* Super-type for the errors raised by the parsing and validation of a [Config] object.
*
@ -531,7 +539,7 @@ object Configuration {
}
/**
* Raised when a key-value pair appeared in the [Config] object without a matching property in the [Configuration.Schema], and [Configuration.Validation.Options.strict] was enabled.
* Raised when a key-value pair appeared in the [Config] object without a matching property in the [Configuration.Schema], and [Configuration.Options.strict] was enabled.
*/
class Unknown private constructor(override val keyName: String, containingPath: List<String> = emptyList()) : Configuration.Validation.Error(keyName, null, message(keyName), containingPath) {
@ -586,5 +594,5 @@ object Configuration {
/**
* Defines the ability to validate a [Config] object, producing a valid [Config] or a set of [Configuration.Validation.Error].
*/
interface Validator : net.corda.common.validation.internal.Validator<Config, Configuration.Validation.Error, Configuration.Validation.Options>
interface Validator : net.corda.common.validation.internal.Validator<Config, Configuration.Validation.Error, Configuration.Options>
}

View File

@ -5,10 +5,9 @@ import net.corda.common.validation.internal.Validated
import net.corda.common.validation.internal.Validated.Companion.invalid
import net.corda.common.validation.internal.Validated.Companion.valid
internal class LongProperty(key: String, sensitive: Boolean = false) : StandardProperty<Long>(key, Long::class.javaObjectType.simpleName, Config::getLong, Config::getLongList, sensitive) {
override fun validate(target: Config, options: Configuration.Validation.Options): Valid<Config> {
internal class LongProperty(key: String, sensitive: Boolean = false) : StandardProperty<Long>(key, Long::class.javaObjectType.simpleName, { config, path, _ -> config.getLong(path) }, { config, path, _ -> config.getLongList(path) }, sensitive) {
override fun validate(target: Config, options: Configuration.Options): Valid<Config> {
val validated = super.validate(target, options)
if (validated.isValid && target.getValue(key).unwrapped().toString().contains(".")) {
return invalid(ConfigException.WrongType(target.origin(), key, Long::class.javaObjectType.simpleName, Double::class.javaObjectType.simpleName).toValidationError(key, typeName))
@ -17,9 +16,11 @@ internal class LongProperty(key: String, sensitive: Boolean = false) : StandardP
}
}
internal open class StandardProperty<TYPE : Any>(override val key: String, typeNameArg: String, private val extractSingleValue: (Config, String) -> TYPE, internal val extractListValue: (Config, String) -> List<TYPE>, override val isSensitive: Boolean = false, final override val schema: Configuration.Schema? = null) : Configuration.Property.Definition.Standard<TYPE> {
typealias ValueSelector<T> = (Config, String, Configuration.Options) -> T
override fun valueIn(configuration: Config) = extractSingleValue.invoke(configuration, key)
internal open class StandardProperty<TYPE : Any>(override val key: String, typeNameArg: String, private val extractSingleValue: ValueSelector<TYPE>, internal val extractListValue: ValueSelector<List<TYPE>>, override val isSensitive: Boolean = false, final override val schema: Configuration.Schema? = null) : Configuration.Property.Definition.Standard<TYPE> {
override fun valueIn(configuration: Config, options: Configuration.Options) = extractSingleValue.invoke(configuration, key, options)
override val typeName: String = schema?.let { "#${it.name ?: "Object@$key"}" } ?: typeNameArg
@ -29,20 +30,18 @@ internal open class StandardProperty<TYPE : Any>(override val key: String, typeN
override fun list(): Configuration.Property.Definition.RequiredList<TYPE> = ListProperty(this)
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue): ConfigValue {
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options): ConfigValue {
if (isSensitive) {
return valueDescription(Configuration.Property.Definition.SENSITIVE_DATA_PLACEHOLDER, serialiseValue)
}
return schema?.describe(configuration.getConfig(key), serialiseValue) ?: valueDescription(valueIn(configuration), serialiseValue)
return schema?.describe(configuration.getConfig(key), serialiseValue, options) ?: valueDescription(valueIn(configuration, options), serialiseValue)
}
override val isMandatory = true
override fun validate(target: Config, options: Configuration.Validation.Options): Valid<Config> {
override fun validate(target: Config, options: Configuration.Options): Valid<Config> {
val errors = mutableSetOf<Configuration.Validation.Error>()
errors += errorsWhenExtractingValue(target)
errors += errorsWhenExtractingValue(target, options)
if (errors.isEmpty()) {
schema?.let { nestedSchema ->
val nestedConfig: Config? = target.getConfig(key)
@ -61,15 +60,19 @@ private class ListProperty<TYPE : Any>(delegate: StandardProperty<TYPE>) : Requi
override val typeName: String = "List<${delegate.typeName}>"
override fun valueIn(configuration: Config): List<TYPE> = delegate.extractListValue.invoke(configuration, key)
override fun validate(target: Config, options: Configuration.Validation.Options): Valid<Config> {
override fun valueIn(configuration: Config, options: Configuration.Options): List<TYPE> = delegate.extractListValue.invoke(configuration, key, options)
override fun validate(target: Config, options: Configuration.Options): Valid<Config> {
val errors = mutableSetOf<Configuration.Validation.Error>()
errors += errorsWhenExtractingValue(target)
errors += errorsWhenExtractingValue(target, options)
if (errors.isEmpty()) {
delegate.schema?.let { schema ->
errors += valueIn(target).asSequence().map { element -> element as ConfigObject }.map(ConfigObject::toConfig).mapIndexed { index, targetConfig -> schema.validate(targetConfig, options).errors.map { error -> error.withContainingPath(*error.containingPath(index).toTypedArray()) } }.fold(emptyList<Configuration.Validation.Error>()) { one, other -> one + other }.toSet()
errors += valueIn(target, options).asSequence()
.map { element -> element as ConfigObject }
.map(ConfigObject::toConfig)
.mapIndexed { index, targetConfig -> schema.validate(targetConfig, options).errors.map { error -> error.withContainingPath(*error.containingPath(index).toTypedArray()) } }
.fold(emptyList<Configuration.Validation.Error>()) { one, other -> one + other }
.toSet()
}
}
return Validated.withResult(target, errors)
@ -77,17 +80,16 @@ private class ListProperty<TYPE : Any>(delegate: StandardProperty<TYPE>) : Requi
override fun <MAPPED> mapValid(mappedTypeName: String, convert: (List<TYPE>) -> Validated<MAPPED, Configuration.Validation.Error>): Configuration.Property.Definition.Required<MAPPED> = ListMappingProperty(this, mappedTypeName, convert)
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue): ConfigValue {
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options): ConfigValue {
if (isSensitive) {
return valueDescription(Configuration.Property.Definition.SENSITIVE_DATA_PLACEHOLDER, serialiseValue)
}
return when {
delegate.schema != null -> {
val elementsDescription = valueIn(configuration).asSequence().map { it as ConfigObject }.map(ConfigObject::toConfig).map { delegate.schema.describe(it, serialiseValue) }.toList()
val elementsDescription = valueIn(configuration, options).asSequence().map { it as ConfigObject }.map(ConfigObject::toConfig).map { delegate.schema.describe(it, serialiseValue, options) }.toList()
ConfigValueFactory.fromIterable(elementsDescription)
}
else -> valueDescription(valueIn(configuration), serialiseValue)
else -> valueDescription(valueIn(configuration, options), serialiseValue)
}
}
@ -106,16 +108,17 @@ private class OptionalPropertyWithDefault<TYPE>(delegate: Configuration.Property
override val typeName: String = delegate.typeName.removeSuffix("?")
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue): ConfigValue? = delegate.describe(configuration, serialiseValue) ?: valueDescription(if (isSensitive) Configuration.Property.Definition.SENSITIVE_DATA_PLACEHOLDER else defaultValue, serialiseValue)
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options): ConfigValue? = delegate.describe(configuration, serialiseValue, options) ?: valueDescription(if (isSensitive) Configuration.Property.Definition.SENSITIVE_DATA_PLACEHOLDER else defaultValue, serialiseValue)
override fun valueIn(configuration: Config): TYPE = delegate.valueIn(configuration) ?: defaultValue
override fun valueIn(configuration: Config, options: Configuration.Options): TYPE = delegate.valueIn(configuration, options) ?: defaultValue
override fun validate(target: Config, options: Configuration.Validation.Options): Valid<Config> = delegate.validate(target, options)
override fun validate(target: Config, options: Configuration.Options): Valid<Config> = delegate.validate(target, options)
}
private class FunctionalProperty<TYPE, MAPPED>(delegate: Configuration.Property.Definition.Standard<TYPE>, private val mappedTypeName: String, internal val extractListValue: (Config, String) -> List<TYPE>, private val convert: (TYPE) -> Valid<MAPPED>) : RequiredDelegatedProperty<MAPPED, Configuration.Property.Definition.Standard<TYPE>>(delegate), Configuration.Property.Definition.Standard<MAPPED> {
private class FunctionalProperty<TYPE, MAPPED>(delegate: Configuration.Property.Definition.Standard<TYPE>, private val mappedTypeName: String, internal val extractListValue: ValueSelector<List<TYPE>>, private val convert: (TYPE) -> Valid<MAPPED>)
: RequiredDelegatedProperty<MAPPED, Configuration.Property.Definition.Standard<TYPE>>(delegate), Configuration.Property.Definition.Standard<MAPPED> {
override fun valueIn(configuration: Config) = convert.invoke(delegate.valueIn(configuration)).value()
override fun valueIn(configuration: Config, options: Configuration.Options) = convert.invoke(delegate.valueIn(configuration, options)).value()
override val typeName: String = if (super.typeName == "#$mappedTypeName") super.typeName else "$mappedTypeName(${super.typeName})"
@ -123,29 +126,31 @@ private class FunctionalProperty<TYPE, MAPPED>(delegate: Configuration.Property.
override fun list(): Configuration.Property.Definition.RequiredList<MAPPED> = FunctionalListProperty(this)
override fun validate(target: Config, options: Configuration.Validation.Options): Valid<Config> {
override fun validate(target: Config, options: Configuration.Options): Valid<Config> {
val errors = mutableSetOf<Configuration.Validation.Error>()
errors += delegate.validate(target, options).errors
if (errors.isEmpty()) {
errors += convert.invoke(delegate.valueIn(target)).mapErrors { error -> error.with(delegate.key, mappedTypeName) }.errors
errors += convert.invoke(delegate.valueIn(target, options)).mapErrors { error -> error.with(delegate.key, mappedTypeName) }.errors
}
return Validated.withResult(target, errors)
}
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue) = delegate.describe(configuration, serialiseValue)
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options) = delegate.describe(configuration, serialiseValue, options)
}
private class FunctionalListProperty<RAW, TYPE>(delegate: FunctionalProperty<RAW, TYPE>) : RequiredDelegatedProperty<List<TYPE>, FunctionalProperty<RAW, TYPE>>(delegate), Configuration.Property.Definition.RequiredList<TYPE> {
override val typeName: String = "List<${super.typeName}>"
override fun valueIn(configuration: Config): List<TYPE> = delegate.extractListValue.invoke(configuration, key).asSequence().map { configObject(key to ConfigValueFactory.fromAnyRef(it)) }.map(ConfigObject::toConfig).map(delegate::valueIn).toList()
override fun validate(target: Config, options: Configuration.Validation.Options): Valid<Config> {
override fun valueIn(configuration: Config, options: Configuration.Options): List<TYPE> = delegate.extractListValue.invoke(configuration, key, options).asSequence()
.map { configObject(key to ConfigValueFactory.fromAnyRef(it)) }
.map(ConfigObject::toConfig)
.map { delegate.valueIn(it, options) }
.toList()
override fun validate(target: Config, options: Configuration.Options): Valid<Config> {
val list = try {
delegate.extractListValue.invoke(target, key)
delegate.extractListValue.invoke(target, key, options)
} catch (e: ConfigException) {
if (isErrorExpected(e)) {
return invalid(e.toValidationError(key, typeName))
@ -153,7 +158,11 @@ private class FunctionalListProperty<RAW, TYPE>(delegate: FunctionalProperty<RAW
throw e
}
}
val errors = list.asSequence().map { configObject(key to ConfigValueFactory.fromAnyRef(it)) }.mapIndexed { index, value -> delegate.validate(value.toConfig(), options).errors.map { error -> error.withContainingPath(*error.containingPath(index).toTypedArray()) } }.fold(emptyList<Configuration.Validation.Error>()) { one, other -> one + other }.toSet()
val errors = list.asSequence()
.map { configObject(key to ConfigValueFactory.fromAnyRef(it)) }
.mapIndexed { index, value -> delegate.validate(value.toConfig(), options).errors.map { error -> error.withContainingPath(*error.containingPath(index).toTypedArray()) } }
.fold(emptyList<Configuration.Validation.Error>()) { one, other -> one + other }
.toSet()
return Validated.withResult(target, errors)
}
@ -165,12 +174,11 @@ private class FunctionalListProperty<RAW, TYPE>(delegate: FunctionalProperty<RAW
}
}
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue): ConfigValue {
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options): ConfigValue {
if (isSensitive) {
return valueDescription(Configuration.Property.Definition.SENSITIVE_DATA_PLACEHOLDER, serialiseValue)
}
return delegate.schema?.let { schema -> valueDescription(valueIn(configuration).asSequence().map { element -> valueDescription(element, serialiseValue) }.map { it as ConfigObject }.map(ConfigObject::toConfig).map { schema.describe(it, serialiseValue) }.toList(), serialiseValue) } ?: valueDescription(valueIn(configuration), serialiseValue)
return delegate.schema?.let { schema -> valueDescription(valueIn(configuration, options).asSequence() .map { element -> valueDescription(element, serialiseValue) } .map { it as ConfigObject } .map(ConfigObject::toConfig) .map { schema.describe(it, serialiseValue, options) } .toList(), serialiseValue) } ?: valueDescription(valueIn(configuration, options), serialiseValue)
}
override fun <MAPPED> mapValid(mappedTypeName: String, convert: (List<TYPE>) -> Validated<MAPPED, Configuration.Validation.Error>): Configuration.Property.Definition.Required<MAPPED> = ListMappingProperty(this, mappedTypeName, convert)
@ -187,18 +195,16 @@ private class OptionalDelegatedProperty<TYPE>(private val delegate: Configuratio
override val typeName: String = "${delegate.typeName}?"
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue) = if (isSpecifiedBy(configuration)) delegate.describe(configuration, serialiseValue) else null
override fun valueIn(configuration: Config): TYPE? {
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options) = if (isSpecifiedBy(configuration)) delegate.describe(configuration, serialiseValue, options) else null
override fun valueIn(configuration: Config, options: Configuration.Options): TYPE? {
return when {
isSpecifiedBy(configuration) -> delegate.valueIn(configuration)
isSpecifiedBy(configuration) -> delegate.valueIn(configuration, options)
else -> null
}
}
override fun validate(target: Config, options: Configuration.Validation.Options): Valid<Config> {
override fun validate(target: Config, options: Configuration.Options): Valid<Config> {
val result = delegate.validate(target, options)
val errors = result.errors
val missingValueError = errors.asSequence().filterIsInstance<Configuration.Validation.Error.MissingValue>().filter { it.pathAsString == key }.singleOrNull()
@ -221,18 +227,17 @@ private abstract class RequiredDelegatedProperty<TYPE, DELEGATE : Configuration.
private class ListMappingProperty<TYPE, MAPPED>(private val delegate: Configuration.Property.Definition.RequiredList<TYPE>, private val mappedTypeName: String, private val convert: (List<TYPE>) -> Validated<MAPPED, Configuration.Validation.Error>) : Configuration.Property.Definition.Required<MAPPED> {
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue): ConfigValue? = delegate.describe(configuration, serialiseValue)
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options): ConfigValue? = delegate.describe(configuration, serialiseValue, options)
override fun valueIn(configuration: Config) = convert.invoke(delegate.valueIn(configuration)).value()
override fun valueIn(configuration: Config, options: Configuration.Options) = convert.invoke(delegate.valueIn(configuration, options)).value()
override fun optional(): Configuration.Property.Definition.Optional<MAPPED> = OptionalDelegatedProperty(this)
override fun validate(target: Config, options: Configuration.Validation.Options): Validated<Config, Configuration.Validation.Error> {
override fun validate(target: Config, options: Configuration.Options): Validated<Config, Configuration.Validation.Error> {
val errors = mutableSetOf<Configuration.Validation.Error>()
errors += delegate.validate(target, options).errors
if (errors.isEmpty()) {
errors += convert.invoke(delegate.valueIn(target)).mapErrors { error -> error.with(delegate.key, mappedTypeName) }.errors
errors += convert.invoke(delegate.valueIn(target, options)).mapErrors { error -> error.with(delegate.key, mappedTypeName) }.errors
}
return Validated.withResult(target, errors)
}
@ -248,7 +253,6 @@ private class ListMappingProperty<TYPE, MAPPED>(private val delegate: Configurat
}
fun ConfigException.toValidationError(keyName: String? = null, typeName: String): Configuration.Validation.Error {
val toError = when (this) {
is ConfigException.Missing -> Configuration.Validation.Error.MissingValue.Companion::of
is ConfigException.WrongType -> Configuration.Validation.Error.WrongType.Companion::of
@ -260,10 +264,9 @@ fun ConfigException.toValidationError(keyName: String? = null, typeName: String)
return toError.invoke(message!!, keyName, typeName, emptyList())
}
private fun Configuration.Property.Definition<*>.errorsWhenExtractingValue(target: Config): Set<Configuration.Validation.Error> {
private fun Configuration.Property.Definition<*>.errorsWhenExtractingValue(target: Config, options: Configuration.Options): Set<Configuration.Validation.Error> {
try {
valueIn(target)
valueIn(target, options)
return emptySet()
} catch (exception: ConfigException) {
if (isErrorExpected(exception)) {

View File

@ -16,7 +16,7 @@ internal class Schema(override val name: String?, unorderedProperties: Iterable<
}
}
override fun validate(target: Config, options: Configuration.Validation.Options): Valid<Config> {
override fun validate(target: Config, options: Configuration.Options): Valid<Config> {
val propertyErrors = properties.flatMap { property ->
property.validate(target, options).errors
@ -47,9 +47,9 @@ internal class Schema(override val name: String?, unorderedProperties: Iterable<
return description.toString()
}
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue): ConfigValue {
override fun describe(configuration: Config, serialiseValue: (Any?) -> ConfigValue, options: Configuration.Options): ConfigValue {
return properties.asSequence().map { it.key to it.describe(configuration, serialiseValue) }.filter { it.second != null }.fold(configObject()) { config, (key, value) -> config.withValue(key, value) }
return properties.asSequence().map { it.key to it.describe(configuration, serialiseValue, options) }.filter { it.second != null }.fold(configObject()) { config, (key, value) -> config.withValue(key, value) }
}
override fun equals(other: Any?): Boolean {

View File

@ -21,7 +21,11 @@ inline fun <TYPE, reified MAPPED> Configuration.Property.Definition.RequiredList
inline fun <TYPE, reified MAPPED> Configuration.Property.Definition.RequiredList<TYPE>.map(noinline convert: (List<TYPE>) -> MAPPED): Configuration.Property.Definition.Required<MAPPED> = map(MAPPED::class.java.simpleName, convert)
operator fun <TYPE> Config.get(property: Configuration.Property.Definition<TYPE>): TYPE = property.valueIn(this)
fun Config.withOptions(options: Configuration.Options) = ConfigurationWithOptions(this, options)
data class ConfigurationWithOptions(private val config: Config, private val options: Configuration.Options) {
operator fun <TYPE> get(property: Configuration.Value.Extractor<TYPE>): TYPE = property.valueIn(config, options)
}
inline fun <reified NESTED : Any> Configuration.Specification<*>.nested(specification: Configuration.Specification<NESTED>, key: String? = null, sensitive: Boolean = false): PropertyDelegate.Standard<NESTED> = nestedObject(schema = specification, key = key, sensitive = sensitive).map(ConfigObject::toConfig).mapValid { value -> specification.parse(value) }
@ -66,15 +70,6 @@ internal typealias Valid<TARGET> = Validated<TARGET, Configuration.Validation.Er
internal fun <TYPE> valid(target: TYPE) = Validated.valid<TYPE, Configuration.Validation.Error>(target)
/**
* Value extracted from a configuration file is a function of the actual value specified and configuration options.
* E.g. password value may be stored in the encrypted form rather than in a clear text.
*/
data class ConfigurationWithOptions(private val config: Config, private val options: Configuration.Validation.Options) {
operator fun <TYPE> get(property: Configuration.Property.Definition<TYPE>): TYPE = property.valueIn(config)
operator fun <TYPE> get(property: Configuration.Value.Extractor<TYPE>): TYPE = property.valueIn(config)
}
/**
* Helper interface to mark objects that will have [ConfigurationWithOptions] in them.
*/

View File

@ -6,21 +6,17 @@ import net.corda.common.configuration.parsing.internal.Valid
import net.corda.common.configuration.parsing.internal.valid
internal class VersionExtractor(versionPath: String, versionDefaultValue: Int) : Configuration.Version.Extractor {
private val containingPath = versionPath.split(".").let { if (it.size > 1) it.subList(0, it.size - 1) else null }
private val key = versionPath.split(".").last()
private val spec = Spec(key, versionDefaultValue, containingPath?.joinToString("."))
override fun parse(configuration: Config, options: Configuration.Validation.Options): Valid<Int> {
override fun parse(configuration: Config, options: Configuration.Options): Valid<Int> {
return spec.parse(configuration)
}
private class Spec(key: String, versionDefaultValue: Int, prefix: String?) : Configuration.Specification<Int>("Version", prefix) {
private val version by int(key = key).optional().withDefaultValue(versionDefaultValue)
override fun parseValid(configuration: Config) = valid(version.valueIn(configuration))
override fun parseValid(configuration: Config, options: Configuration.Options) = valid(version.valueIn(configuration, options))
}
}

View File

@ -21,8 +21,8 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isTrue()
assertThat(property.isSpecifiedBy(configuration)).isTrue()
assertThat(property.valueIn(configuration)).isEqualTo(value)
assertThat(configuration[property]).isEqualTo(value)
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(value)
assertThat(configuration.withOptions(Configuration.Options.defaults)[property]).isEqualTo(value)
}
@Test(timeout=300_000)
@ -38,7 +38,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isTrue()
assertThat(property.isSpecifiedBy(configuration)).isTrue()
assertThatThrownBy { property.valueIn(configuration) }.isInstanceOf(ConfigException.WrongType::class.java)
assertThatThrownBy { property.valueIn(configuration, Configuration.Options.defaults) }.isInstanceOf(ConfigException.WrongType::class.java)
}
@Test(timeout=300_000)
@ -54,7 +54,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isTrue()
assertThat(property.isSpecifiedBy(configuration)).isTrue()
assertThat(property.valueIn(configuration)).isEqualTo(value)
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(value)
}
@Test(timeout=300_000)
@ -70,7 +70,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isTrue()
assertThat(property.isSpecifiedBy(configuration)).isTrue()
assertThat(property.valueIn(configuration)).isEqualTo(value.max())
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(value.max())
}
@Test(timeout=300_000)
@ -85,7 +85,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isFalse()
assertThat(property.valueIn(configuration)).isEqualTo(null)
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(null)
}
@Test(timeout=300_000)
@ -101,7 +101,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isTrue()
assertThat(property.isSpecifiedBy(configuration)).isTrue()
assertThat(property.valueIn(configuration)).isEqualTo(value.max())
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(value.max())
}
@Test(timeout=300_000)
@ -116,7 +116,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isFalse()
assertThat(property.valueIn(configuration)).isEqualTo(null)
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(null)
}
@Test(timeout=300_000)
@ -132,7 +132,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isTrue()
assertThat(property.valueIn(configuration)).isEqualTo(value)
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(value)
}
@Test(timeout=300_000)
@ -147,7 +147,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isFalse()
assertThat(property.valueIn(configuration)).isNull()
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isNull()
}
@ -164,7 +164,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isFalse()
assertThat(property.valueIn(configuration)).isEqualTo(defaultValue)
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(defaultValue)
}
@Test(timeout=300_000)
@ -179,7 +179,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isTrue()
assertThat(property.isSpecifiedBy(configuration)).isFalse()
assertThatThrownBy { property.valueIn(configuration) }.isInstanceOf(ConfigException.Missing::class.java)
assertThatThrownBy { property.valueIn(configuration, Configuration.Options.defaults) }.isInstanceOf(ConfigException.Missing::class.java)
}
@Test(timeout=300_000)
@ -195,7 +195,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isTrue()
assertThat(property.valueIn(configuration)).isEqualTo(value)
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(value)
}
@Test(timeout=300_000)
@ -211,7 +211,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isTrue()
assertThatThrownBy { property.valueIn(configuration) }.isInstanceOf(ConfigException.WrongType::class.java)
assertThatThrownBy { property.valueIn(configuration, Configuration.Options.defaults) }.isInstanceOf(ConfigException.WrongType::class.java)
}
@Test(timeout=300_000)
@ -226,7 +226,7 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isFalse()
assertThat(property.valueIn(configuration)).isNull()
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isNull()
}
@Test(timeout=300_000)
@ -242,6 +242,6 @@ class PropertyTest {
assertThat(property.key).isEqualTo(key)
assertThat(property.isMandatory).isFalse()
assertThat(property.isSpecifiedBy(configuration)).isFalse()
assertThat(property.valueIn(configuration)).isEqualTo(defaultValue)
assertThat(property.valueIn(configuration, Configuration.Options.defaults)).isEqualTo(defaultValue)
}
}

View File

@ -15,7 +15,7 @@ class PropertyValidationTest {
val property = Configuration.Property.Definition.long(key)
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.MissingValue::class.java) { error ->
@ -34,7 +34,7 @@ class PropertyValidationTest {
val property = Configuration.Property.Definition.long(key)
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.MissingValue::class.java) { error ->
@ -53,7 +53,7 @@ class PropertyValidationTest {
val property = Configuration.Property.Definition.long(key).list()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.MissingValue::class.java) { error ->
@ -72,7 +72,7 @@ class PropertyValidationTest {
val property = Configuration.Property.Definition.long(key).list()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.MissingValue::class.java) { error ->
@ -94,7 +94,7 @@ class PropertyValidationTest {
val property = Configuration.Property.Definition.long(key).list().mapValid(::parseMax)
assertThat(property.validate(configuration).errors).isEmpty()
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).isEmpty()
}
@Test(timeout=300_000)
@ -114,7 +114,7 @@ class PropertyValidationTest {
val property = Configuration.Property.Definition.long(key).list().mapValid(::parseMax)
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.BadValue::class.java) { error ->
@ -134,7 +134,7 @@ class PropertyValidationTest {
val configuration = configObject(key to false).toConfig()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.WrongType::class.java) { error ->
@ -154,7 +154,7 @@ class PropertyValidationTest {
val configuration = configObject(key to 1.2).toConfig()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.WrongType::class.java) { error ->
@ -174,7 +174,7 @@ class PropertyValidationTest {
val configuration = configObject(key to 1).toConfig()
assertThat(property.validate(configuration).isValid).isTrue()
assertThat(property.validate(configuration, Configuration.Options.defaults).isValid).isTrue()
}
@Test(timeout=300_000)
@ -186,7 +186,7 @@ class PropertyValidationTest {
val configuration = configObject(key to listOf(false, true)).toConfig()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.WrongType::class.java) { error ->
@ -206,7 +206,7 @@ class PropertyValidationTest {
val configuration = configObject(key to listOf(1, 2, 3)).toConfig()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.WrongType::class.java) { error ->
@ -226,7 +226,7 @@ class PropertyValidationTest {
val configuration = configObject(key to 1).toConfig()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.WrongType::class.java) { error ->
@ -249,7 +249,7 @@ class PropertyValidationTest {
val configuration = configObject(key to configObject(nestedKey to false)).toConfig()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.WrongType::class.java) { error ->
@ -272,7 +272,7 @@ class PropertyValidationTest {
val configuration = configObject(key to configObject()).toConfig()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.MissingValue::class.java) { error ->
@ -295,7 +295,7 @@ class PropertyValidationTest {
val configuration = configObject(key to configObject(nestedKey to null)).toConfig()
assertThat(property.validate(configuration).errors).satisfies { errors ->
assertThat(property.validate(configuration, Configuration.Options.defaults).errors).satisfies { errors ->
assertThat(errors).hasSize(1)
assertThat(errors.first()).isInstanceOfSatisfying(Configuration.Validation.Error.MissingValue::class.java) { error ->
@ -317,7 +317,7 @@ class PropertyValidationTest {
val configuration = configObject(key to configObject(nestedKey to false)).toConfig()
assertThat(property.validate(configuration).isValid).isTrue()
assertThat(property.validate(configuration, Configuration.Options.defaults).isValid).isTrue()
}
@Test(timeout=300_000)
@ -333,7 +333,7 @@ class PropertyValidationTest {
val configuration = configObject(key to value).toConfig()
assertThat(property.validate(configuration).isValid).isTrue()
assertThat(property.validate(configuration, Configuration.Options.defaults).isValid).isTrue()
}
@Test(timeout=300_000)
@ -350,7 +350,7 @@ class PropertyValidationTest {
val configuration = configObject(key to value).toConfig()
val result = property.validate(configuration)
val result = property.validate(configuration, Configuration.Options.defaults)
assertThat(result.errors).satisfies { errors ->

View File

@ -29,7 +29,7 @@ class SchemaTest {
val fooConfigSchema = Configuration.Schema.withProperties(name = "Foo") { setOf(boolean("prop4"), double("prop5")) }
val barConfigSchema = Configuration.Schema.withProperties(name = "Bar") { setOf(string(prop1), long(prop2), nestedObject("prop3", fooConfigSchema)) }
val result = barConfigSchema.validate(configuration)
val result = barConfigSchema.validate(configuration, Configuration.Options.defaults)
println(barConfigSchema.description())
assertThat(result.isValid).isTrue()
@ -59,17 +59,17 @@ class SchemaTest {
val fooConfigSchema = Configuration.Schema.withProperties { setOf(boolean("prop4"), double("prop5")) }
val barConfigSchema = Configuration.Schema.withProperties { setOf(string(prop1), long(prop2), nestedObject("prop3", fooConfigSchema)) }
val strictErrors = barConfigSchema.validate(configuration, Configuration.Validation.Options(strict = true)).errors
val strictErrors = barConfigSchema.validate(configuration, Configuration.Options(strict = true)).errors
assertThat(strictErrors).hasSize(2)
assertThat(strictErrors.filter { error -> error.keyName == "prop4" }).hasSize(1)
assertThat(strictErrors.filter { error -> error.keyName == "prop6" }).hasSize(1)
val errors = barConfigSchema.validate(configuration, Configuration.Validation.Options(strict = false)).errors
val errors = barConfigSchema.validate(configuration, Configuration.Options(strict = false)).errors
assertThat(errors).isEmpty()
val errorsWithDefaultOptions = barConfigSchema.validate(configuration).errors
val errorsWithDefaultOptions = barConfigSchema.validate(configuration, Configuration.Options.defaults).errors
assertThat(errorsWithDefaultOptions).isEmpty()
}
@ -98,7 +98,7 @@ class SchemaTest {
val fooConfigSchema = Configuration.Schema.withProperties { setOf(boolean("prop4"), double("prop5")) }
val barConfigSchema = Configuration.Schema.withProperties { setOf(string(prop1), long(prop2), nestedObject("prop3", fooConfigSchema)) }
val result = barConfigSchema.validate(configuration)
val result = barConfigSchema.validate(configuration, Configuration.Options.defaults)
assertThat(result.isValid).isTrue()
}
@ -127,7 +127,7 @@ class SchemaTest {
val fooConfigSchema = Configuration.Schema.withProperties { setOf(boolean("prop4"), double("prop5")) }
val barConfigSchema = Configuration.Schema.withProperties { setOf(string(prop1), long(prop2), nestedObject("prop3", fooConfigSchema)) }
val errors = barConfigSchema.validate(configuration).errors
val errors = barConfigSchema.validate(configuration, Configuration.Options.defaults).errors
errors.forEach(::println)
assertThat(errors).hasSize(2)
@ -154,7 +154,7 @@ class SchemaTest {
val fooConfigSchema = Configuration.Schema.withProperties(name = "Foo") { setOf(boolean("prop4"), string("prop5", sensitive = true)) }
val barConfigSchema = Configuration.Schema.withProperties(name = "Bar") { setOf(string(prop1), long(prop2), nestedObject("prop3", fooConfigSchema)) }
val printedConfiguration = barConfigSchema.describe(configuration)
val printedConfiguration = barConfigSchema.describe(configuration, options = Configuration.Options.defaults)
val description = printedConfiguration.serialize().also { println(it) }
@ -185,7 +185,7 @@ class SchemaTest {
val fooConfigSchema = Configuration.Schema.withProperties(name = "Foo") { setOf(boolean("prop4"), string("prop5", sensitive = true)) }
val barConfigSchema = Configuration.Schema.withProperties(name = "Bar") { setOf(string(prop1), long(prop2), nestedObject("prop3", fooConfigSchema).list()) }
val printedConfiguration = barConfigSchema.describe(configuration)
val printedConfiguration = barConfigSchema.describe(configuration, options = Configuration.Options.defaults)
val description = printedConfiguration.serialize().also { println(it) }

View File

@ -16,7 +16,7 @@ class SpecificationTest {
val principal by string().mapValid(::parseAddress)
val admin by string().mapValid(::parseAddress)
override fun parseValid(configuration: Config) = valid(Addresses(configuration[principal], configuration[admin]))
override fun parseValid(configuration: Config, options: Configuration.Options) = configuration.withOptions(options).let { valid(Addresses(it[principal], it[admin])) }
private fun parseAddress(rawValue: String): Valid<Address> {
@ -27,7 +27,7 @@ class SpecificationTest {
val useSsl by boolean()
val addresses by nested(AddressesSpec)
override fun parseValid(configuration: Config) = valid<RpcSettings>(RpcSettingsImpl(configuration[addresses], configuration[useSsl]))
override fun parseValid(configuration: Config, options: Configuration.Options) = configuration.withOptions(options).let { valid<RpcSettings>(RpcSettingsImpl(it[addresses], it[useSsl])) }
}
@Test(timeout=300_000)
@ -60,9 +60,9 @@ class SpecificationTest {
private val maxElement by long("elements").list().map { elements -> elements.max() }
override fun parseValid(configuration: Config): Valid<AtomicLong> {
return valid(AtomicLong(configuration[maxElement]!!))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<AtomicLong> {
val config = configuration.withOptions(options)
return valid(AtomicLong(config[maxElement]!!))
}
}
@ -111,9 +111,9 @@ class SpecificationTest {
private val maxElement by long("elements").list().mapValid(::parseMax)
override fun parseValid(configuration: Config): Valid<AtomicLong> {
return valid(AtomicLong(configuration[maxElement]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<AtomicLong> {
val config = configuration.withOptions(options)
return valid(AtomicLong(config[maxElement]))
}
}
@ -159,7 +159,7 @@ class SpecificationTest {
@Suppress("unused")
val myProp by string().list().optional()
override fun parseValid(configuration: Config) = valid(configuration[myProp])
override fun parseValid(configuration: Config, options: Configuration.Options) = configuration.withOptions(options).let { valid(it[myProp]) }
}
assertThat(spec.properties).hasSize(1)

View File

@ -15,5 +15,5 @@ internal fun <VALUE> extractValueWithErrors(errors: Set<Configuration.Validation
internal fun <VALUE> extractValue(value: Valid<VALUE>) = object : Configuration.Value.Parser<VALUE> {
override fun parse(configuration: Config, options: Configuration.Validation.Options): Valid<VALUE> = value
override fun parse(configuration: Config, options: Configuration.Options): Valid<VALUE> = value
}

View File

@ -2,9 +2,9 @@ package net.corda.nodeapi.internal.network
import com.typesafe.config.Config
import net.corda.common.configuration.parsing.internal.Configuration
import net.corda.common.configuration.parsing.internal.get
import net.corda.common.configuration.parsing.internal.mapValid
import net.corda.common.configuration.parsing.internal.nested
import net.corda.common.configuration.parsing.internal.withOptions
import net.corda.common.validation.internal.Validated
import net.corda.core.internal.noPackageOverlap
import net.corda.core.internal.requirePackageValid
@ -17,7 +17,7 @@ import java.security.KeyStoreException
typealias Valid<TARGET> = Validated<TARGET, Configuration.Validation.Error>
fun Config.parseAsNetworkParametersConfiguration(options: Configuration.Validation.Options = Configuration.Validation.Options(strict = false)):
fun Config.parseAsNetworkParametersConfiguration(options: Configuration.Options = Configuration.Options.defaults):
Valid<NetworkParametersOverrides> = NetworkParameterOverridesSpec.parse(this, options)
internal fun <T> badValue(msg: String): Valid<T> = Validated.invalid(sequenceOf(Configuration.Validation.Error.BadValue.of(msg)).toSet())
@ -36,11 +36,12 @@ internal object NetworkParameterOverridesSpec : Configuration.Specification<Netw
private val keystorePassword by string()
private val keystoreAlias by string()
override fun parseValid(configuration: Config): Validated<PackageOwner, Configuration.Validation.Error> {
val suppliedKeystorePath = configuration[keystore]
val keystorePassword = configuration[keystorePassword]
override fun parseValid(configuration: Config, options: Configuration.Options): Validated<PackageOwner, Configuration.Validation.Error> {
val config = configuration.withOptions(options)
val suppliedKeystorePath = config[keystore]
val keystorePassword = config[keystorePassword]
return try {
val javaPackageName = configuration[packageName]
val javaPackageName = config[packageName]
val absoluteKeystorePath = if (suppliedKeystorePath.isAbsolute) {
suppliedKeystorePath
} else {
@ -49,10 +50,10 @@ internal object NetworkParameterOverridesSpec : Configuration.Specification<Netw
}.toAbsolutePath()
val ks = loadKeyStore(absoluteKeystorePath, keystorePassword)
return try {
val publicKey = ks.getCertificate(configuration[keystoreAlias]).publicKey
val publicKey = ks.getCertificate(config[keystoreAlias]).publicKey
valid(PackageOwner(javaPackageName, publicKey))
} catch (kse: KeyStoreException) {
badValue("Keystore has not been initialized for alias ${configuration[keystoreAlias]}.")
badValue("Keystore has not been initialized for alias ${config[keystoreAlias]}")
}
} catch (kse: KeyStoreException) {
badValue("Password is incorrect or the key store is damaged for keyStoreFilePath: $suppliedKeystorePath.")
@ -79,8 +80,9 @@ internal object NetworkParameterOverridesSpec : Configuration.Specification<Netw
}
}
override fun parseValid(configuration: Config): Valid<NetworkParametersOverrides> {
val packageOwnership = configuration[packageOwnership]
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<NetworkParametersOverrides> {
val config = configuration.withOptions(options)
val packageOwnership = config[packageOwnership]
if (packageOwnership != null && !noPackageOverlap(packageOwnership.map { it.javaPackageName })) {
return Validated.invalid(sequenceOf(Configuration.Validation.Error.BadValue.of(
"Package namespaces must not overlap",
@ -89,11 +91,11 @@ internal object NetworkParameterOverridesSpec : Configuration.Specification<Netw
)).toSet())
}
return valid(NetworkParametersOverrides(
minimumPlatformVersion = configuration[minimumPlatformVersion],
maxMessageSize = configuration[maxMessageSize],
maxTransactionSize = configuration[maxTransactionSize],
minimumPlatformVersion = config[minimumPlatformVersion],
maxMessageSize = config[maxMessageSize],
maxTransactionSize = config[maxTransactionSize],
packageOwnership = packageOwnership,
eventHorizon = configuration[eventHorizon]
eventHorizon = config[eventHorizon]
))
}

View File

@ -49,7 +49,7 @@ open class SharedNodeCmdLineOptions {
var devMode: Boolean? = null
open fun parseConfiguration(configuration: Config): Valid<NodeConfiguration> {
val option = Configuration.Validation.Options(strict = unknownConfigKeysPolicy == UnknownConfigKeysPolicy.FAIL)
val option = Configuration.Options(strict = unknownConfigKeysPolicy == UnknownConfigKeysPolicy.FAIL)
return configuration.parseAsNodeConfiguration(option)
}

View File

@ -26,7 +26,7 @@ internal class ValidateConfigurationCli : CliWrapperBase("validate-configuration
return "for path: \"$pathAsString\": $message"
}
internal fun logRawConfig(config: Config) = logger.info("Actual configuration:\n${V1NodeConfigurationSpec.describe(config, Any?::toConfigValue).render(configRenderingOptions)}")
internal fun logRawConfig(config: Config) = logger.info("Actual configuration:\n${V1NodeConfigurationSpec.describe(config, Any?::toConfigValue, Configuration.Options()).render(configRenderingOptions)}")
}
@Mixin

View File

@ -107,7 +107,7 @@ object ConfigHelper {
newKey.let { key ->
val cfg = ConfigFactory.parseMap(mapOf(key to it.value))
val result = V1NodeConfigurationSpec.validate(cfg, Configuration.Validation.Options(strict = true))
val result = V1NodeConfigurationSpec.validate(cfg, Configuration.Options(strict = true))
val isInvalidProperty = result.errors.any { err -> err is Configuration.Validation.Error.Unknown }
if (isInvalidProperty) {

View File

@ -217,7 +217,7 @@ data class FlowTimeoutConfiguration(
internal typealias Valid<TARGET> = Validated<TARGET, Configuration.Validation.Error>
fun Config.parseAsNodeConfiguration(options: Configuration.Validation.Options = Configuration.Validation.Options(strict = true)): Valid<NodeConfiguration> = V1NodeConfigurationSpec.parse(this, options)
fun Config.parseAsNodeConfiguration(options: Configuration.Options = Configuration.Options(strict = true)): Valid<NodeConfiguration> = V1NodeConfigurationSpec.parse(this, options)
data class NodeH2Settings(
val address: NetworkHostAndPort?

View File

@ -5,11 +5,11 @@ package net.corda.node.services.config.schema.v1
import com.typesafe.config.Config
import com.typesafe.config.ConfigObject
import net.corda.common.configuration.parsing.internal.Configuration
import net.corda.common.configuration.parsing.internal.get
import net.corda.common.configuration.parsing.internal.listOrEmpty
import net.corda.common.configuration.parsing.internal.map
import net.corda.common.configuration.parsing.internal.mapValid
import net.corda.common.configuration.parsing.internal.nested
import net.corda.common.configuration.parsing.internal.withOptions
import net.corda.common.validation.internal.Validated.Companion.invalid
import net.corda.common.validation.internal.Validated.Companion.valid
import net.corda.core.context.AuthServiceId
@ -55,11 +55,12 @@ internal object UserSpec : Configuration.Specification<User>("User") {
private val password by string(sensitive = true)
private val permissions by string().listOrEmpty()
override fun parseValid(configuration: Config): Valid<User> {
val username = configuration[username] ?: configuration[user]
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<User> {
val config = configuration.withOptions(options)
val username = config[username] ?: config[user]
return when (username) {
null -> invalid(Configuration.Validation.Error.MissingValue.forKey("username"))
else -> valid(User(username, configuration[password], configuration[permissions].toSet()))
else -> valid(User(username, config[password], config[permissions].toSet()))
}
}
}
@ -72,11 +73,12 @@ internal object SecurityConfigurationSpec : Configuration.Specification<Security
private val connection by nestedObject(sensitive = true).map(::toProperties).optional()
private val users by nested(UserSpec).list().optional()
override fun parseValid(configuration: Config): Valid<SecurityConfiguration.AuthService.DataSource> {
val type = configuration[type]
val passwordEncryption = configuration[passwordEncryption]
val connection = configuration[connection]
val users = configuration[users]
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<SecurityConfiguration.AuthService.DataSource> {
val config = configuration.withOptions(options)
val type = config[type]
val passwordEncryption = config[passwordEncryption]
val connection = config[connection]
val users = config[users]
return when {
type == AuthDataSourceType.INMEMORY && (users == null || connection != null) -> badValue("\"INMEMORY\" data source type requires \"users\" and cannot specify \"connection\"")
@ -91,15 +93,17 @@ internal object SecurityConfigurationSpec : Configuration.Specification<Security
private val expireAfterSecs by long().mapValid { value -> if (value >= 0) validValue(value) else badValue("cannot be less than 0'") }
private val maxEntries by long().mapValid { value -> if (value >= 0) validValue(value) else badValue("cannot be less than 0'") }
override fun parseValid(configuration: Config): Valid<SecurityConfiguration.AuthService.Options.Cache> {
return valid(SecurityConfiguration.AuthService.Options.Cache(configuration[expireAfterSecs], configuration[maxEntries]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<SecurityConfiguration.AuthService.Options.Cache> {
val config = configuration.withOptions(options)
return valid(SecurityConfiguration.AuthService.Options.Cache(config[expireAfterSecs], config[maxEntries]))
}
}
private val cache by nested(CacheSpec).optional()
override fun parseValid(configuration: Config): Valid<SecurityConfiguration.AuthService.Options> {
return valid(SecurityConfiguration.AuthService.Options(configuration[cache]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<SecurityConfiguration.AuthService.Options> {
val config = configuration.withOptions(options)
return valid(SecurityConfiguration.AuthService.Options(config[cache]))
}
}
@ -107,21 +111,23 @@ internal object SecurityConfigurationSpec : Configuration.Specification<Security
private val id by string().map(::AuthServiceId).optional()
val options by nested(OptionsSpec).optional()
override fun parseValid(configuration: Config): Valid<SecurityConfiguration.AuthService> {
val dataSource = configuration[dataSource]
val id = configuration[id] ?: defaultAuthServiceId(dataSource.type)
val options = configuration[options]
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<SecurityConfiguration.AuthService> {
val config = configuration.withOptions(options)
val dataSource = config[dataSource]
val id = config[id] ?: defaultAuthServiceId(dataSource.type)
val authServiceOptions = config[this.options]
return when {
dataSource.type == AuthDataSourceType.INMEMORY && options?.cache != null -> badValue("no cache supported for \"INMEMORY\" data provider")
else -> valid(SecurityConfiguration.AuthService(dataSource, id, options))
dataSource.type == AuthDataSourceType.INMEMORY && authServiceOptions?.cache != null -> badValue("no cache supported for \"INMEMORY\" data provider")
else -> valid(SecurityConfiguration.AuthService(dataSource, id, authServiceOptions))
}
}
}
private val authService by nested(AuthServiceSpec)
override fun parseValid(configuration: Config): Valid<SecurityConfiguration> {
return valid(SecurityConfiguration(configuration[authService]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<SecurityConfiguration> {
val config = configuration.withOptions(options)
return valid(SecurityConfiguration(config[authService]))
}
}
@ -134,13 +140,15 @@ internal object DevModeOptionsSpec : Configuration.Specification<DevModeOptions>
private val bootstrapSource by string().optional()
private val cordaSource by string().list()
override fun parseValid(configuration: Config): Valid<DJVMOptions> {
return valid(DJVMOptions(configuration[bootstrapSource], configuration[cordaSource]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<DJVMOptions> {
val config = configuration.withOptions(options)
return valid(DJVMOptions(config[bootstrapSource], config[cordaSource]))
}
}
override fun parseValid(configuration: Config): Valid<DevModeOptions> {
return valid(DevModeOptions(configuration[disableCheckpointChecker], configuration[allowCompatibilityZone], configuration[djvm]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<DevModeOptions> {
val config = configuration.withOptions(options)
return valid(DevModeOptions(config[disableCheckpointChecker], config[allowCompatibilityZone], config[djvm]))
}
}
@ -151,8 +159,9 @@ internal object NetworkServicesConfigSpec : Configuration.Specification<NetworkS
private val inferred by boolean().optional().withDefaultValue(false)
private val csrToken by string(sensitive = true).optional()
override fun parseValid(configuration: Config): Valid<NetworkServicesConfig> {
return valid(NetworkServicesConfig(configuration[doormanURL], configuration[networkMapURL], configuration[pnm], configuration[inferred], configuration[csrToken]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<NetworkServicesConfig> {
val config = configuration.withOptions(options)
return valid(NetworkServicesConfig(config[doormanURL], config[networkMapURL], config[pnm], config[inferred], config[csrToken]))
}
}
@ -160,22 +169,24 @@ internal object NetworkParameterAcceptanceSettingsSpec :
Configuration.Specification<NetworkParameterAcceptanceSettings>("NetworkParameterAcceptanceSettings") {
private val autoAcceptEnabled by boolean().optional().withDefaultValue(true)
private val excludedAutoAcceptableParameters by string().listOrEmpty()
override fun parseValid(configuration: Config): Valid<NetworkParameterAcceptanceSettings> {
return valid(NetworkParameterAcceptanceSettings(configuration[autoAcceptEnabled],
configuration[excludedAutoAcceptableParameters].toSet())
override fun parseValid(configuration: Config, options: Configuration.Options):
Valid<NetworkParameterAcceptanceSettings> {
val config = configuration.withOptions(options)
return valid(NetworkParameterAcceptanceSettings(config[autoAcceptEnabled],
config[excludedAutoAcceptableParameters].toSet())
)
}
}
@Suppress("DEPRECATION")
internal object CertChainPolicyConfigSpec : Configuration.Specification<CertChainPolicyConfig>("CertChainPolicyConfig") {
private val role by string()
private val policy by enum(CertChainPolicyType::class)
private val trustedAliases by string().listOrEmpty()
override fun parseValid(configuration: Config): Valid<CertChainPolicyConfig> {
return valid(CertChainPolicyConfig(configuration[role], configuration[policy], configuration[trustedAliases].toSet()))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<CertChainPolicyConfig> {
val config = configuration.withOptions(options)
return valid(CertChainPolicyConfig(config[role], config[policy], config[trustedAliases].toSet()))
}
}
@ -184,8 +195,9 @@ internal object FlowTimeoutConfigurationSpec : Configuration.Specification<FlowT
private val maxRestartCount by int()
private val backoffBase by double()
override fun parseValid(configuration: Config): Valid<FlowTimeoutConfiguration> {
return valid(FlowTimeoutConfiguration(configuration[timeout], configuration[maxRestartCount], configuration[backoffBase]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<FlowTimeoutConfiguration> {
val config = configuration.withOptions(options)
return valid(FlowTimeoutConfiguration(config[timeout], config[maxRestartCount], config[backoffBase]))
}
}
@ -198,8 +210,9 @@ internal object NotaryConfigSpec : Configuration.Specification<NotaryConfig>("No
private val raft by nested(RaftConfigSpec).optional()
private val bftSMaRt by nested(BFTSmartConfigSpec).optional()
override fun parseValid(configuration: Config): Valid<NotaryConfig> {
return valid(NotaryConfig(configuration[validating], configuration[serviceLegalName], configuration[className], configuration[etaMessageThresholdSeconds], configuration[extraConfig], configuration[raft], configuration[bftSMaRt]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<NotaryConfig> {
val config = configuration.withOptions(options)
return valid(NotaryConfig(config[validating], config[serviceLegalName], config[className], config[etaMessageThresholdSeconds], config[extraConfig], config[raft], config[bftSMaRt]))
}
}
@ -207,8 +220,9 @@ internal object RaftConfigSpec : Configuration.Specification<RaftConfig>("RaftCo
private val nodeAddress by string().mapValid(::toNetworkHostAndPort)
private val clusterAddresses by string().mapValid(::toNetworkHostAndPort).listOrEmpty()
override fun parseValid(configuration: Config): Valid<RaftConfig> {
return valid(RaftConfig(configuration[nodeAddress], configuration[clusterAddresses]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<RaftConfig> {
val config = configuration.withOptions(options)
return valid(RaftConfig(config[nodeAddress], config[clusterAddresses]))
}
}
@ -218,19 +232,20 @@ internal object BFTSmartConfigSpec : Configuration.Specification<BFTSmartConfig>
private val debug by boolean().optional().withDefaultValue(false)
private val exposeRaces by boolean().optional().withDefaultValue(false)
override fun parseValid(configuration: Config): Valid<BFTSmartConfig> {
return valid(BFTSmartConfig(configuration[replicaId], configuration[clusterAddresses], configuration[debug], configuration[exposeRaces]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<BFTSmartConfig> {
val config = configuration.withOptions(options)
return valid(BFTSmartConfig(config[replicaId], config[clusterAddresses], config[debug], config[exposeRaces]))
}
}
internal object NodeRpcSettingsSpec : Configuration.Specification<NodeRpcSettings>("NodeRpcSettings") {
internal object BrokerRpcSslOptionsSpec : Configuration.Specification<BrokerRpcSslOptions>("BrokerRpcSslOptions") {
private val keyStorePath by string().mapValid(::toPath)
private val keyStorePassword by string(sensitive = true)
override fun parseValid(configuration: Config): Valid<BrokerRpcSslOptions> {
return valid(BrokerRpcSslOptions(configuration[keyStorePath], configuration[keyStorePassword]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<BrokerRpcSslOptions> {
val config = configuration.withOptions(options)
return valid(BrokerRpcSslOptions(config[keyStorePath], config[keyStorePassword]))
}
}
@ -240,18 +255,18 @@ internal object NodeRpcSettingsSpec : Configuration.Specification<NodeRpcSetting
private val useSsl by boolean().optional().withDefaultValue(NodeRpcSettings.Defaults.useSsl)
private val ssl by nested(BrokerRpcSslOptionsSpec).optional()
override fun parseValid(configuration: Config): Valid<NodeRpcSettings> {
return valid(NodeRpcSettings(configuration[address], configuration[adminAddress], configuration[standAloneBroker], configuration[useSsl], configuration[ssl]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<NodeRpcSettings> {
val config = configuration.withOptions(options)
return valid(NodeRpcSettings(config[address], config[adminAddress], config[standAloneBroker], config[useSsl], config[ssl]))
}
}
internal object SSHDConfigurationSpec : Configuration.Specification<SSHDConfiguration>("SSHDConfiguration") {
private val port by int()
override fun parseValid(configuration: Config): Valid<SSHDConfiguration> = attempt<SSHDConfiguration, IllegalArgumentException> { SSHDConfiguration(configuration[port]) }
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<SSHDConfiguration> = attempt<SSHDConfiguration, IllegalArgumentException> { SSHDConfiguration(configuration.withOptions(options)[port]) }
}
internal object DatabaseConfigSpec : Configuration.Specification<DatabaseConfig>("DatabaseConfig") {
private val initialiseSchema by boolean().optional().withDefaultValue(DatabaseConfig.Defaults.initialiseSchema)
private val initialiseAppSchema by enum(SchemaInitializationType::class).optional().withDefaultValue(DatabaseConfig.Defaults.initialiseAppSchema)
@ -259,16 +274,18 @@ internal object DatabaseConfigSpec : Configuration.Specification<DatabaseConfig>
private val exportHibernateJMXStatistics by boolean().optional().withDefaultValue(DatabaseConfig.Defaults.exportHibernateJMXStatistics)
private val mappedSchemaCacheSize by long().optional().withDefaultValue(DatabaseConfig.Defaults.mappedSchemaCacheSize)
override fun parseValid(configuration: Config): Valid<DatabaseConfig> {
return valid(DatabaseConfig(configuration[initialiseSchema], configuration[initialiseAppSchema], configuration[transactionIsolationLevel], configuration[exportHibernateJMXStatistics], configuration[mappedSchemaCacheSize]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<DatabaseConfig> {
val config = configuration.withOptions(options)
return valid(DatabaseConfig(config[initialiseSchema], config[initialiseAppSchema], config[transactionIsolationLevel], config[exportHibernateJMXStatistics], config[mappedSchemaCacheSize]))
}
}
internal object NodeH2SettingsSpec : Configuration.Specification<NodeH2Settings>("NodeH2Settings") {
private val address by string().mapValid(::toNetworkHostAndPort).optional()
override fun parseValid(configuration: Config): Valid<NodeH2Settings> {
return valid(NodeH2Settings(configuration[address]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<NodeH2Settings> {
val config = configuration.withOptions(options)
return valid(NodeH2Settings(config[address]))
}
}
@ -277,14 +294,16 @@ internal object FlowOverridesConfigSpec : Configuration.Specification<FlowOverri
private val initiator by string()
private val responder by string()
override fun parseValid(configuration: Config): Valid<FlowOverride> {
return valid(FlowOverride(configuration[initiator], configuration[responder]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<FlowOverride> {
val config = configuration.withOptions(options)
return valid(FlowOverride(config[initiator], config[responder]))
}
}
private val overrides by nested(FlowOverridesConfigSpec.SingleSpec).listOrEmpty()
override fun parseValid(configuration: Config): Valid<FlowOverrideConfig> {
return valid(FlowOverrideConfig(configuration[overrides]))
override fun parseValid(configuration: Config, options: Configuration.Options): Valid<FlowOverrideConfig> {
val config = configuration.withOptions(options)
return valid(FlowOverrideConfig(config[overrides]))
}
}

View File

@ -70,67 +70,68 @@ internal object V1NodeConfigurationSpec : Configuration.Specification<NodeConfig
@Suppress("unused")
private val systemProperties by nestedObject().optional()
override fun parseValid(configuration: Config): Validated<NodeConfiguration, Configuration.Validation.Error> {
override fun parseValid(configuration: Config, options: Configuration.Options): Validated<NodeConfiguration, Configuration.Validation.Error> {
val config = configuration.withOptions(options)
val messagingServerExternal = configuration[messagingServerExternal] ?: Defaults.messagingServerExternal(configuration[messagingServerAddress])
val database = configuration[database] ?: Defaults.database(configuration[devMode])
val baseDirectoryPath = configuration[baseDirectory]
val cordappDirectories = configuration[cordappDirectories] ?: Defaults.cordappsDirectories(baseDirectoryPath)
val messagingServerExternal = config[messagingServerExternal] ?: Defaults.messagingServerExternal(config[messagingServerAddress])
val database = config[database] ?: Defaults.database(config[devMode])
val baseDirectoryPath = config[baseDirectory]
val cordappDirectories = config[cordappDirectories] ?: Defaults.cordappsDirectories(baseDirectoryPath)
val result = try {
valid<NodeConfigurationImpl, Configuration.Validation.Error>(NodeConfigurationImpl(
baseDirectory = baseDirectoryPath,
myLegalName = configuration[myLegalName],
emailAddress = configuration[emailAddress],
p2pAddress = configuration[p2pAddress],
keyStorePassword = configuration[keyStorePassword],
trustStorePassword = configuration[trustStorePassword],
crlCheckSoftFail = configuration[crlCheckSoftFail],
dataSourceProperties = configuration[dataSourceProperties],
rpcUsers = configuration[rpcUsers],
verifierType = configuration[verifierType],
flowTimeout = configuration[flowTimeout],
rpcSettings = configuration[rpcSettings],
messagingServerAddress = configuration[messagingServerAddress],
notary = configuration[notary],
flowOverrides = configuration[flowOverrides],
additionalP2PAddresses = configuration[additionalP2PAddresses],
additionalNodeInfoPollingFrequencyMsec = configuration[additionalNodeInfoPollingFrequencyMsec],
jmxMonitoringHttpPort = configuration[jmxMonitoringHttpPort],
security = configuration[security],
devMode = configuration[devMode],
devModeOptions = configuration[devModeOptions],
compatibilityZoneURL = configuration[compatibilityZoneURL],
networkServices = configuration[networkServices],
certificateChainCheckPolicies = configuration[certificateChainCheckPolicies],
myLegalName = config[myLegalName],
emailAddress = config[emailAddress],
p2pAddress = config[p2pAddress],
keyStorePassword = config[keyStorePassword],
trustStorePassword = config[trustStorePassword],
crlCheckSoftFail = config[crlCheckSoftFail],
dataSourceProperties = config[dataSourceProperties],
rpcUsers = config[rpcUsers],
verifierType = config[verifierType],
flowTimeout = config[flowTimeout],
rpcSettings = config[rpcSettings],
messagingServerAddress = config[messagingServerAddress],
notary = config[notary],
flowOverrides = config[flowOverrides],
additionalP2PAddresses = config[additionalP2PAddresses],
additionalNodeInfoPollingFrequencyMsec = config[additionalNodeInfoPollingFrequencyMsec],
jmxMonitoringHttpPort = config[jmxMonitoringHttpPort],
security = config[security],
devMode = config[devMode],
devModeOptions = config[devModeOptions],
compatibilityZoneURL = config[compatibilityZoneURL],
networkServices = config[networkServices],
certificateChainCheckPolicies = config[certificateChainCheckPolicies],
messagingServerExternal = messagingServerExternal,
useTestClock = configuration[useTestClock],
lazyBridgeStart = configuration[lazyBridgeStart],
detectPublicIp = configuration[detectPublicIp],
sshd = configuration[sshd],
localShellAllowExitInSafeMode = configuration[localShellAllowExitInSafeMode],
localShellUnsafe = configuration[localShellUnsafe],
useTestClock = config[useTestClock],
lazyBridgeStart = config[lazyBridgeStart],
detectPublicIp = config[detectPublicIp],
sshd = config[sshd],
localShellAllowExitInSafeMode = config[localShellAllowExitInSafeMode],
localShellUnsafe = config[localShellUnsafe],
database = database,
noLocalShell = configuration[noLocalShell],
attachmentCacheBound = configuration[attachmentCacheBound],
extraNetworkMapKeys = configuration[extraNetworkMapKeys],
tlsCertCrlDistPoint = configuration[tlsCertCrlDistPoint],
tlsCertCrlIssuer = configuration[tlsCertCrlIssuer],
h2Settings = configuration[h2Settings],
flowMonitorPeriodMillis = configuration[flowMonitorPeriodMillis],
flowMonitorSuspensionLoggingThresholdMillis = configuration[flowMonitorSuspensionLoggingThresholdMillis],
jmxReporterType = configuration[jmxReporterType],
rpcAddress = configuration[rpcAddress],
transactionCacheSizeMegaBytes = configuration[transactionCacheSizeMegaBytes],
attachmentContentCacheSizeMegaBytes = configuration[attachmentContentCacheSizeMegaBytes],
h2port = configuration[h2port],
jarDirs = configuration[jarDirs],
noLocalShell = config[noLocalShell],
attachmentCacheBound = config[attachmentCacheBound],
extraNetworkMapKeys = config[extraNetworkMapKeys],
tlsCertCrlDistPoint = config[tlsCertCrlDistPoint],
tlsCertCrlIssuer = config[tlsCertCrlIssuer],
h2Settings = config[h2Settings],
flowMonitorPeriodMillis = config[flowMonitorPeriodMillis],
flowMonitorSuspensionLoggingThresholdMillis = config[flowMonitorSuspensionLoggingThresholdMillis],
jmxReporterType = config[jmxReporterType],
rpcAddress = config[rpcAddress],
transactionCacheSizeMegaBytes = config[transactionCacheSizeMegaBytes],
attachmentContentCacheSizeMegaBytes = config[attachmentContentCacheSizeMegaBytes],
h2port = config[h2port],
jarDirs = config[jarDirs],
cordappDirectories = cordappDirectories.map { baseDirectoryPath.resolve(it) },
cordappSignerKeyFingerprintBlacklist = configuration[cordappSignerKeyFingerprintBlacklist],
blacklistedAttachmentSigningKeys = configuration[blacklistedAttachmentSigningKeys],
networkParameterAcceptanceSettings = configuration[networkParameterAcceptanceSettings],
configurationWithOptions = ConfigurationWithOptions(configuration, Configuration.Validation.Options.defaults),
flowExternalOperationThreadPoolSize = configuration[flowExternalOperationThreadPoolSize],
quasarExcludePackages = configuration[quasarExcludePackages]
cordappSignerKeyFingerprintBlacklist = config[cordappSignerKeyFingerprintBlacklist],
blacklistedAttachmentSigningKeys = config[blacklistedAttachmentSigningKeys],
networkParameterAcceptanceSettings = config[networkParameterAcceptanceSettings],
configurationWithOptions = ConfigurationWithOptions(configuration, Configuration.Options.defaults),
flowExternalOperationThreadPoolSize = config[flowExternalOperationThreadPoolSize],
quasarExcludePackages = config[quasarExcludePackages]
))
} catch (e: Exception) {
return when (e) {