Spring rest template close connection if the data is more - spring

I have a scenario where the http connection needs to be closed if the server is sending more data than expected. i.e after a few seconds of receiving the data, I would like the close the connection automatically. Is this feasible?

You can specify a timeout on your RestTemplate. That way you can terminate any long running requests.
#Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder)
{
return restTemplateBuilder
.setConnectTimeout(...)
.setReadTimeout(...)
.build();
}

Related

how to do client side load balancing in spring integration

we can add client-side load balancing in spring boot applications by,
#Bean
#LoadBalanced
public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
This will take care of the microservice resolution as well. ie. identifying service by the URL like "http://service_name/api/v1/endpoint/".
Is there any similar mechanism for name resolution in Spring integration?
See this ctor for Spring Integration HTTP Outbound Channel Adapter:
/**
* Create a handler that will send requests to the provided URI using a provided RestTemplate
* #param uri The URI.
* #param restTemplate The rest template.
*/
public HttpRequestExecutingMessageHandler(String uri, RestTemplate restTemplate) {
So, when you configure a #ServiceActivator (handle() in Java DSL), you just inject your load-balanced RestTemplate and everything should work as expected.

Connection is unable to read and will timeout after being idle

ServiceA uses a RestTemplate, created using a new instance of RestTemplateBuilder (not the default one created by Spring), to send requests to third-party services.
#Service
public class ServiceA {
private static final String URL_B = "...";
private RestTemplate restTemplate;
public ServiceA() {
restTemplate = new RestTemplateBuilder()
.uriTemplateHandler(new UriTemplateHandler() {
//...
})
.build();
}
public ResponseB getResponseAForServiceB() {
return restTemplate.getForObject(URL_B, ResponseB.class);
}
}
When the Spring Boot app starts up, requests made by ServiceA to ServiceB (third-party) will succeed without any issues. After about 1-1.5 hours of no requests, the first request made by ServiceA to ServiceB will cause a connection timeout for failing to read but a second request will succeed. What is causing the connection to not be able to read and timeout after being idle for a bit?

Spring Boot RestTemplate random ResourceAccessException: Connection reset errors

I have a system that implements 4 micro-services. The four services need to occasionally share information and they do it via RESTful requests using Spring's RestTemplate. Currently about 5%-10% of the requests fail with an exception like:
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://otherservice.com/path": Connection reset; nested exception is java.net.SocketException: Connection reset
Again, this appears random and only fails about 5%-10% of the time. I have tried multiple things but nothing seems to work. Currently I am trying this:
Configuration:
#Configuration
public class BeanConfiguration {
#Bean
public RestTemplate restTemplate() {
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());
return new RestTemplate(requestFactory);
}
}
Service:
#Autowired
public MyService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public Contact addContact(Contact contact) {
HttpEntity<Contact> entity = new HttpEntity<>(contact, authenticationTokenInfo.setTokenHeaders());
ResponseEntity<Contact> response = restTemplate.exchange(contact_base_url, HttpMethod.POST, entity, Contact.class);
return response.getBody();
}
I have tried a number of different approaches and nothing has made any difference. I tried this for example:
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
I am logging all of the requests in each of my micro-services and it doesn't appear that the requests are actually hitting the other services. They just fail. According to the logs they fail in less than 50 ms so it isn't a timeout issue. For a couple of them I have implemented an exponential back-off retry but that isn't really a viable solution.
I also faced with same problem. Seems like the problem is with idle connections in pool.
This resolve problem in my case and no any error occasionally occurred
HttpClient httpClient = HttpClients
.custom()
.evictIdleConnections(60000, TimeUnit.MILLISECONDS)
.build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

Spring cloud multiple RestTemplate

I am using spring cloud: Spring Boot Application with Eureka + Ribbon default configuration.
I am using 2 RestTemplate configurations, both are #LoadBalanced currently and both of them have the same UriTemplateHandler.
I declared both the #SpringBootApplication and also the #RibbonClient(name="${service.name}") annotations.
My problem is:
When I am trying to access the first configured RestTemplate, the RestTemplate resolvs (by eureka and load balancing by ribbon) to a server , not as I requested as configured in the UriTemplateHandler.
For example: in the UriTemplateHandler I configured "A-Service" and in real time the restTemplate sends the httpRequest to "B-Service"
This behavior happens often, not just for a specific request, but it looks like it only happens when I'm accessing the first configured RestTemplate.
Is it a problem to use 2 RestTemplate with the same uri?
I have no idea why it happens, please advise.
When creating these rest templates as beans, name them uniquely, like e.g.
#LoadBalanced
#Bean("integrationRestTemplate")
public RestTemplate restTemplate() throws Exception {
// build and return your rest template
return ....
}
Then, the other one might be without any specific name e.g.
#Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
Now, if you have these two distinctive rest templates, you can inject the former one e.g. like that:
#Service
public class MyService {
private final RestTemplate restTemplate;
public ApplicantService(#Qualifier("integrationRestTemplate") RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
// service methods
...
}
Basically, the point is you can choose whatever rest template you want, by specifying a #Qualifier.

Spring Rest template weird time out exception

I am using Spring rest template to generate a REST call to a server.
from the application, it returns
I/O error on GET request for "http://XX.XX.XX.XX/v1/api":Connect to XX.XX.XX.XX:80 [/XX.XX.XX.XX] failed: connect timed out"
But if I use the browser I get the DATA perfectly.
This is the configuration:
#Bean
public RestTemplate restTemplate() {
return new RestTemplate(clientHttpRequestFactory());
}
What can be the problem?
Thanks

Resources