0

I am writing a java library module in Micronaut which has an httpClient. The idea is that my microservices will use this library as a jar dependency and use the httpClient.

Problem Statement : I want to configure my HttpClient without using application.yml.

Why don't I want to use application.yml ? - Because the microservices using this library will also have their own application.yml and when the jar is built, the two application.yml files will need to be merged. While technically possible, I don't want to use this approach.

Scenario - There is a boolean configuration property called micronaut.http.client.exception-on-error-status in micronaut that I need to set to false. I can easily set this in the application.yml as micronaut.http.client.exception-on-error-status=false but I want to avoid this approach due to aforementioned reasons. I want to set this in code.

I tried the following TWO approaches and neither of them worked.

Approach 1 - Using @ConfigurationProperties

I created the following MicronautHttpClientConfiguration.java class, but the property was NOT set.

import io.micronaut.context.annotation.ConfigurationProperties;

@ConfigurationProperties("micronaut.http.client")
public class MicronautHttpClientConfiguration {
    private boolean exceptionOnErrorStatus;

    public MicronautHttpClientConfiguration() {
        this.exceptionOnErrorStatus = false;
    }

    public boolean isExceptionOnErrorStatus() {
        return exceptionOnErrorStatus;
    }

    public void setExceptionOnErrorStatus(boolean exceptionOnErrorStatus) {
        this.exceptionOnErrorStatus = exceptionOnErrorStatus;
    }
}

Approach 2 - Using BeanCreatedEventListener

I created the following BeanCreatedEventListener to try and configure the HttpClient on creation, but was not able to.

import io.micronaut.context.event.BeanCreatedEvent;
import io.micronaut.context.event.BeanCreatedEventListener;
import io.micronaut.http.client.HttpClient;

import javax.inject.Singleton;

@Singleton
public class HttpClientBeanCreationEvent implements BeanCreatedEventListener<HttpClient> {
    @Override
    public HttpClient onCreated(BeanCreatedEvent<HttpClient> event) {
        HttpClient httpClient = event.getBean();
        // I have a handle on the HttpClient here, but not really sure how to set that property
        return httpClient;
    }
}

P.S. This problem is applicable to any HttpClient configuration (like read-timeout) or any default micronaut configuration for that matter.

UPDATE 1 : I am looking for a solution using @ConfigurationProperties as I realised that if I use approach 2 of BeanCreationEvent, Micronaut will never honour any configuration in application.yml (for this property) as BeanCreationEvent overrides all that. This will make it difficult for implementing microservices to override this property.

Burt Beckwith
  • 75,342
  • 5
  • 143
  • 156
Shrinath
  • 534
  • 10
  • 18
  • "I am looking for a solution using @ConfigurationProperties" - You should update the title of this question which is currently "Configuring default micronaut httpClient properties without using application.yml". There are a lot of ways to do it without using `application.yml`. It would be better if the title represented the specific way you are asking about (`@ConfigurationProperties`). – Jeff Scott Brown Mar 24 '22 at 16:07
  • Do you have to use micronaut HttpClient? If not I can offer you some alternatives. One of them is my own HttpClient which is part of my own open-source library. This one is very simplistic but the advantage is if it does what you need - no configuration required. All settings are done in code and they hold over between the calls. I.e. If you configured url and all the headers you can continuously invoke Http call method(s) and they will re-use your settings until manually changed. – Michael Gantman Mar 31 '22 at 09:28
  • Thanks, but using a non-standard library will require a lot of approvals at my company - so that's not an option. If you can share the link, I can definitely take a look. – Shrinath Mar 31 '22 at 11:42

1 Answers1

0

You should be creating a declarative client to expose to users and in the @Client annotation you can specify a configuration class

James Kleeh
  • 12,094
  • 5
  • 34
  • 61