I want to group configuration items in Quarkus and use them as a Map
. Something along the lines of the next application.properties
:
greeting.names = tom,jane
greeting.tom.message = hello
greeting.tom.name = tom
greeting.jane.message = hi
greeting.jane.name = jane
And have them in the application in a Map
, like this:
@ConfigProperties
public class GreetingConfig {
private String name;
private String message;
// getters / setters
}
And use them like this:
private Map<String, GreetingConfig> config;
They are now name indexed, but a List
would also be fine (and is what I actually need):
greeting.1.message = hello
greeting.1.name = tom
greeting.2.message = hi
greeting.2.name = jane
Any ideas on how to realize this? I have a programmatic solution, but would prefer a solution by annotation only
I've had a similar problem these days. So I wrote a simple Quarkus extension which helped me with the configuration. You can use the guides from the Quarkus site: Quarkus - Writing Your Own Extension and Quarkus - Building my first extension, but basically these are the steps taken in order to create the configuration:
maven
multi module project (not the project where the configuration will be consumed).mvn io.quarkus:quarkus-maven-plugin:1.4.2.Final:create-extension -N \
-Dquarkus.artifactIdBase=keycloak-extension \
-Dquarkus.artifactIdPrefix=otaibe-commons-quarkus- \
-Dquarkus.nameBase="Keycloak extension"
This will create 'sub multi module' project there with the following modules: runtume
and deployment
.
runtime
module and add and annotate your config class. It should be something similar to this classruntime
module create a producer
class which should register the configuration class as CDI bean:@ApplicationScoped
public class OtaibeKeycloakQuarkusProducer {
private volatile OtaibeKeycloakConfig otaibeKeycloakConfig;
void initialize(OtaibeKeycloakConfig config) {
this.otaibeKeycloakConfig = config;
}
@Singleton
@Produces
public OtaibeKeycloakConfig otaibeKeycloakConfig() {
return otaibeKeycloakConfig;
}
}
Recorder
class which should initialize the Producer
:@Recorder
public class OtaibeKeycloakRecorder {
public void initOtaQuarkusProducer(BeanContainer container, OtaibeKeycloakConfig configuration) {
OtaibeKeycloakQuarkusProducer producer = container.instance(OtaibeKeycloakQuarkusProducer.class);
producer.initialize(configuration);
}
}
deployment
module you have a Processor
class. Go there and register your Producer
to be injectable as CDI bean and your Recorder
to initialize it. Add the similar code: @BuildStep
AdditionalBeanBuildItem beans() {
return AdditionalBeanBuildItem.builder().addBeanClasses(OtaibeKeycloakQuarkusProducer.class).build();
}
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void otaibeKeycloackConfigBuildItem(BeanContainerBuildItem beanContainer,
OtaibeKeycloakConfig otaibeKeycloakConfig,
OtaibeKeycloakRecorder recorder) {
recorder.initOtaQuarkusProducer(beanContainer.getValue(), otaibeKeycloakConfig);
}
You can find my implementation here.
Now, go to your initial project where the configuration will be consumed and add the runtime
module as a dependency.
In order to ensure that the configuration is added properly execute the following maven
command:
mvn quarkus:generate-config
Now, you can check the file src/main/resources/application.properties.example
and verify whether your properties are added there. The property group should start with quarkus.
plus the name of your @ConfigRoot
annotation. In my case for example it will start with quarkus.otaibe.keycloak
That's it!