Monday 15 May 2023

Micronaut: @EachProperty: list based binding of configuration properties

This is continuation to my previous post. In my previous post, I explained how to derive beans using @EachProperty annotation from a map style of configuration. But there are situations, where a map style configuration doesn’t make sense, in that case, we can inform Micronaut that this class is bound from a list.

 

For example, have a look at below configuration.

app:   
  datasource:
    - name : devSource
      connection-timeout: 3000
      max-lifetime: 4000
      maximum-pool-size: 5
    - name : qaSource
      connection-timeout: 5000
      max-lifetime: 6000
      maximum-pool-size: 6
    - name : prodSource
      connection-timeout: 7000
      max-lifetime: 8000
      maximum-pool-size: 7

 

We can get three datasource beans using below definition.

@EachProperty(value = "app.datasource", list = true)
public class DataSourceConfiguration implements Ordered{

  private Integer connectionTimeout;

  private Integer maxLifetime;

  private Integer maximumPoolSize;

  private String name;

  private Integer index;

  public DataSourceConfiguration(@Parameter Integer index) {
    this.index = index;
  }

  .......
  .......
}

Points to note:

a.    The list member of the annotation is set to true

b.   Implement Ordered if order matters when retrieving the beans

c.    The index is injected into the constructor

 

Find the below working application.

 

Step 1: Create new maven project ‘micronaut-each-property-list-demo’.

 

Step 2: Update pom.xml with maven dependencies.

 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sample.app</groupId>
  <artifactId>micronaut-each-property-list-demo</artifactId>
  <version>1</version>

  <parent>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-parent</artifactId>
    <version>3.7.3</version>
  </parent>


  <properties>
    <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>

    <maven.compiler.target>15</maven.compiler.target>
    <maven.compiler.source>15</maven.compiler.source>
  </properties>

  <dependencies>

    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-inject-java</artifactId>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin.version}</version>
        <configuration>
          <annotationProcessorPaths>
            <path>
              <groupId>io.micronaut</groupId>
              <artifactId>micronaut-inject-java</artifactId>
            </path>
          </annotationProcessorPaths>
        </configuration>
      </plugin>

      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <mainClass>com.sample.app.App</mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>

        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>


    </plugins>
  </build>
</project>

Step 3: Create application.yml file under src/main/resources folder.

 

application.yml

app:   
  datasource:
    - name : devSource
      connection-timeout: 3000
      max-lifetime: 4000
      maximum-pool-size: 5
    - name : qaSource
      connection-timeout: 5000
      max-lifetime: 6000
      maximum-pool-size: 6
    - name : prodSource
      connection-timeout: 7000
      max-lifetime: 8000
      maximum-pool-size: 7

 

Step 4: Define DataSourceConfiguration class.

 

DataSourceConfiguration.java

package com.sample.app.configuration;

import io.micronaut.context.annotation.EachProperty;
import io.micronaut.context.annotation.Parameter;
import io.micronaut.core.order.Ordered;

@EachProperty(value = "app.datasource", list = true)
public class DataSourceConfiguration implements Ordered{

  private Integer connectionTimeout;

  private Integer maxLifetime;

  private Integer maximumPoolSize;

  private String name;

  private Integer index;

  public DataSourceConfiguration(@Parameter Integer index) {
    this.index = index;
  }

  public Integer getConnectionTimeout() {
    return connectionTimeout;
  }

  public void setConnectionTimeout(Integer connectionTimeout) {
    this.connectionTimeout = connectionTimeout;
  }

  public Integer getMaxLifetime() {
    return maxLifetime;
  }

  public void setMaxLifetime(Integer maxLifetime) {
    this.maxLifetime = maxLifetime;
  }

  public Integer getMaximumPoolSize() {
    return maximumPoolSize;
  }

  public void setMaximumPoolSize(Integer maximumPoolSize) {
    this.maximumPoolSize = maximumPoolSize;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Integer getIndex() {
    return index;
  }

  public void setIndex(Integer index) {
    this.index = index;
  }

  @Override
  public String toString() {
    return "DataSourceConfiguration [connectionTimeout=" + connectionTimeout + ", maxLifetime=" + maxLifetime
        + ", maximumPoolSize=" + maximumPoolSize + ", name=" + name + ", index=" + index + "]";
  }

}

 

Step 5: Define main application class.

 

App.java

 

package com.sample.app;

import java.util.Collection;

import com.sample.app.configuration.DataSourceConfiguration;

import io.micronaut.context.ApplicationContext;

public class App {

  public static void main(String[] args) {

    try (ApplicationContext applicationContext = ApplicationContext.run()) {

      Collection<DataSourceConfiguration> configs = applicationContext
          .getBeansOfType(DataSourceConfiguration.class);

      for (DataSourceConfiguration config : configs) {
        System.out.println(config);
      }
    }

  }
}

Total project structure looks like below.



 

Build the project using mvn package command.

Navigate to the folder where pom.xml is located and execute the command ‘mvn package’.

 

Upon command successful execution, you can see the jar file ‘micronaut-each-property-list-demo-1-jar-with-dependencies.jar’ in project target folder.

 

$ls ./target/
archive-tmp
classes
generated-sources
generated-test-sources
maven-archiver
maven-status
micronaut-each-property-list-demo-1-jar-with-dependencies.jar
micronaut-each-property-list-demo-1.jar
test-classes

Execute below command to run the application.

java -jar ./target/micronaut-each-property-list-demo-1-jar-with-dependencies.jar

$java -jar ./target/micronaut-each-property-list-demo-1-jar-with-dependencies.jar
DataSourceConfiguration [connectionTimeout=3000, maxLifetime=4000, maximumPoolSize=5, name=devSource, index=0]
DataSourceConfiguration [connectionTimeout=7000, maxLifetime=8000, maximumPoolSize=7, name=prodSource, index=2]
DataSourceConfiguration [connectionTimeout=5000, maxLifetime=6000, maximumPoolSize=6, name=qaSource, index=1]

You can download this application from this link.


Previous                                                    Next                                                    Home

No comments:

Post a Comment