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");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.dcaegen2.collectors.datafile.service.producer;
23 import java.nio.charset.StandardCharsets;
24 import java.security.KeyManagementException;
25 import java.security.KeyStoreException;
26 import java.security.NoSuchAlgorithmException;
27 import java.time.Duration;
29 import java.util.concurrent.Future;
31 import javax.net.ssl.SSLContext;
33 import org.apache.commons.codec.binary.Base64;
34 import org.apache.http.HttpResponse;
35 import org.apache.http.client.config.RequestConfig;
36 import org.apache.http.client.methods.HttpUriRequest;
37 import org.apache.http.conn.ssl.NoopHostnameVerifier;
38 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
39 import org.apache.http.ssl.SSLContextBuilder;
40 import org.onap.dcaegen2.collectors.datafile.exceptions.DatafileTaskException;
41 import org.onap.dcaegen2.collectors.datafile.http.HttpAsyncClientBuilderWrapper;
42 import org.onap.dcaegen2.collectors.datafile.web.PublishRedirectStrategy;
43 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
47 import org.slf4j.Marker;
48 import org.slf4j.MarkerFactory;
51 * Client used to send requests to DataRouter.
53 * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 7/4/18
54 * @author <a href="mailto:henrik.b.andersson@est.tech">Henrik Andersson</a>
56 public class DmaapProducerHttpClient {
58 private static final Duration DEFAULT_REQUEST_TIMEOUT = Duration.ofMinutes(2);
59 private static final Marker INVOKE = MarkerFactory.getMarker("INVOKE");
60 private static final Marker INVOKE_RETURN = MarkerFactory.getMarker("INVOKE_RETURN");
62 private final Logger logger = LoggerFactory.getLogger(this.getClass());
64 private final DmaapPublisherConfiguration configuration;
67 * Constructor DmaapProducerReactiveHttpClient.
69 * @param dmaapPublisherConfiguration - DMaaP producer configuration object
71 public DmaapProducerHttpClient(DmaapPublisherConfiguration dmaapPublisherConfiguration) {
72 this.configuration = dmaapPublisherConfiguration;
76 * Executes the given request and handles redirects.
78 * @param request the request to execute.
79 * @param contextMap context for logging.
81 * @return the response from the request.
83 * @throws DatafileTaskException if anything goes wrong.
85 public HttpResponse getDmaapProducerResponseWithRedirect(HttpUriRequest request, Map<String, String> contextMap)
86 throws DatafileTaskException {
87 MDC.setContextMap(contextMap);
88 try (CloseableHttpAsyncClient webClient = createWebClient(true, DEFAULT_REQUEST_TIMEOUT, contextMap)) {
91 logger.trace(INVOKE, "Starting to produce to DR {}", request);
92 Future<HttpResponse> future = webClient.execute(request, null);
93 HttpResponse response = future.get();
94 logger.trace(INVOKE_RETURN, "Response from DR {}", response);
96 } catch (Exception e) {
97 throw new DatafileTaskException("Unable to create web client.", e);
102 * Executes the given request using the given timeout time.
104 * @param request the request to execute.
105 * @param requestTimeout the timeout time for the request.
106 * @param contextMap context for logging.
108 * @return the response from the request.
110 * @throws DatafileTaskException if anything goes wrong.
112 public HttpResponse getDmaapProducerResponseWithCustomTimeout(HttpUriRequest request, Duration requestTimeout,
113 Map<String, String> contextMap) throws DatafileTaskException {
114 MDC.setContextMap(contextMap);
115 try (CloseableHttpAsyncClient webClient = createWebClient(false, requestTimeout, contextMap)) {
118 logger.trace(INVOKE, "Starting to produce to DR {}", request);
119 Future<HttpResponse> future = webClient.execute(request, null);
120 HttpResponse response = future.get();
121 logger.trace(INVOKE_RETURN, "Response from DR {}", response);
123 } catch (Exception e) {
124 throw new DatafileTaskException("Unable to create web client.", e);
129 * Adds the user credentials needed to talk to DataRouter to the provided request.
131 * @param request the request to add credentials to.
133 public void addUserCredentialsToHead(HttpUriRequest request) {
134 String plainCreds = configuration.dmaapUserName() + ":" + configuration.dmaapUserPassword();
135 byte[] plainCredsBytes = plainCreds.getBytes(StandardCharsets.ISO_8859_1);
136 byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
137 String base64Creds = new String(base64CredsBytes);
138 logger.trace("base64Creds...: {}", base64Creds);
139 request.addHeader("Authorization", "Basic " + base64Creds);
142 private CloseableHttpAsyncClient createWebClient(boolean expectRedirect, Duration requestTimeout,
143 Map<String, String> contextMap) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
144 SSLContext sslContext =
145 new SSLContextBuilder().loadTrustMaterial(null, (certificate, authType) -> true).build();
147 HttpAsyncClientBuilderWrapper clientBuilder = getHttpClientBuilder();
148 clientBuilder.setSslContext(sslContext) //
149 .setSslHostnameVerifier(new NoopHostnameVerifier());
151 if (expectRedirect) {
152 clientBuilder.setRedirectStrategy(new PublishRedirectStrategy(contextMap));
155 if (requestTimeout.toMillis() > 0) {
156 int millis = (int) requestTimeout.toMillis();
157 RequestConfig requestConfig = RequestConfig.custom() //
158 .setSocketTimeout(millis) //
159 .setConnectTimeout(millis) //
160 .setConnectionRequestTimeout(millis) //
163 clientBuilder.setDefaultRequestConfig(requestConfig);
165 logger.error("WEB client without timeout created {}", requestTimeout);
168 return clientBuilder.build();
171 HttpAsyncClientBuilderWrapper getHttpClientBuilder() {
172 return new HttpAsyncClientBuilderWrapper();