Skip to content

Configure RestTemplate to hava a time-live in the connection pool #142

@oharsta

Description

@oharsta

Recommended is to add a @Bean and only use the Builder pattern to instantiate the RestTemplate. Example code:

import org.apache.hc.client5.http.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplateBuilder restTemplateBuilder() {
        // Create connection manager with a TTL of 30 seconds
        PoolingHttpClientConnectionManager connectionManager =
                PoolingHttpClientConnectionManagerBuilder.create()
                        .setConnectionTimeToLive(30, TimeUnit.SECONDS)
                        .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .evictExpiredConnections() // evict connections past TTL
                .evictIdleConnections(Duration.ofSeconds(30)) // optional
                .build();

        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory(httpClient);

        return new RestTemplateBuilder()
                .requestFactory(() -> requestFactory);
    }

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
}

Check all of the occurrences below:

~/projects$ grep -rin 'new RestTemplate(' . --include='*java'
./oidc-playground/oidc-playground-server/src/main/java/playground/api/Oidc.java:137:        this.restTemplate = new RestTemplate();
./access/server/src/main/java/access/jira/JiraClient.java:35:    private final RestTemplate restTemplate = new RestTemplate();
./access/server/src/main/java/access/manage/RemoteManage.java:39:            Environment.TEST, new RestTemplate(
./access/server/src/main/java/access/manage/RemoteManage.java:42:            Environment.PROD, new RestTemplate(
./attribute-aggregation/src/main/java/aa/aggregators/AbstractAttributeAggregator.java:63:        RestTemplate restTemplate = new RestTemplate(getRequestFactory(attributeAuthorityConfiguration));
./attribute-aggregation/src/main/java/aa/aggregators/entitlements/EntitlementsAggregator.java:40:        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
./attribute-aggregation/src/main/java/aa/control/AccountController.java:59:    private final RestTemplate restTemplate = new RestTemplate();
./student-mobility/student-mobility-inteken-ontvanger-generiek/src/main/java/generiek/ServiceRegistry.java:29:        this.restTemplate = new RestTemplate(new OkHttp3ClientHttpRequestFactory(builder.build()));
./student-mobility/student-mobility-inteken-ontvanger-generiek/src/main/java/generiek/api/EnrollmentEndpoint.java:135:        this.restTemplate = new RestTemplate(requestFactory);
./student-mobility/student-mobility-broker/server/src/main/java/broker/api/BrokerController.java:118:        this.restTemplate = new RestTemplate(getClientHttpRequestFactory(connectionTimeoutMillis));
./myconext/myconext-server/src/main/java/myconext/sms/SMSServiceImpl.java:30:    private final RestTemplate restTemplate = new RestTemplate();
./myconext/myconext-server/src/main/java/myconext/captcha/CaptchaVerifier.java:30:        this.restTemplate = new RestTemplate();
./myconext/myconext-server/src/main/java/myconext/api/AccountLinkerController.java:105:    private final RestTemplate restTemplate = new RestTemplate();
./myconext/myconext-server/src/main/java/myconext/manage/RemoteManage.java:23:    private final RestTemplate restTemplate = new RestTemplate();
./myconext/myconext-server/src/main/java/myconext/oidcng/OpenIDConnectRemote.java:37:        this.restTemplate = new RestTemplate();
./myconext/tiqr-mock/src/main/java/tiqr/org/TiqrEndpoint.java:52:        this.restTemplate = new RestTemplate();
./invite/server/src/test/java/invite/security/IgnoreMeTest.java:44:        RestTemplate restTemplate = new RestTemplate();
./invite/server/src/main/java/invite/provision/ProvisioningServiceDefault.java:53:    private final RestTemplate restTemplate = new RestTemplate();
./invite/server/src/main/java/invite/manage/RemoteManage.java:27:    private final RestTemplate restTemplate = new RestTemplate();
./invite/server/src/main/java/invite/eduid/EduID.java:27:        this.restTemplate = new RestTemplate();
./OpenConext-pdp/src/main/java/pdp/sab/SabClient.java:31:        this.restTemplate = new RestTemplate();
./OpenConext-pdp/src/main/java/pdp/manage/UrlResourceManage.java:31:    private final RestTemplate restTemplate = new RestTemplate();
./voot/src/main/java/voot/provider/AbstractProvider.java:48:        this.restTemplate = new RestTemplate(getRequestFactory());
./teams/teams-server/src/main/java/teams/api/InviteController.java:31:    private final RestTemplate restTemplate = new RestTemplate();
./idp-dashboard/dashboard-server/src/main/java/dashboard/sab/SabRest.java:31:        this.restTemplate = new RestTemplate();
./idp-dashboard/dashboard-server/src/main/java/dashboard/manage/UrlResourceManage.java:29:    private final RestTemplate restTemplate = new RestTemplate();
./idp-dashboard/dashboard-server/src/main/java/dashboard/service/impl/JiraClientImpl.java:90:        this.restTemplate = new RestTemplate();
./idp-dashboard/dashboard-server/src/main/java/dashboard/pdp/PdpServiceImpl.java:49:        this.pdpRestTemplate = new RestTemplate(clientHttpRequestFactory(10 * 1000));
./idp-dashboard/dashboard-server/src/main/java/dashboard/stats/StatsImpl.java:26:        this.restTemplate = new RestTemplate(clientHttpRequestFactory(10 * 1000));
./manage/manage-server/src/main/java/manage/control/PdPController.java:35:        this.pdpRestTemplate = new RestTemplate();
./monitoring/src/main/java/monitoring/eb/MetadataMonitor.java:33:        this.restTemplate = new RestTemplate();
./oidcng/oidc/src/main/java/oidc/eduid/AttributePseudonymisation.java:34:        this.restTemplate = new RestTemplate();

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions