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