2 * ============LICENSE_START======================================================================
3 * Copyright (C) 2021 Nokia. All rights reserved.
4 * ===============================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
6 * in compliance with the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software distributed under the License
11 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 * or implied. See the License for the specific language governing permissions and limitations under
14 * ============LICENSE_END========================================================================
16 package org.onap.dcaegen2.collectors.datafile.http;
18 import org.apache.http.config.Registry;
19 import org.apache.http.config.RegistryBuilder;
20 import org.apache.http.conn.socket.ConnectionSocketFactory;
21 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
22 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
23 import org.apache.http.ssl.SSLContextBuilder;
24 import org.apache.http.ssl.SSLContexts;
25 import org.onap.dcaegen2.collectors.datafile.commons.SecurityUtil;
26 import org.onap.dcaegen2.collectors.datafile.exceptions.DatafileTaskException;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import org.springframework.core.io.FileSystemResource;
31 import javax.net.ssl.SSLContext;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.nio.file.Paths;
36 import java.security.KeyStore;
37 import java.security.KeyStoreException;
38 import java.security.NoSuchAlgorithmException;
39 import java.security.UnrecoverableKeyException;
40 import java.security.cert.CertificateException;
43 * Utility class supplying connection manager for HTTPS protocol.
45 * @author <a href="mailto:krzysztof.gajewski@nokia.com">Krzysztof Gajewski</a>
47 public class HttpsClientConnectionManagerUtil {
49 private HttpsClientConnectionManagerUtil() {
52 private static final Logger logger = LoggerFactory.getLogger(HttpsClientConnectionManagerUtil.class);
53 //Be aware to be less than ScheduledTasks.NUMBER_OF_WORKER_THREADS
54 private static final int MAX_NUMBER_OF_CONNECTIONS = 200;
55 private static PoolingHttpClientConnectionManager connectionManager;
57 public static PoolingHttpClientConnectionManager instance() throws DatafileTaskException {
58 if (connectionManager == null) {
59 throw new DatafileTaskException("ConnectionManager has to be set or update first");
61 return connectionManager;
64 public static void setupOrUpdate(String keyCertPath, String keyCertPasswordPath, String trustedCaPath,
65 String trustedCaPasswordPath) throws DatafileTaskException {
66 synchronized (HttpsClientConnectionManagerUtil.class) {
67 if (connectionManager != null) {
68 connectionManager.close();
69 connectionManager = null;
71 setup(keyCertPath, keyCertPasswordPath, trustedCaPath, trustedCaPasswordPath);
73 logger.trace("HttpsConnectionManager setup or updated");
76 private static void setup(String keyCertPath, String keyCertPasswordPath, String trustedCaPath,
77 String trustedCaPasswordPath) throws DatafileTaskException {
79 SSLContextBuilder sslBuilder = SSLContexts.custom();
80 sslBuilder = supplyKeyInfo(keyCertPath, keyCertPasswordPath, sslBuilder);
81 sslBuilder = supplyTrustInfo(trustedCaPath, trustedCaPasswordPath, sslBuilder);
83 SSLContext sslContext = sslBuilder.build();
85 SSLConnectionSocketFactory sslConnectionSocketFactory =
86 new SSLConnectionSocketFactory(sslContext, new String[] {"TLSv1.2"}, null,
87 (hostname, session) -> true);
89 Registry<ConnectionSocketFactory> socketFactoryRegistry =
90 RegistryBuilder.<ConnectionSocketFactory>create().register("https", sslConnectionSocketFactory)
93 connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
94 connectionManager.setMaxTotal(MAX_NUMBER_OF_CONNECTIONS);
96 } catch (Exception e) {
97 throw new DatafileTaskException("Unable to prepare HttpsConnectionManager : ", e);
101 private static SSLContextBuilder supplyKeyInfo(String keyCertPath, String keyCertPasswordPath,
102 SSLContextBuilder sslBuilder)
103 throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException,
104 UnrecoverableKeyException {
105 String keyPass = SecurityUtil.getKeystorePasswordFromFile(keyCertPasswordPath);
106 KeyStore keyFile = createKeyStore(keyCertPath, keyPass);
107 return sslBuilder.loadKeyMaterial(keyFile, keyPass.toCharArray());
110 private static KeyStore createKeyStore(String trustedCaPath, String trustedCaPassword)
111 throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
112 logger.trace("Creating trust manager from file: {}", trustedCaPath);
113 try (InputStream fis = createInputStream(trustedCaPath)) {
114 KeyStore keyStore = KeyStore.getInstance("PKCS12");
115 keyStore.load(fis, trustedCaPassword.toCharArray());
120 private static InputStream createInputStream(String localFileName) throws IOException {
121 FileSystemResource realResource = new FileSystemResource(Paths.get(localFileName));
122 return realResource.getInputStream();
125 private static SSLContextBuilder supplyTrustInfo(String trustedCaPath, String trustedCaPasswordPath,
126 SSLContextBuilder sslBuilder)
127 throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
128 String trustPass = SecurityUtil.getTruststorePasswordFromFile(trustedCaPasswordPath);
129 File trustStoreFile = new File(trustedCaPath);
130 return sslBuilder.loadTrustMaterial(trustStoreFile, trustPass.toCharArray());