CDI Extensions
SmallRye Config provides a set of additional extensions to enhance MicroProfile Config and CDI integration.
Config Source Injection
The Config Source Injection extension allows you to use CDI injection to inject a ConfigSource by name in your CDI
aware beans, or by looking it up programatically in the CDI BeanManager
.
Usage
To use the Config Source Injection, add the following to your Maven pom.xml
:
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-source-injection</artifactId>
<version>2.4.0</version>
</dependency>
Injecting Sources
You can inject a ConfigSource
by referencing it by name:
@Inject
@Name("MemoryConfigSource")
private ConfigSource memoryConfigSource;
@Inject
@Name("SysPropConfigSource")
private ConfigSource systemPropertiesConfigSource;
You can also get a Map of all config sources. The map key holds the ConfigSource
name and the map value the
ConfigSource
:
@Inject
@ConfigSourceMap
private Map<String,ConfigSource> configSourceMap;
Config Events
The Config Events extension allows you to fire change events on Config Sources.
Usage
To use the Config Events, add the following to your Maven pom.xml
:
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-events</artifactId>
<version>2.4.0</version>
</dependency>
Events
The CDI Event is a ChangeEvent
and contains the following fields:
-
String key
-
Optional<String> oldValue
-
String newValue
-
Type type
-
String fromSource
The ChangeEvent
can be of any of the following types:
-
NEW - When you create a new key and value (i.e. the key does not exist anywhere in any config source)
-
UPDATE - When you update a value of an existing key (i.e. the key and value exist somewhere in a config source)
-
REMOVE - When you remove the value from the source (and that changed the overall config)
Observing Events
You can listen to all or some of these events, filtering by type
and/or key
and/or source
, example:
// Getting all config event
public void all(@Observes ChangeEvent changeEvent){
log.log(Level.SEVERE, "ALL: Received a config change event: {0}", changeEvent);
}
// Get only new values
public void newValue(@Observes @TypeFilter(Type.NEW) ChangeEvent changeEvent){
log.log(Level.SEVERE, "NEW: Received a config change event: {0}", changeEvent);
}
// Get only override values
public void overrideValue(@Observes @TypeFilter(Type.UPDATE) ChangeEvent changeEvent){
log.log(Level.SEVERE, "UPDATE: Received a config change event: {0}", changeEvent);
}
// Get only revert values
public void revertValue(@Observes @TypeFilter(Type.REMOVE) ChangeEvent changeEvent){
log.log(Level.SEVERE, "REMOVE: Received a config change event: {0}", changeEvent);
}
// Getting all config event when key is some.key
public void allForKey(@Observes @KeyFilter("some.key") ChangeEvent changeEvent){
log.log(Level.SEVERE, "ALL for key [some.key]: Received a config change event: {0}", changeEvent);
}
// Getting all config event when key is some.key for new events
public void newForKey(@Observes @TypeFilter(Type.NEW) @KeyFilter("some.key") ChangeEvent changeEvent){
log.log(Level.SEVERE, "NEW for key [some.key]: Received a config change event: {0}", changeEvent);
}
// Getting all config event when key is some.key for override events
public void overrideForKey(@Observes @TypeFilter(Type.UPDATE) @KeyFilter("some.key") ChangeEvent changeEvent){
log.log(Level.SEVERE, "UPDATE for key [some.key]: Received a config change event: {0}", changeEvent);
}
// Getting all config event when key is some.key for revert events
public void revertForKey(@Observes @TypeFilter(Type.REMOVE) @KeyFilter("some.key") ChangeEvent changeEvent){
log.log(Level.SEVERE, "REMOVE for key [some.key]: Received a config change event: {0}", changeEvent);
}
// Getting all config events for a certain source
public void allForSource(@Observes @SourceFilter("MemoryConfigSource") ChangeEvent changeEvent){
log.log(Level.SEVERE, "ALL for source [MemoryConfigSource]: Received a config change event: {0}", changeEvent);
}
// Getting all config events for a certain source
public void allForSourceAndKey(@Observes @SourceFilter("MemoryConfigSource") @KeyFilter("some.key") ChangeEvent changeEvent){
log.log(Level.SEVERE, "ALL for source [MemoryConfigSource] and for key [some.key]: Received a config change event: {0}", changeEvent);
}
// Getting all config events for a certain source
public void overrideForSourceAndKey(@Observes @TypeFilter(Type.UPDATE) @SourceFilter("MemoryConfigSource") @KeyFilter("some.key") ChangeEvent changeEvent){
log.log(Level.SEVERE, "UPDATE for source [MemoryConfigSource] and for key [some.key]: Received a config change event: {0}", changeEvent);
}
Note: You can filter by including the @TypeFilter
and/or the @KeyFilter
and/or the @SourceFilter
.
Pattern matching on field.
You might want to listen for fields that match a certain regex.
Example, listen to all keys that starts with some.
:
@RegexFilter("^some\\..+")
public void allForPatternMatchOnKey(@Observes ChangeEvent changeEvent){
log.log(Level.SEVERE, "Pattern match on key: Received a config change event: {0}", changeEvent);
}
By default, it will match on key
, however you also listen on another field, for example, listen to all oldValue
that starts with some.
:
@RegexFilter(onField = Field.oldValue, value = "^some\\..+")
public void allForPatternMatchOnOldValue(@Observes ChangeEvent changeEvent){
log.log(Level.SEVERE, "Pattern match on old value: Received a config change event: {0}", changeEvent);
}
You can Match on the following fields of the ChangeEvent
object:
-
key
-
oldValue
-
newValue
-
fromSource
Implementing Events in a ConfigSource
The ChangeEventNotifier
allows you to detect changes and fire the appropriate events.
To use it in your own source:
-
Get a snapshot of the properties before the change.
-
Get a snapshot of the properties after the change.
-
Call
detectChangesAndFire
method:
Example:
Map<String,String> before = new HashMap<>(configSource.getProperties());
memoryConfigSource.getProperties().remove(key);
Map<String,String> after = new HashMap<>(configSource.getProperties());
ChangeEventNotifier.getInstance().detectChangesAndFire(before, after,configSource.getName());
or if you know the change and do not need detection:
configSource.getProperties().remove(key);
ChangeEventNotifier.getInstance().fire(new ChangeEvent(Type.REMOVE,key,getOptionalOldValue(oldValue),null,configSource.getName()));