Skip to content

Commit

Permalink
New property definition syntax (#15)
Browse files Browse the repository at this point in the history
* wip: new syntax done/working. need to clean up

* get rid of need for ConfigPropertyState, further flesh out prop
building syntax to use suppliers directly

* cleanup

* update readme

* remove leftover old syntax in docs
  • Loading branch information
bbaldino authored Jul 27, 2020
1 parent 7e11213 commit b7f6d97
Show file tree
Hide file tree
Showing 17 changed files with 186 additions and 259 deletions.
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![Java CI with Maven](https://github.com/jitsi/jitsi-metaconfig/workflows/Java%20CI%20with%20Maven/badge.svg)
![Java CI with Maven](https://github.com/jitsi/jitsi-metaconfig/workflows/Java%20CI%20with%20Maven/badge.svg)
![Code Coverage](https://codecov.io/gh/jitsi/jitsi-metaconfig/branch/master/graph/badge.svg)

# jitsi-metaconfig
Expand All @@ -15,38 +15,44 @@ supports marking old properties as deprecated to ease the transition to removing
### Example config properties:
```kotlin
class Foo {
// Simple property
// A simple property with just a key and a source
val enabled: Boolean by config("app.enabled".from(myConfigSource))

// Optional property
val optionalParam: String? by optionalconfig("app.client.optional-param".from(myConfigSource))

// Convert the type (retrieve as a Long, convert to a Duration)
val interval: Duration by config {
retrieve("app.interval-ms".from(myConfigSource).asType<Long>().andConvertBy(Duration::ofMillis))
"app.interval-ms".from(myConfigSource).convertFrom<Long>(Duration::ofMillis)
}

// Transform the value (invert the retrieved boolean value)
val enabled: Boolean by config {
retrieve("app.disabled".from(myConfigSource).andTransformBy { !it })
"app.disabled".from(myConfigSource).andTransformBy { !it }
}

// Search for value in a legacy config file and then the new one
val enabled: Boolean by config {
retrieve("old.path.app.enabled".from(legacyConfigSource))
retrieve("new.path.app.enabled".from(newConfigSource))
"old.path.app.enabled".from(legacyConfigSource)
"new.path.app.enabled".from(newConfigSource)
}

// Search for value in a legacy config file and then the new one, mark the old one as deprecated
val enabled: Boolean by config {
retrieve("old.path.app.enabled".from(legacyConfigSource).softDeprecated("use 'new.path.app.enabled' in new config source")
retrieve("new.path.app.enabled".from(newConfigSource))
"old.path.app.enabled".from(legacyConfigSource).softDeprecated("use 'new.path.app.enabled' in new config source")
"new.path.app.enabled".from(newConfigSource)
}

// Use the result of a lambda as a value
val port: Int by config {
"path.to.port".from(newConfigSource)
"default" { 8080 }
}

// Only allow access to port if 'enabled' is true (throws an exception otherwise)
val port: Int by config {
onlyIf("Server is enabled", ::enabled) {
retrieve("path.to.port".from(newConfigSource))
"path.to.port".from(newConfigSource)
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions docs/Debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ For example, to set up the jitsi-metaconfig logger:
val logger = Logger.getLogger("metaconfig")

val metaconfigLogger = object : MetaconfigLogger {
override fun error(block: () -> String) {
override fun error(block: () -> String) {
logger.error(block())
}
override fun warn(block: () -> String) {
}
override fun warn(block: () -> String) {
logger.warn(block())
}
}
override fun debug(block: () -> String) {
logger.fine(block)
}
Expand All @@ -23,10 +23,10 @@ val metaconfigLogger = object : MetaconfigLogger {
### Logging when searching for a value
If you have a property:
```kotlin
val num: Int by config {
retrieve("some.missing.path".from(legacyConfig))
retrieve("new.num".from(newConfig))
retrieve("default value") { 8080 }
val num: Int by config {
"some.missing.path".from(legacyConfig)
"new.num".from(newConfig)
"default value" { 8080 }
}
```

Expand Down
40 changes: 20 additions & 20 deletions docs/DelegateHelpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ val myProperty: Int by config("path.to.property".from(myConfigSource))
To define a property which checks multiple configuration sources, stopping at the first value it finds, use:
```kotlin
val myProperty: Int by config {
retrieve("legacy.path".from(legacyConfigSource))
retrieve("new.path".from(newConfigSource))
"legacy.path".from(legacyConfigSource)
"new.path".from(newConfigSource)
}
```
This will first try to retrieve an `Int` at `legacy.path` from `legacyConfigSource`, if it isn't found, it will try to retrieve an `Int` at `new.path` from `newConfigSource`.
Expand All @@ -22,7 +22,7 @@ This will first try to retrieve an `Int` at `legacy.path` from `legacyConfigSour
To transform the retrieved value in some way (here, by inverting the retrieved boolean), use:
```kotlin
val myProperty: Boolean by config {
retrieve("path.to.property".from(myConfigSource).andTransformBy { !it })
"path.to.property".from(myConfigSource).andTransformBy { !it }
}
```
This is useful if the semantics of a property were changed, for example:
Expand All @@ -46,34 +46,34 @@ This is useful if the semantics of a property were changed, for example:
The property would be:
```kotlin
val serverEnabled: Boolean by config {
retrieve("app.server.enabled".from(oldConfig))
"app.server.enabled".from(oldConfig)
// Invert the value to match if it's 'enabled'
retrieve("app.server.disabled".from(newConfig).andTransformBy { !it })
"app.server.disabled".from(newConfig).andTransformBy { !it }
}
```
Converting the type of a value is also possible. This is useful if you want the code to use a friendlier type than the config (say a `Duration` instead of a `Long` representing milliseconds):
```kotlin
val healthInterval: Duration by config {
retrieve("app.health.interval".from(legacyConfigSource).asType<Long>().andConvertBy(Duration::ofMillis)
"app.health.interval".from(legacyConfigSource).convertFrom<Long>(Duration::ofMillis)
}
```
---
### Pulling a value from elsewhere
It's possible to pull a value from anywhere (e.g. a property of an object, or even just a hard-coded default) by passing a lambda:
```kotlin
val port: Int by config {
retrieve("path.to.port".from(myConfig))
"path.to.port".from(myConfig)
// Since the lambda is opaque, the description gives some context
retrieve("Foo::port") { foo.port }
"Foo::port" { foo.port }
}
```
This will first try to retrieve an `Int` at `path.to.port` from `myConfig` and, if it can't be found, will grab the `port` member of `foo`. This could also be used to set a default value:

```kotlin
val port: Int by config {
retrieve("path.to.port".from(myConfig))
"path.to.port".from(myConfig)
// Since the lambda is opaque, the description gives some context
retrieve("default") { 8080 }
"default" { 8080 }
}
```
---
Expand All @@ -87,9 +87,9 @@ val serverEnabled: Boolean by config("app.server.enabled".from(config))

val port: Int by config {
onlyIf("Server is enabled", ::serverEnabled) {
retrieve("path.to.port".from(myConfig))
"path.to.port".from(myConfig)
// Since the lambda is opaque, the description gives some context
retrieve("default") { 8080 }
"default" { 8080 }
}
}
```
Expand All @@ -103,8 +103,8 @@ val myProperty: Int? by optionalconfig("path.to.property".from(myConfigSource))
Or
```kotlin
val myProperty: Int? by optionalconfig {
retrieve("path.to.property".from(myConfigSource))
retrieve("new.path.to.property".from(myConfigSource))
"path.to.property".from(myConfigSource)
"new.path.to.property".from(myConfigSource)
}
```

Expand Down Expand Up @@ -136,15 +136,15 @@ And you want to move the property:
You'd define a property in the code to look in both places, so deployments with the old configuration don't break:
```kotlin
val serverEnabled: Boolean by config {
retrieve("app.server.enabled".from(myConfig))
retrieve("app.api.server.enabled".from(myConfig))
"app.server.enabled".from(myConfig)
"app.api.server.enabled".from(myConfig)
}
```
But you want users to know that `app.server.enabled` is deprecated and they should use the new name/path. You can mark the old path as deprecated:
```kotlin
val serverEnabled: Boolean by config {
retrieve("app.server.enabled".from(myConfig).softDeprecated("use 'app.api.server.enabled'")
retrieve("app.api.server.enabled".from(myConfig))
"app.server.enabled".from(myConfig).softDeprecated("use 'app.api.server.enabled'")
"app.api.server.enabled".from(myConfig)
}
```
If a value is retrieved via "app.server.enabled" from myConfig, a warning will be logged:
Expand All @@ -156,8 +156,8 @@ This warning is only printed once, and only if the value marked as deprecated wa
Values can also be _hard_ deprecated:
```kotlin
val serverEnabled: Boolean by config {
retrieve("app.server.enabled".from(myConfig).hardDeprecated("use 'app.api.server.enabled'")
retrieve("app.api.server.enabled".from(myConfig))
"app.server.enabled".from(myConfig).hardDeprecated("use 'app.api.server.enabled'")
"app.api.server.enabled".from(myConfig)
}
```
And `ConfigException.UnableToRetrieve.Deprecated` will be thrown if that value is used as the result.
Expand Down
163 changes: 0 additions & 163 deletions src/main/kotlin/org/jitsi/metaconfig/ConfigPropertyState.kt

This file was deleted.

Loading

0 comments on commit b7f6d97

Please sign in to comment.