001/* 002 * Copyright 2024 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.ApiKeyAuthMethod; 019import com.vonage.client.auth.AuthCollection; 020import com.vonage.client.auth.AuthMethod; 021import com.vonage.client.auth.JWTAuthMethod; 022import org.apache.http.HttpHost; 023import org.apache.http.client.HttpClient; 024import org.apache.http.client.config.RequestConfig; 025import org.apache.http.config.ConnectionConfig; 026import org.apache.http.config.SocketConfig; 027import org.apache.http.impl.client.CloseableHttpClient; 028import org.apache.http.impl.client.HttpClientBuilder; 029import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 030import java.net.URI; 031import java.nio.charset.StandardCharsets; 032import java.util.UUID; 033 034/** 035 * Internal class that holds available authentication methods and a shared HttpClient. 036 */ 037public class HttpWrapper { 038 private static final String 039 CLIENT_NAME = "vonage-java-sdk", 040 CLIENT_VERSION = "8.15.1", 041 JAVA_VERSION = System.getProperty("java.version"), 042 USER_AGENT = String.format("%s/%s java/%s", CLIENT_NAME, CLIENT_VERSION, JAVA_VERSION); 043 044 private AuthCollection authCollection; 045 private CloseableHttpClient httpClient; 046 private HttpConfig httpConfig; 047 048 public HttpWrapper(HttpConfig httpConfig, AuthCollection authCollection) { 049 this.authCollection = authCollection; 050 this.httpConfig = httpConfig; 051 } 052 053 public HttpWrapper(AuthCollection authCollection) { 054 this(HttpConfig.builder().build(), authCollection); 055 } 056 057 public HttpWrapper(AuthMethod... authMethods) { 058 this(HttpConfig.builder().build(), authMethods); 059 } 060 061 public HttpWrapper(HttpConfig httpConfig, AuthMethod... authMethods) { 062 this(httpConfig, new AuthCollection(authMethods)); 063 } 064 065 /** 066 * Gets the underlying {@link HttpClient} instance used by the SDK. 067 * 068 * @return The Apache HTTP client instance. 069 */ 070 public CloseableHttpClient getHttpClient() { 071 if (httpClient == null) { 072 httpClient = createHttpClient(); 073 } 074 return httpClient; 075 } 076 077 /** 078 * Returns the application ID if it was set when creating the client. 079 * 080 * @return The application ID, or {@code null} if unavailable. 081 * @since 8.9.0 082 */ 083 public UUID getApplicationId() { 084 try { 085 return UUID.fromString(getAuthCollection().getAuth(JWTAuthMethod.class).getApplicationId()); 086 } 087 catch (RuntimeException ex) { 088 return null; 089 } 090 } 091 092 /** 093 * Returns the API key if it was set when creating the client. 094 * 095 * @return The API key, or {@code null} if unavailable. 096 * @since 8.9.0 097 */ 098 public String getApiKey() { 099 try { 100 return getAuthCollection().getAuth(ApiKeyAuthMethod.class).getApiKey(); 101 } 102 catch (RuntimeException ex) { 103 return null; 104 } 105 } 106 107 @Deprecated 108 public void setHttpClient(HttpClient httpClient) { 109 this.httpClient = (CloseableHttpClient) httpClient; 110 } 111 112 @Deprecated 113 public void setHttpConfig(HttpConfig httpConfig) { 114 this.httpConfig = httpConfig; 115 } 116 117 /** 118 * Gets the authentication settings used by the client. 119 * 120 * @return The available authentication methods object. 121 */ 122 public AuthCollection getAuthCollection() { 123 return authCollection; 124 } 125 126 @Deprecated 127 public void setAuthCollection(AuthCollection authCollection) { 128 this.authCollection = authCollection; 129 } 130 131 protected CloseableHttpClient createHttpClient() { 132 PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); 133 connectionManager.setDefaultMaxPerRoute(200); 134 connectionManager.setMaxTotal(200); 135 connectionManager.setDefaultConnectionConfig( 136 ConnectionConfig.custom().setCharset(StandardCharsets.UTF_8).build() 137 ); 138 connectionManager.setDefaultSocketConfig(SocketConfig.custom().setTcpNoDelay(true).build()); 139 140 // Need to work out a good value for the following: 141 // threadSafeClientConnManager.setValidateAfterInactivity(); 142 RequestConfig requestConfig = RequestConfig.custom() 143 .setConnectTimeout(httpConfig.getTimeoutMillis()) 144 .setConnectionRequestTimeout(httpConfig.getTimeoutMillis()) 145 .setSocketTimeout(httpConfig.getTimeoutMillis()) 146 .build(); 147 148 HttpClientBuilder clientBuilder = HttpClientBuilder.create() 149 .setConnectionManager(connectionManager) 150 .setUserAgent(getUserAgent()) 151 .setDefaultRequestConfig(requestConfig) 152 .useSystemProperties().disableRedirectHandling(); 153 154 URI proxy = httpConfig.getProxy(); 155 if (proxy != null) { 156 clientBuilder.setProxy(new HttpHost(proxy.getHost(), proxy.getPort(), proxy.getScheme())); 157 } 158 159 return clientBuilder.build(); 160 } 161 162 /** 163 * Gets the HTTP configuration settings for the client. 164 * 165 * @return The request configuration settings object. 166 */ 167 public HttpConfig getHttpConfig() { 168 return httpConfig; 169 } 170 171 /** 172 * Gets the {@code User-Agent} header to be used in HTTP requests. 173 * This includes the Java runtime and SDK version, as well as the custom user agent string, if present. 174 * 175 * @return The user agent string. 176 */ 177 public String getUserAgent() { 178 String ua = USER_AGENT, custom = httpConfig.getCustomUserAgent(); 179 if (custom != null) { 180 ua += " " + httpConfig.getCustomUserAgent(); 181 } 182 return ua; 183 } 184 185 /** 186 * Gets the SDK version. 187 * 188 * @return The SDK version as a string. 189 * @since 8.11.0 190 */ 191 public String getClientVersion() { 192 return CLIENT_VERSION; 193 } 194}