SpringBoot RestTemplate Connection Pooling: Managing Stale Connections - spring

I am using RestTemplate with ConnectionPooling using PoolingHttpClientConnectionManager as in below code :
PoolingHttpClientConnectionManager connectionManager = new
PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
connectionManager.setMaxPerRoute(new HttpRoute(new
HttpHost(excConfig.getImsServerEndpoint())), IMS_ROUTE_MAX_CONNECTIONS);
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connectionManager).build();
HttpComponentsClientHttpRequestFactory httpReqFactory = new HttpComponentsClientHttpRequestFactory(httpclient);
httpReqFactory.setReadTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
httpReqFactory.setConnectionRequestTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
httpReqFactory.setConnectTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
restTemplate = new RestTemplate(httpReqFactory);
Does RestTemplate take care of terminating stale connections by itself? Or do I need to put in some specific handling for the same?

By default it does not, but you can configure it easily in your CloseableHttpClient configuration.
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true))
.setConnectionManager(connectionManager)
.build();`
Source here.

setStaleConnectionCheckEnabled has become obsolete.
HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true))
.setConnectionManager(connectionManager)
.build();
In HttpClient 4.5.3 the below code works -
PoolingHttpClientConnectionManager connManager
= new PoolingHttpClientConnectionManager();
connManager.setValidateAfterInactivity(20);
HttpClient httpClient = HttpClients.custom().setConnectionManager(connManager).build();

Related

springboot 3.0 restTemplate with SSLHostNameVerifier

We are upgrading to springboot 3.0 and we have the following resttemplate code.The following code creating issue at CloseableHttpClient and NoopHostnameVerifier.We are upgrading this app to springboot 3.0.
`
#Bean public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()) .build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory( httpClient);
restTemplate.setRequestFactory(clientHttpRequestFactory);
return restTemplate;
}
`
We are noware found NoopHostnameVerifier,CloseableHttpClient.Any help is appreciated.
Upgrade to spring boot 3
Thanks in Advance

CloseableHttpClient Breaking with Reason-Phrase

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(2000);
connectionManager.setDefaultMaxPerRoute(500);
RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(10000).setConnectTimeout(10000)
.setSocketTimeout(10000).build();
CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
.setDefaultRequestConfig(config).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
// HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(10000);
requestFactory.setReadTimeout(10000);
requestFactory.setConnectionRequestTimeout(10000);
RestTemplate restTemplate = new RestTemplate(requestFactory);
When we call a API which responds with Response status and Reason Phrase
HTTP/1.1 200 OK
This breaks as following
Caused by: org.apache.http.ProtocolException: Invalid header: [0x10][0x11]OK
at org.apache.http.impl.io.AbstractMessageParser.parseHeaders(AbstractMessageParser.java:230)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:266)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)

Adding Java environment variables in application.properties in springboot

I am running a springboot application which requires to trust the certificate which i added in my local truststore.
For now i am setting it under run configurations options in intellij and it works.
ex->::-Djavax.net.ssl.trustStore=location\cacerts;-Djavax.net.ssl.trustStorePassword=changeit
I was wondering is there any way to set it from application.properties file in springboot in the way we set spring properties?
If you want to make REST calls, You can configure the RestTemplate Bean like :
#Configuration
public class SslConfiguration {
#Value("${http.client.ssl.trust-store}")
private Resource keyStore;
#Value("${http.client.ssl.trust-store-password}")
private String keyStorePassword;
#Bean
RestTemplate restTemplate() throws Exception {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(
keyStore.getURL(),
keyStorePassword.toCharArray()
).build();
SSLConnectionSocketFactory socketFactory =
new SSLConnectionSocketFactory(sslContext);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory).build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
}
Check this : Example

How to set NTLM authentication in rest template Header in Spring

I want to authenticate NTLM using Rest template , can any one suggest the way ?
If anyone stumble upon this entry again, this is the builtin solution:
Ensure your project includes the org.apache.httpcomponents.httpclient.
Then you can build your RestTemplate with this snippet:
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new NTCredentials(user, password, "source-host-name", "domain-name"));
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
this is what I did taking cues from here. Credits goes here only.
Set up rest template to use apache http client -> compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.5'
Updated my rest template bean to use httpclient -
RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
restTemplate.setRequestFactory(requestFactory);
Then just do what the link here says. Add the NtlmAuthenticator class and do this just before your restTemplate call.
NtlmAuthenticator authenticator = new NtlmAuthenticator(userName, password);
Authenticator.setDefault(authenticator);
That's it. You are all set up.

How do I set timeouts per request using Spring REST Template?

I have an application that makes use of multiple rest clients. Each of those REST clients use the same Spring REST template bean. I was wondering if there was a way to set the timeout value per request using the Spring rest template?
This worked for me...
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
private ClientHttpRequestFactory getClientHttpRequestFactory() {
int timeout = 5000;
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
= new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout(timeout);
return clientHttpRequestFactory;
}
To achieve calling rest template with timeout, first you should create config class also use with #Bean annotation, then implement in class and call with RestTemplateConfig.
#Configuration
public class RestTemplateConfig {
#Bean
public RestTemplate restTemplate() {
return new RestTemplate(clientHttpRequestFactory());
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectionRequestTimeout(4000);
clientHttpRequestFactory.setReadTimeout(4000);
clientHttpRequestFactory.setConnectTimeout(4000);
return clientHttpRequestFactory;
}
}
But I suggest you use Apache HttpClient, you can manage the connection pool, keep-alive, idle monitor and also create custom error handler. You can check the link: https://springframework.guru/using-resttemplate-with-apaches-httpclient/
You can also modify the SimpleClientHttpRequestFactory.
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(customHttpRequestFactory());
private SimpleClientHttpRequestFactory customHttpRequestFactory() {
SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
simpleClientHttpRequestFactory.setReadTimeout(2000);
simpleClientHttpRequestFactory.setConnectTimeout(2000);
return simpleClientHttpRequestFactory;
}

Resources