001/*
002 *   Copyright 2020 Vonage
003 *
004 *   Licensed under the Apache License, Version 2.0 (the "License");
005 *   you may not use this file except in compliance with the License.
006 *   You may obtain a copy of the License at
007 *
008 *        http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *   Unless required by applicable law or agreed to in writing, software
011 *   distributed under the License is distributed on an "AS IS" BASIS,
012 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *   See the License for the specific language governing permissions and
014 *   limitations under the License.
015 */
016package com.vonage.client;
017
018import com.vonage.client.auth.AuthCollection;
019import com.vonage.client.auth.AuthMethod;
020import org.apache.http.client.HttpClient;
021import org.apache.http.client.config.RequestConfig;
022import org.apache.http.config.ConnectionConfig;
023import org.apache.http.config.SocketConfig;
024import org.apache.http.impl.client.HttpClientBuilder;
025import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
026
027import java.nio.charset.Charset;
028
029/**
030 * Internal class that holds available authentication methods and a shared HttpClient.
031 */
032public class HttpWrapper {
033    private static final String CLIENT_NAME = "vonage-java-sdk";
034    private static final String CLIENT_VERSION = "5.5.0";
035    private static final String JAVA_VERSION = System.getProperty("java.version");
036
037    private AuthCollection authCollection;
038    private HttpClient httpClient = null;
039    private HttpConfig httpConfig;
040
041    public HttpWrapper(AuthCollection authCollection) {
042        this(HttpConfig.builder().build(), authCollection);
043    }
044
045    public HttpWrapper(HttpConfig httpConfig, AuthCollection authCollection) {
046        this.authCollection = authCollection;
047        this.httpConfig = httpConfig;
048    }
049
050    public HttpWrapper(AuthMethod... authMethods) {
051        this(HttpConfig.builder().build(), authMethods);
052    }
053
054    public HttpWrapper(HttpConfig httpConfig, AuthMethod... authMethods) {
055        this(new AuthCollection());
056        for (AuthMethod authMethod : authMethods) {
057            authCollection.add(authMethod);
058        }
059
060        this.httpConfig = httpConfig;
061    }
062
063    public HttpClient getHttpClient() {
064        if (this.httpClient == null) {
065            this.httpClient = createHttpClient();
066        }
067        return this.httpClient;
068    }
069
070    public void setHttpClient(HttpClient httpClient) {
071        this.httpClient = httpClient;
072    }
073
074    public AuthCollection getAuthCollection() {
075        return authCollection;
076    }
077
078    public void setAuthCollection(AuthCollection authCollection) {
079        this.authCollection = authCollection;
080    }
081
082    protected HttpClient createHttpClient() {
083        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
084        connectionManager.setDefaultMaxPerRoute(200);
085        connectionManager.setMaxTotal(200);
086        connectionManager.setDefaultConnectionConfig(ConnectionConfig
087                .custom()
088                .setCharset(Charset.forName("UTF-8"))
089                .build());
090        connectionManager.setDefaultSocketConfig(SocketConfig.custom().setTcpNoDelay(true).build());
091
092        // Need to work out a good value for the following:
093        // threadSafeClientConnManager.setValidateAfterInactivity();
094
095        RequestConfig requestConfig = RequestConfig.custom().build();
096
097        return HttpClientBuilder
098                .create()
099                .setConnectionManager(connectionManager)
100                .setUserAgent(String.format("%s/%s java/%s", CLIENT_NAME, CLIENT_VERSION, JAVA_VERSION))
101                .setDefaultRequestConfig(requestConfig)
102                .useSystemProperties()
103                .build();
104    }
105
106    public HttpConfig getHttpConfig() {
107        return httpConfig;
108    }
109}