dynamic-property
Provides easy way to change application configuration at runtime.
Inject properties by id
class MyService{
@PropertyId("my.service.rate")
lateinit var rate: DynamicProperty<Integer>
fun myMethod(){
val rate = rate.get()
//use current value of rate from dynamic property
calculate(rate)
}
}
class MyService {
@PropertyId("my.service.setting")
lateinit var setting: PropertySubscription<Setting>
@PostConstruct
fun postConstructInitialization() {
setting.setAndCallListener{oldValue, newValue ->
updateState(newValue)
}
}
fun updateState(setting: Setting) {}
fun doWork() {}
}
Provide default values for injected properties
class MyService{
@PropertyId("my.service.rate")
var rate = DynamicProperty.of(12)
@PropertyId("my.service.setting")
var setting = PropertySubscription.of(Setting(7, 15))
}
Inject properties explicitly through constructor
class MyService(setting: DynamicProperty<Setting>) {
val subscription = setting.createSubscription().setAndCallListener { oldSetting, newSetting ->
// initialize service
// or update state on settings change
updateState(newSetting)
}
fun updateState(setting: Setting) {}
fun doWork() {}
}
class MyService(val setting: DynamicProperty<Setting>) {
fun doWork() {
val currentSetting = setting.get()
}
}
Support various property sources.
- properties files
- ZooKeeper
Compose properties
You can build one property based on another:
val stringProperty: DynamicProperty<String>
val intProperty = stringProperty.map { str -> str.toInt() }
val service = ServiceThatRequiresIntProperty(intProperty)
Combine properties
You can build new property based on several others:
val first = AtomicProperty("hello")
val second = AtomicProperty("123")
val combined = CombinedProperty(listOf(first, second)) { first.get() + second.get() }
//combined == "hello123"
first.set("hi")
//combined == "hi123"
second.set("42")
//combined == "hi42"
Mock property in tests
//constant property that never changes
val constantProperty = DynamicProperty.of(122)
val myService = MyService(constantProperty)
myService.doWork()
//property that could change during test
val atomicProperty = AtomicProperty(122)
val myService = MyService(atomicProperty)
atomicProperty.set(512)
myService.doWork()
Polled values
DynamicPropertyPoller regularly invoke user defined supplier function that returns current value of DynamicProperty that backed by custom user defined data source.
DynamicPropertyPoller poller = DynamicPropertyPoller(
NamedExecutors.newSingleThreadScheduler(
"polling",
profiler
),
DynamicProperty.of(Schedule.withRate(1000L)));
class UserClassWithDynamicPropertiesBackedByCustomDataSource {
DynamicProperty<String> myProperty;
public UserClass(DynamicPropertyPoller poller){
myProperty = poller.createProperty(()-> myDaoService.loadValueFromDatabase(...));
myProperty.addAndCallListener( value -> {
//init or update state based on property value
...
});
}
}