Sync Integ to Master
[sdc.git] / common-app-api / src / main / java / org / openecomp / sdc / common / http / client / api / HttpConnectionMngFactory.java
1 package org.openecomp.sdc.common.http.client.api;
2
3 import java.io.FileInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.security.GeneralSecurityException;
7 import java.security.KeyStore;
8 import java.util.Map;
9 import java.util.concurrent.ConcurrentHashMap;
10
11 import org.apache.commons.lang3.StringUtils;
12 import org.apache.http.config.Registry;
13 import org.apache.http.config.RegistryBuilder;
14 import org.apache.http.conn.HttpClientConnectionManager;
15 import org.apache.http.conn.socket.ConnectionSocketFactory;
16 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
17 import org.apache.http.conn.ssl.NoopHostnameVerifier;
18 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
19 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
20 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
21 import org.apache.http.ssl.SSLContextBuilder;
22 import org.openecomp.sdc.common.api.Constants;
23 import org.openecomp.sdc.common.http.config.ClientCertificate;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 public class HttpConnectionMngFactory {
28
29     private static final String P12_KEYSTORE_EXTENTION = ".p12";
30     private static final String PFX_KEYSTORE_EXTENTION = ".pfx";
31     private static final String JKS_KEYSTORE_EXTENTION = ".jks";
32     
33     private static final String P12_KEYSTORE_TYPE = "pkcs12";
34     private static final String JKS_KEYSTORE_TYPE = "jks";
35     
36     private static final Logger logger = LoggerFactory.getLogger(HttpConnectionMngFactory.class);
37     private static final int DEFAULT_CONNECTION_POOL_SIZE = 30;
38     private static final int DEFAULT_MAX_CONNECTION_PER_ROUTE = 5;
39     private static final int VALIDATE_CONNECTION_AFTER_INACTIVITY_MS = 10000;
40     
41     private Map<ClientCertificate, HttpClientConnectionManager> sslClientConnectionManagers = new ConcurrentHashMap<>();
42     private HttpClientConnectionManager plainClientConnectionManager;
43     
44     HttpConnectionMngFactory() {
45         plainClientConnectionManager = createConnectionMng(null);
46     }
47
48     HttpClientConnectionManager getOrCreate(ClientCertificate clientCertificate) {
49         if(clientCertificate == null) {
50             return plainClientConnectionManager;
51         }
52         return sslClientConnectionManagers.computeIfAbsent(clientCertificate, k -> createConnectionMng(clientCertificate));
53     }
54     
55     private HttpClientConnectionManager createConnectionMng(ClientCertificate clientCertificate) {
56
57         SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
58         SSLConnectionSocketFactory sslsf = null;
59         try {
60             sslContextBuilder.loadTrustMaterial(new TrustSelfSignedStrategy());
61             
62             if(clientCertificate != null) {
63                 setClientSsl(clientCertificate, sslContextBuilder);
64             }
65             sslsf = new SSLConnectionSocketFactory(sslContextBuilder.build(), NoopHostnameVerifier.INSTANCE);
66         }
67         catch (GeneralSecurityException e) {
68             logger.debug("Create SSL connection socket factory failed with exception, use default SSL factory ", e);
69             sslsf = SSLConnectionSocketFactory.getSocketFactory();
70         }
71
72         Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
73                 .register(Constants.HTTP, PlainConnectionSocketFactory.getSocketFactory())
74                 .register(Constants.HTTPS, sslsf).build();
75
76         PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(registry);
77
78         manager.setMaxTotal(DEFAULT_CONNECTION_POOL_SIZE);
79         manager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTION_PER_ROUTE);
80         manager.setValidateAfterInactivity(VALIDATE_CONNECTION_AFTER_INACTIVITY_MS);
81
82         return manager;
83     }
84
85     private void setClientSsl(ClientCertificate clientCertificate, SSLContextBuilder sslContextBuilder) {
86         try {
87             char[] keyStorePassword = clientCertificate.getKeyStorePassword().toCharArray();
88             KeyStore clientKeyStore = createClientKeyStore(clientCertificate.getKeyStore(), keyStorePassword);
89             sslContextBuilder.loadKeyMaterial(clientKeyStore, keyStorePassword);
90             logger.debug("#setClientSsl - Set Client Certificate authentication");
91         }
92         catch (IOException | GeneralSecurityException e) {
93             logger.debug("#setClientSsl - Set Client Certificate authentication failed with exception, diasable client SSL authentication ", e);
94         }
95     }
96         
97     private KeyStore createClientKeyStore(String keyStorePath, char[] keyStorePassword) throws IOException, GeneralSecurityException {
98         KeyStore keyStore = null;
99         try (InputStream stream = new FileInputStream(keyStorePath)) {
100             keyStore = KeyStore.getInstance(getKeyStoreType(keyStorePath));
101             keyStore.load(stream, keyStorePassword);
102         }
103         return keyStore;
104     }
105     
106     private String getKeyStoreType(String keyStore) {
107         if(!StringUtils.isEmpty(keyStore)) {
108             if(keyStore.endsWith(P12_KEYSTORE_EXTENTION) || keyStore.endsWith(PFX_KEYSTORE_EXTENTION)) {
109                 return P12_KEYSTORE_TYPE;
110             }
111             else if(keyStore.endsWith(JKS_KEYSTORE_EXTENTION)) {
112                 return JKS_KEYSTORE_TYPE;
113             }            
114         }
115         return KeyStore.getDefaultType();
116     }
117 }