b0904b29563a94ab8743cd3f41434272cdaa03a7
[dcaegen2/collectors/datafile.git] /
1 /*
2  * ============LICENSE_START======================================================================
3  * Copyright (C) 2018 NOKIA Intellectual Property, 2018-2019 Nordix Foundation. 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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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
13  * the License.
14  * ============LICENSE_END========================================================================
15  */
16
17 package org.onap.dcaegen2.collectors.datafile.service.producer;
18
19 import java.nio.charset.StandardCharsets;
20 import java.security.KeyManagementException;
21 import java.security.KeyStoreException;
22 import java.security.NoSuchAlgorithmException;
23 import java.time.Duration;
24 import java.util.Map;
25 import java.util.concurrent.Future;
26
27 import javax.net.ssl.SSLContext;
28
29 import org.apache.commons.codec.binary.Base64;
30 import org.apache.http.HttpResponse;
31 import org.apache.http.client.config.RequestConfig;
32 import org.apache.http.client.methods.HttpUriRequest;
33 import org.apache.http.conn.ssl.NoopHostnameVerifier;
34 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
35 import org.apache.http.ssl.SSLContextBuilder;
36 import org.onap.dcaegen2.collectors.datafile.exceptions.DatafileTaskException;
37 import org.onap.dcaegen2.collectors.datafile.http.HttpAsyncClientBuilderWrapper;
38 import org.onap.dcaegen2.collectors.datafile.http.IHttpAsyncClientBuilder;
39 import org.onap.dcaegen2.collectors.datafile.web.PublishRedirectStrategy;
40 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.slf4j.MDC;
44 import org.slf4j.Marker;
45 import org.slf4j.MarkerFactory;
46 import org.springframework.web.util.DefaultUriBuilderFactory;
47 import org.springframework.web.util.UriBuilder;
48
49 /**
50  * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 7/4/18
51  * @author <a href="mailto:henrik.b.andersson@est.tech">Henrik Andersson</a>
52  */
53 public class DmaapProducerHttpClient {
54
55     private static final Duration DEFAULT_REQUEST_TIMEOUT = Duration.ofMinutes(2);
56     private static final Marker INVOKE = MarkerFactory.getMarker("INVOKE");
57     private static final Marker INVOKE_RETURN = MarkerFactory.getMarker("INVOKE_RETURN");
58
59     private final Logger logger = LoggerFactory.getLogger(this.getClass());
60
61     private final DmaapPublisherConfiguration configuration;
62
63     /**
64      * Constructor DmaapProducerReactiveHttpClient.
65      *
66      * @param dmaapPublisherConfiguration - DMaaP producer configuration object
67      */
68     public DmaapProducerHttpClient(DmaapPublisherConfiguration dmaapPublisherConfiguration) {
69         this.configuration = dmaapPublisherConfiguration;
70     }
71
72     public HttpResponse getDmaapProducerResponseWithRedirect(HttpUriRequest request, Map<String, String> contextMap)
73             throws DatafileTaskException {
74         MDC.setContextMap(contextMap);
75         try (CloseableHttpAsyncClient webClient = createWebClient(true, DEFAULT_REQUEST_TIMEOUT)) {
76             webClient.start();
77
78             logger.trace(INVOKE, "Starting to produce to DR {}", request);
79             Future<HttpResponse> future = webClient.execute(request, null);
80             HttpResponse response = future.get();
81             logger.trace(INVOKE_RETURN, "Response from DR {}", response);
82             return response;
83         } catch (Exception e) {
84             throw new DatafileTaskException("Unable to create web client.", e);
85         }
86     }
87
88     public HttpResponse getDmaapProducerResponseWithCustomTimeout(HttpUriRequest request, Duration requestTimeout,
89             Map<String, String> contextMap) throws DatafileTaskException {
90         MDC.setContextMap(contextMap);
91         try (CloseableHttpAsyncClient webClient = createWebClient(false, requestTimeout)) {
92             webClient.start();
93
94             logger.trace(INVOKE, "Starting to produce to DR {}", request);
95             Future<HttpResponse> future = webClient.execute(request, null);
96             HttpResponse response = future.get();
97             logger.trace(INVOKE_RETURN, "Response from DR {}", response);
98             return response;
99         } catch (Exception e) {
100             throw new DatafileTaskException("Unable to create web client.", e);
101         }
102     }
103
104     public void addUserCredentialsToHead(HttpUriRequest request) {
105         String plainCreds = configuration.dmaapUserName() + ":" + configuration.dmaapUserPassword();
106         byte[] plainCredsBytes = plainCreds.getBytes(StandardCharsets.ISO_8859_1);
107         byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
108         String base64Creds = new String(base64CredsBytes);
109         logger.trace("base64Creds...: {}", base64Creds);
110         request.addHeader("Authorization", "Basic " + base64Creds);
111     }
112
113     public UriBuilder getBaseUri() {
114         return new DefaultUriBuilderFactory().builder() //
115                 .scheme(configuration.dmaapProtocol()) //
116                 .host(configuration.dmaapHostName()) //
117                 .port(configuration.dmaapPortNumber());
118     }
119
120     private CloseableHttpAsyncClient createWebClient(boolean expectRedirect, Duration requestTimeout)
121             throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
122         SSLContext sslContext =
123                 new SSLContextBuilder().loadTrustMaterial(null, (certificate, authType) -> true).build();
124
125         IHttpAsyncClientBuilder clientBuilder = getHttpClientBuilder();
126         clientBuilder.setSSLContext(sslContext) //
127                 .setSSLHostnameVerifier(new NoopHostnameVerifier());
128
129         if (expectRedirect) {
130             clientBuilder.setRedirectStrategy(PublishRedirectStrategy.INSTANCE);
131         }
132
133         if (requestTimeout.toMillis() > 0) {
134             int millis = (int)requestTimeout.toMillis();
135             RequestConfig requestConfig = RequestConfig.custom() //
136                     .setSocketTimeout(millis) //
137                     .setConnectTimeout(millis) //
138                     .setConnectionRequestTimeout(millis) //
139                     .build();
140
141             clientBuilder.setDefaultRequestConfig(requestConfig);
142         } else {
143             logger.error("WEB client without timeout created {}", requestTimeout);
144         }
145
146         return clientBuilder.build();
147     }
148
149     IHttpAsyncClientBuilder getHttpClientBuilder() {
150         return new HttpAsyncClientBuilderWrapper();
151     }
152 }