user0000001
user0000001

Reputation: 2233

Reading configuration file with a map of properties in Quarkus

My application.yaml has a map of values stored in a yaml file.

app:
  myMap:
    key1: value1
    key2: value2
    key3: value3

Configuration class:

@Data
@ApplicationScoped
public class AppConfiguration {

    @ConfigProperty(name = "app.myMap")
    private Map<String, String> myMap;
}

This results in the following error:
javax.enterprise.inject.spi.DeploymentException: No config value of type [java.util.Map] exists for: app.myMap

I'm unable to read these values because MicroProfile does not support java.util.Map. I came across this mailing list that suggests a workaround but being rather new to Quarkus, I'm unsure of how to implement this properly. It's also a year old and I'm wondering if there is a better implementation then what was suggested in that mailing list.

Upvotes: 0

Views: 5256

Answers (2)

triangularSquare
triangularSquare

Reputation: 21

You can achieve this by using a config mapping that's provided through the @ConfigMapping interface.

Using a YAML configuration

Since your specific case deals with YAML, you can do the following ...

Code

First, make sure you don't forget to provide the respective dependency to enable YAML configuration:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-config-yaml</artifactId>
</dependency>

The configuration you want to apply is application.yaml:

app:
  myMap:
    key1: value1
    key2: value2
    key3: value3

The respective config mapping can be implemented like this:

@ConfigMapping(prefix = "app")
public interface AppConfig {

    @WithName("myMap")
    Map<String, String> myMap();
}

Calling the configuration in your code is then straightforward, eg.:

@Path("/ping")
public class PingResource {

    @Inject
    AppConfig appConfig;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String ping() {
        String v1 = appConfig.myMap().get("key1");
        String v2 = appConfig.myMap().get("key2");
        String v3 = appConfig.myMap().get("key3");
        return "Values: [" + v1 + ":" + v2 + ":" + v3 + "]\n";
    }
}

Using an application.properties file

In case you want to use an application.properties instead, do the following ...

Code

If you want to use an application.properties , we don't need the quarkus-config-yaml Maven dependency.

The application.properties then becomes:

app.myMap.key1=value1
app.myMap.key2=value2
app.myMap.key3=value3

The code for the config mapping keeps being the same:

@ConfigMapping(prefix = "app")
public interface AppConfig {

    @WithName("myMap")
    Map<String, String> myMap();
}

... as well as the logic to fetch it:

@Path("/ping")
public class PingResource {

    @Inject
    AppConfig appConfig;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String ping() {
        String v1 = appConfig.myMap().get("key1");
        String v2 = appConfig.myMap().get("key2");
        String v3 = appConfig.myMap().get("key3");
        return "Values: [" + v1 + ":" + v2 + ":" + v3 + "]\n";
    }
}

Reference

https://quarkus.io/guides/config-yaml

https://quarkus.io/guides/config-mappings

Upvotes: 0

Roberto Cortez
Roberto Cortez

Reputation: 1163

Yes, indeed there is a better way now. Quarkus configuration is implemented by SmallRye Config. Unfortunately, it doesn't support Map direct injection directly, but you can use a mapping object like documented here: https://smallrye.io/docs/smallrye-config/main/mapping/mapping.html

Here is an example project: https://github.com/smallrye/smallrye-config/tree/main/examples/mapping

All of this works in Quarkus.

Upvotes: 2

Related Questions