Spring custom, high performance, metered http client instances
Coming from DropWizard, I am used to HttpClientConfiguration and I am confused that in Spring Boot I cannot find support for managing in similarly used http client instances, for example with RestTemplates.
For production to work, the base client implementation must be high (e.g. no blocking io, with connection reuse and pooling).
Then I need to set timeouts or authentication, maybe metrics collection, cookie settings, SSL certificate settings.
All of the above should be easily configured in different flavors for different instances to be used in different contexts (for example, for service X use these parameters and this pool, for Y use a different pool and settings), and most of the parameters should be set via environment properties to have different meanings in production / qa / development.
Is there something that can be used for this purpose?
source to share
Below is an example setup HttpClient
with a config class. It configures basic authentication for all requests through this one RestTemplate
, as well as some settings to the pool.
HttpClientConfiguration.java
@Configuration
public class HttpClientConfiguration {
private static final Logger log = LoggerFactory.getLogger(HttpClientConfiguration.class);
@Autowired
private Environment environment;
@Bean
public ClientHttpRequestFactory httpRequestFactory() {
return new HttpComponentsClientHttpRequestFactory(httpClient());
}
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(httpRequestFactory());
restTemplate.setInterceptors(ImmutableList.of((request, body, execution) -> {
byte[] token = Base64.encodeBase64((format("%s:%s", environment.getProperty("fake.username"), environment.getProperty("fake.password"))).getBytes());
request.getHeaders().add("Authorization", format("Basic %s", new String(token)));
return execution.execute(request, body);
}));
return restTemplate;
}
@Bean
public HttpClient httpClient() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
// Get the poolMaxTotal value from our application[-?].yml or default to 10 if not explicitly set
connectionManager.setMaxTotal(environment.getProperty("poolMaxTotal", Integer.class, 10));
return HttpClientBuilder
.create()
.setConnectionManager(connectionManager)
.build();
}
/**
* Just for demonstration
*/
@PostConstruct
public void debug() {
log.info("Pool max total: {}", environment.getProperty("poolMaxTotal", Integer.class));
}
}
and example application.yml
fake.username: test
fake.password: test
poolMaxTotal: 10
You can export config values ββto application.yml
, like to poolMaxTotal
, etc. higher.
You can use Spring profiles to support different values ββfor your environment. Using the above example, you can simply create application-prod.yml
with a specific "prod" value for poolMaxTotal
. Then run the application with --spring.profiles.active=prod
and instead of the default in application.yml
, the value "prod" will be used. You can do this for any large number of environments you need.
application-prod.yml
poolMaxTotal: 20
For async HttpClient
, see here: http://vincentdevillers.blogspot.fr/2013/10/a-best-spring-asyncresttemplate.html
source to share