All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.symphony.bdk.http.jersey2.ApiClientBuilderJersey2 Maven / Gradle / Ivy

There is a newer version: 3.1.0
Show newest version
package com.symphony.bdk.http.jersey2;

import static com.symphony.bdk.http.api.util.ApiUtils.addDefaultRootCaCertificates;
import static org.apache.commons.lang3.ObjectUtils.isNotEmpty;

import com.symphony.bdk.http.api.ApiClient;
import com.symphony.bdk.http.api.ApiClientBuilder;
import com.symphony.bdk.http.api.auth.Authentication;
import com.symphony.bdk.http.api.util.ApiUtils;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apiguardian.api.API;
import org.glassfish.jersey.SslConfigurator;
import org.glassfish.jersey.apache.connector.ApacheClientProperties;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.SSLContext;

/**
 * Specific implementation of {@link ApiClientBuilder} which creates a new instance of an {@link ApiClientJersey2}.
 *
 * 

Please note that overriding this class is an {@link org.apiguardian.api.API.Status#EXPERIMENTAL} feature that we * offer to developers for {@link ApiClient} customization. The internal contract of this class (e.g. protected methods) * is subject to changes in the future. */ @API(status = API.Status.STABLE) public class ApiClientBuilderJersey2 implements ApiClientBuilder { private static final String TRUSTSTORE_FORMAT = "JKS"; protected String basePath; protected byte[] keyStoreBytes; protected String keyStorePassword; protected byte[] trustStoreBytes; protected String trustStorePassword; protected Map defaultHeaders; protected int connectionTimeout; protected int readTimeout; protected int connectionPoolMax; protected int connectionPoolPerRoute; protected String temporaryFolderPath; protected String proxyUrl; protected String proxyUser; protected String proxyPassword; protected Map authentications; public ApiClientBuilderJersey2() { this.basePath = "https://acme.symphony.com"; this.keyStoreBytes = null; this.keyStorePassword = null; this.trustStoreBytes = null; this.trustStorePassword = null; this.defaultHeaders = new HashMap<>(); this.connectionTimeout = DEFAULT_CONNECT_TIMEOUT; this.readTimeout = DEFAULT_READ_TIMEOUT; this.connectionPoolMax = DEFAULT_CONNECTION_POOL_MAX; this.connectionPoolPerRoute = DEFAULT_CONNECTION_POOL_MAX; this.temporaryFolderPath = null; this.proxyUrl = null; this.proxyUser = null; this.proxyPassword = null; this.authentications = new HashMap<>(); this.withUserAgent(ApiUtils.getUserAgent()); } /** * Specific implementation of {@link ApiClientBuilder#build()} which returns an {@link ApiClientJersey2} instance. */ @Override public ApiClient build() { java.util.logging.Logger.getLogger("org.glassfish.jersey.client").setLevel(java.util.logging.Level.SEVERE); SSLContext sslContext = this.createSSLContext(); final Client httpClient = ClientBuilder.newBuilder() .sslContext(sslContext) .withConfig(this.createClientConfig(sslContext)) .build(); httpClient.property(ClientProperties.CONNECT_TIMEOUT, this.connectionTimeout); httpClient.property(ClientProperties.READ_TIMEOUT, this.readTimeout); final ApiClient apiClient = new ApiClientJersey2(httpClient, this.basePath, this.defaultHeaders, this.temporaryFolderPath); this.authentications.forEach(apiClient.getAuthentications()::put); return apiClient; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withBasePath(String basePath) { this.basePath = basePath; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withUserAgent(String userAgent) { this.withDefaultHeader("User-Agent", userAgent); return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withKeyStore(byte[] keyStoreBytes, String keyStorePassword) { this.keyStoreBytes = keyStoreBytes; this.keyStorePassword = keyStorePassword; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withTrustStore(byte[] trustStoreBytes, String trustStorePassword) { this.trustStoreBytes = trustStoreBytes; this.trustStorePassword = trustStorePassword; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withDefaultHeader(String key, String value) { this.defaultHeaders.put(key, value); return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withTemporaryFolderPath(String temporaryFolderPath) { this.temporaryFolderPath = temporaryFolderPath; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withConnectionTimeout(Integer connectionTimeout) { this.connectionTimeout = connectionTimeout == null ? DEFAULT_CONNECT_TIMEOUT : connectionTimeout; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withReadTimeout(Integer readTimeout) { this.readTimeout = readTimeout == null ? DEFAULT_READ_TIMEOUT : readTimeout; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withConnectionPoolMax(Integer connectionPoolMax) { this.connectionPoolMax = connectionPoolMax == null ? DEFAULT_CONNECTION_POOL_MAX : connectionPoolMax; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withConnectionPoolPerRoute(Integer connectionPoolPerRoute) { this.connectionPoolPerRoute = connectionPoolPerRoute == null ? DEFAULT_CONNECTION_POOL_MAX : connectionPoolPerRoute; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withProxy(String proxyHost, int proxyPort) { this.proxyUrl = proxyHost != null ? "http://" + proxyHost + ":" + proxyPort : null; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withProxyCredentials(String proxyUser, String proxyPassword) { this.proxyUser = proxyUser; this.proxyPassword = proxyPassword; return this; } /** * {@inheritDoc} */ @Override public ApiClientBuilder withAuthentication(String name, Authentication authentication) { this.authentications.put(name, authentication); return this; } @API(status = API.Status.EXPERIMENTAL) protected ClientConfig createClientConfig(SSLContext sslContext) { final ClientConfig clientConfig = new ClientConfig(); this.configureJackson(clientConfig); if (this.proxyUrl != null) { this.configureProxy(clientConfig); } clientConfig.register(ApiClientJersey2RequestLogFilter.class); clientConfig.register(MultiPartFeature.class); clientConfig.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true); // turn off compliance validation to be able to send payloads with DELETE calls clientConfig.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true); SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext); Registry registry = RegistryBuilder.create() .register("https", sslConnectionSocketFactory) .register("http", new PlainConnectionSocketFactory()) .build(); // By default PoolingHttpClientConnectionManager, if not configured, has 20 connection in the // pool BUT only 2 max connection per route. final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); connectionManager.setMaxTotal(this.connectionPoolMax); connectionManager.setDefaultMaxPerRoute(this.connectionPoolPerRoute); clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager); clientConfig.connectorProvider(new ApacheConnectorProvider()); return clientConfig; } @API(status = API.Status.EXPERIMENTAL) protected void configureJackson(ClientConfig clientConfig) { clientConfig.register(new JSON()); clientConfig.register(JacksonFeature.class); } @API(status = API.Status.EXPERIMENTAL) protected void configureProxy(ClientConfig clientConfig) { clientConfig.property(ClientProperties.PROXY_URI, proxyUrl); clientConfig.property(ClientProperties.PROXY_USERNAME, proxyUser); clientConfig.property(ClientProperties.PROXY_PASSWORD, proxyPassword); } @API(status = API.Status.EXPERIMENTAL) protected SSLContext createSSLContext() { try { final SslConfigurator sslConfig = SslConfigurator.newInstance(); if (isNotEmpty(trustStoreBytes) && isNotEmpty(trustStorePassword)) { final KeyStore truststore = KeyStore.getInstance(TRUSTSTORE_FORMAT); truststore.load(new ByteArrayInputStream(trustStoreBytes), trustStorePassword.toCharArray()); addDefaultRootCaCertificates(truststore); sslConfig.trustStore(truststore); ApiUtils.logTrustStore(truststore); } if (isNotEmpty(keyStoreBytes) && isNotEmpty(keyStorePassword)) { sslConfig .keyStoreBytes(keyStoreBytes) .keyStorePassword(keyStorePassword); } return sslConfig.createSSLContext(); } catch (IOException | GeneralSecurityException e) { throw new IllegalStateException(e.getCause().getMessage(), e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy