Improve code quality 99/115299/6
authorBogumil Zebek <bogumil.zebek@nokia.com>
Tue, 24 Nov 2020 11:56:32 +0000 (12:56 +0100)
committerZebek Bogumil <bogumil.zebek@nokia.com>
Wed, 2 Dec 2020 12:20:29 +0000 (13:20 +0100)
- fix sonars
- remove potential NullPointerException when HttpClient cannot be created for SSL
- extract code to separate classes

Issue-ID: SDC-3388
Signed-off-by: Zebek Bogumil <bogumil.zebek@nokia.com>
Change-Id: Ic42bc638fddf83a4f3e1944bedf3cc2b92012e5e

pom.xml
sdc-distribution-client/pom.xml
sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClient.java
sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClientException.java [new file with mode: 0644]
sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpClientFactory.java [new file with mode: 0644]
sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpRequestFactory.java [new file with mode: 0644]
sdc-distribution-client/src/main/java/org/onap/sdc/http/SdcConnectorClient.java
sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpAsdcClientResponseTest.java [new file with mode: 0644]
sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpAsdcClientTest.java [new file with mode: 0644]
sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpRequestFactoryTest.java [new file with mode: 0644]
sdc-distribution-client/src/test/java/org/onap/sdc/http/SdcConnectorClientTest.java

diff --git a/pom.xml b/pom.xml
index a10c7ac..52add6d 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,6 @@
 
        <modules>
                <module>sdc-distribution-client</module>
-               <!-- <module>sdc-distribution-ci</module> -->
        </modules>
 
        <properties>
@@ -43,7 +42,7 @@
                <guava.version>21.0</guava.version>
                <jetty.version>9.4.18.v20190429</jetty.version>
                <bean-matchers.version>0.11</bean-matchers.version>
-               
+
                <nexus.proxy>https://nexus.onap.org</nexus.proxy>
                <sitePath>/content/sites/site/org/onap/sdc/sdc-distribution-client/${project.version}</sitePath>
                <snapshots.path>snapshots</snapshots.path>
@@ -60,7 +59,7 @@
                <sonar.test.exclusions>**/test/**/*,**/tests/**/*</sonar.test.exclusions>
                <sonar.inclusions>app/**/*.js,server-mock/**/*.js,src/**/*.js,src/main/**/*.java</sonar.inclusions>
                <sonar.branch>${project.version}</sonar.branch>
-               
+
        </properties>
        <reporting>
                <plugins>
@@ -82,7 +81,7 @@
                        </plugin>
                </plugins>
        </reporting>
-       
+
        <build>
                <plugins>
                        <plugin>
                                        </execution>
                                </executions>
                        </plugin>
-                       
+
                        <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-surefire-plugin</artifactId>
                                <artifactId>maven-javadoc-plugin</artifactId>
                                <version>2.10.3</version>
                                <configuration/>
-                       </plugin>                       
+                       </plugin>
                        <plugin>
                                <groupId>org.sonarsource.scanner.maven</groupId>
                                <artifactId>sonar-maven-plugin</artifactId>
                        </plugin>
                </plugins>
        </build>
-       
+
        <repositories>
                <repository>
                        <id>central</id>
index f774af3..596d3d3 100644 (file)
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-       <modelVersion>4.0.0</modelVersion>
-
-       <parent>
-               <groupId>org.onap.sdc.sdc-distribution-client</groupId>
-               <artifactId>sdc-main-distribution-client</artifactId>
-               <version>1.4.1-SNAPSHOT</version>
-       </parent>
-
-       <artifactId>sdc-distribution-client</artifactId>
-       <name>sdc-sdc-distribution-client</name>
-       <description>Distribution client JAR file to use by consumers</description>
-       <packaging>jar</packaging>
-
-
-
-       <dependencies>
-       
-               <dependency>
-                       <groupId>com.att.nsa</groupId>
-                       <artifactId>saClientLibrary</artifactId>
-                       <version>0.0.1</version>
-                       <scope>compile</scope>
-                       <exclusions>
-                               <exclusion>  <!-- declare the exclusion here -->
-                                       <groupId>org.slf4j</groupId>
-                                       <artifactId>slf4j-log4j12</artifactId>
-                               </exclusion>
-                       </exclusions>
-               </dependency>
-               <dependency>
-                       <groupId>org.slf4j</groupId>
-                       <artifactId>slf4j-api</artifactId>
-                       <version>1.7.10</version>
-               </dependency>
-               <dependency>
-                       <groupId>com.att.nsa</groupId>
-                       <artifactId>cambriaClient</artifactId>
-                       <version>0.0.1</version>
-                       <scope>compile</scope>
-               </dependency>
-
-               <dependency>
-                       <groupId>com.google.code.gson</groupId>
-                       <artifactId>gson</artifactId>
-                       <version>2.3.1</version>
-                       <scope>compile</scope>
-               </dependency>
-
-               <dependency>
-                       <groupId>org.functionaljava</groupId>
-                       <artifactId>functionaljava</artifactId>
-                       <version>4.2</version>
-                       <scope>compile</scope>
-               </dependency>
-
-               <dependency>
-                       <groupId>commons-io</groupId>
-                       <artifactId>commons-io</artifactId>
-                       <version>2.5</version>
-               </dependency>
-
-               <!-- http client -->
-               <dependency>
-                       <groupId>org.apache.httpcomponents</groupId>
-                       <artifactId>httpclient</artifactId>
-                       <version>${httpclient.version}</version>
-                       <exclusions>
-                               <exclusion>
-                                       <groupId>commons-codec</groupId>
-                                       <artifactId>commons-codec</artifactId>
-                               </exclusion>
-                       </exclusions>
-                       <scope>compile</scope>
-               </dependency>
-
-               <dependency>
-                       <groupId>org.apache.httpcomponents</groupId>
-                       <artifactId>httpmime</artifactId>
-                       <version>${httpclient.version}</version>
-                       <scope>compile</scope>
-               </dependency>
-
-               <!-- YAML parser -->
-               <dependency>
-                       <groupId>org.yaml</groupId>
-                       <artifactId>snakeyaml</artifactId>
-                       <version>${snakeyaml.version}</version>
-                       <scope>compile</scope>
-               </dependency>
-
-               <!-- http core -->
-               <dependency>
-                       <groupId>org.apache.httpcomponents</groupId>
-                       <artifactId>httpcore</artifactId>
-                       <version>${httpcore.version}</version>
-                       <scope>compile</scope>
-               </dependency>
-
-               <dependency>
-                       <groupId>com.google.guava</groupId>
-                       <artifactId>guava</artifactId>
-                       <version>${guava.version}</version>
-               </dependency>
-
-               <!-- TEST -->
-               <dependency>
-                       <groupId>org.eclipse.jetty</groupId>
-                       <artifactId>jetty-servlet</artifactId>
-                       <scope>test</scope>
-                       <version>${jetty.version}</version>
-               </dependency>
-
-               <dependency>
-                       <groupId>org.eclipse.jetty</groupId>
-                       <artifactId>jetty-webapp</artifactId>
-                       <version>${jetty.version}</version>
-                       <scope>test</scope>
-               </dependency>
-
-               <dependency>
-                       <groupId>junit</groupId>
-                       <artifactId>junit</artifactId>
-                       <version>4.12</version>
-                       <scope>test</scope>
-               </dependency>
-
-               <dependency>
-                       <groupId>org.mockito</groupId>
-                       <artifactId>mockito-all</artifactId>
-                       <version>1.10.19</version>
-                       <scope>test</scope>
-               </dependency>
-
-               <dependency>
-                       <groupId>com.google.code.bean-matchers</groupId>
-                       <artifactId>bean-matchers</artifactId>
-                       <version>${bean-matchers.version}</version>
-                       <scope>test</scope>
-               </dependency>
-
-       </dependencies>
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <properties>
+        <assertj-core.version>3.18.1</assertj-core.version>
+        <mockito-all.version>3.6.28</mockito-all.version>
+        <commons-io.version>2.5</commons-io.version>
+        <gson.version>2.3.1</gson.version>
+        <cambriaClient.version>0.0.1</cambriaClient.version>
+        <slf4j-api.version>1.7.10</slf4j-api.version>
+    </properties>
+
+    <parent>
+        <groupId>org.onap.sdc.sdc-distribution-client</groupId>
+        <artifactId>sdc-main-distribution-client</artifactId>
+        <version>1.4.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>sdc-distribution-client</artifactId>
+    <name>sdc-sdc-distribution-client</name>
+    <description>Distribution client JAR file to use by consumers</description>
+    <packaging>jar</packaging>
+
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.att.nsa</groupId>
+            <artifactId>saClientLibrary</artifactId>
+            <version>${cambriaClient.version}</version>
+            <scope>compile</scope>
+            <exclusions>
+                <exclusion>  <!-- declare the exclusion here -->
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-log4j12</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>${slf4j-api.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.att.nsa</groupId>
+            <artifactId>cambriaClient</artifactId>
+            <version>${cambriaClient.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>${gson.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.functionaljava</groupId>
+            <artifactId>functionaljava</artifactId>
+            <version>${functionaljava.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons-io.version}</version>
+        </dependency>
+
+        <!-- http client -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>${httpclient.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-codec</groupId>
+                    <artifactId>commons-codec</artifactId>
+                </exclusion>
+            </exclusions>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>${httpclient.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <!-- YAML parser -->
+        <dependency>
+            <groupId>org.yaml</groupId>
+            <artifactId>snakeyaml</artifactId>
+            <version>${snakeyaml.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <!-- http core -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>${httpcore.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${guava.version}</version>
+        </dependency>
+
+        <!-- TEST -->
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlet</artifactId>
+            <scope>test</scope>
+            <version>${jetty.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-webapp</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>${mockito-all.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.bean-matchers</groupId>
+            <artifactId>bean-matchers</artifactId>
+            <version>${bean-matchers.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>${assertj-core.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 
 </project>
index 44f1295..14c9c7f 100644 (file)
@@ -3,7 +3,7 @@
  * sdc-distribution-client
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * Modifications copyright (C) 2019 Nokia. All rights reserved.
+ * Modifications copyright (C) 2020 Nokia. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.sdc.http;
 
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.ConnectException;
-import java.net.UnknownHostException;
-import java.security.KeyStore;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpStatus;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.CredentialsProvider;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.ssl.SSLContextBuilder;
-import org.apache.http.ssl.TrustStrategy;
 import org.onap.sdc.api.consumer.IConfiguration;
 import org.onap.sdc.utils.Pair;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class HttpAsdcClient implements IHttpAsdcClient {
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
 
-    private static final String TLS = "TLSv1.2";
-    private static final String AUTHORIZATION_HEADER = "Authorization";
-    private static final String HTTPS = "https://";
-    private static final String HTTP = "http://";
-    public static final int AUTHORIZATION_SCOPE_PORT = 443;
-    public static final int AUTHORIZATION_SCOPE_PLAIN_PORT = 80;
-    private static Logger log = LoggerFactory.getLogger(HttpAsdcClient.class.getName());
-    private CloseableHttpClient httpClient = null;
-    private String serverFqdn = null;
-    private String authHeaderValue = "";
-    private Boolean use_ssl = true;
+public class HttpAsdcClient implements IHttpAsdcClient {
 
+    private static final Logger log = LoggerFactory.getLogger(HttpAsdcClient.class.getName());
+    private static final boolean ALWAYS_CLOSE_THE_REQUEST_CONNECTION = true;
+    private final CloseableHttpClient httpClient;
+    private final String httpSchema;
+    private final String serverFqdn;
+    private final HttpRequestFactory httpRequestFactory;
+
+    /**
+     * Constructor
+     *
+     * @deprecated
+     * This constructor will be removed in the future.
+     *
+     * @param configuration Asdc client configuration
+     */
+    @Deprecated
     public HttpAsdcClient(IConfiguration configuration) {
-        this.serverFqdn = configuration.getAsdcAddress();
-
-        String username = configuration.getUser();
-        String password = configuration.getPassword();
-        this.use_ssl = configuration.isUseHttpsWithSDC();
-        if (this.use_ssl) {
-            initSSL(username, password, configuration.getKeyStorePath(), configuration.getKeyStorePassword(), configuration.activateServerTLSAuth());
-        } else {
-            CredentialsProvider credsProvider = new BasicCredentialsProvider();
-            credsProvider.setCredentials(new AuthScope("localhost", AUTHORIZATION_SCOPE_PLAIN_PORT), new UsernamePasswordCredentials(username, password));
-            httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(credsProvider).build();
-        }
-
-        String userNameAndPassword = username + ":" + password;
-        this.authHeaderValue = "Basic " + Base64.getEncoder().encodeToString(userNameAndPassword.getBytes());
+        this(configuration.getAsdcAddress(),
+                new HttpClientFactory(configuration),
+                new HttpRequestFactory(configuration.getUser(), configuration.getPassword())
+        );
     }
 
-    // @SuppressWarnings("deprecation")
-    private void initSSL(String username, String password, String keyStorePath, String keyStoePass, boolean isSupportSSLVerification) {
-
-        try {
-            HostnameVerifier hostnameVerifier = new HostnameVerifier() {
-
-                @Override
-                public boolean verify(String hostname, SSLSession session) {
-                    return true;
-                }
-            };
-
-            // SSLContextBuilder is not thread safe
-            // @SuppressWarnings("deprecation")
-            CredentialsProvider credsProvider = new BasicCredentialsProvider();
-            credsProvider.setCredentials(new AuthScope("localhost", AUTHORIZATION_SCOPE_PORT), new UsernamePasswordCredentials(username, password));
-            SSLContext sslContext;
-            sslContext = SSLContext.getInstance(TLS);
-            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-            KeyStore trustStore = null;
-            tmf.init(trustStore);
-            TrustManager[] tms = tmf.getTrustManagers();
-            if (isSupportSSLVerification) {
-
-                if (keyStorePath != null && !keyStorePath.isEmpty()) {
-                    // trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
-                    // trustStore.load(new FileInputStream(keyStorePath), keyStoePass.toCharArray());
-
-                    // Using null here initialises the TMF with the default trust store.
-
-                    // Get hold of the default trust manager
-                    X509TrustManager defaultTm = null;
-                    for (TrustManager tm : tmf.getTrustManagers()) {
-                        if (tm instanceof X509TrustManager) {
-                            defaultTm = (X509TrustManager) tm;
-                            break;
-                        }
-                    }
-
-                    // Do the same with your trust store this time
-                    // Adapt how you load the keystore to your needs
-                    trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
-                    trustStore.load(new FileInputStream(keyStorePath), keyStoePass.toCharArray());
-
-                    tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-                    tmf.init(trustStore);
-
-                    // Get hold of the default trust manager
-                    X509TrustManager myTm = null;
-                    for (TrustManager tm : tmf.getTrustManagers()) {
-                        if (tm instanceof X509TrustManager) {
-                            myTm = (X509TrustManager) tm;
-                            break;
-                        }
-                    }
-
-                    // Wrap it in your own class.
-                    final X509TrustManager finalDefaultTm = defaultTm;
-                    final X509TrustManager finalMyTm = myTm;
-                    X509TrustManager customTm = new X509TrustManager() {
-                        @Override
-                        public X509Certificate[] getAcceptedIssuers() {
-                            // If you're planning to use client-cert auth,
-                            // merge results from "defaultTm" and "myTm".
-                            return finalDefaultTm.getAcceptedIssuers();
-                        }
-
-                        @Override
-                        public void checkServerTrusted(X509Certificate[] chain, String authType)
-                                throws CertificateException {
-                            try {
-                                finalMyTm.checkServerTrusted(chain, authType);
-                            } catch (CertificateException e) {
-                                // This will throw another CertificateException if this fails too.
-                                finalDefaultTm.checkServerTrusted(chain, authType);
-                            }
-                        }
-
-                        @Override
-                        public void checkClientTrusted(X509Certificate[] chain, String authType)
-                                throws CertificateException {
-                            // If you're planning to use client-cert auth,
-                            // do the same as checking the server.
-                            finalDefaultTm.checkClientTrusted(chain, authType);
-                        }
-                    };
-
-                    tms = new TrustManager[]{customTm};
-
-                }
-
-                sslContext.init(null, tms, null);
-                SSLContext.setDefault(sslContext);
-
-
-            } else {
-
-                SSLContextBuilder builder = new SSLContextBuilder();
-
-                builder.loadTrustMaterial(null, new TrustStrategy() {
-                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-                        return true;
-                    }
-                });
-
-                sslContext = builder.build();
-            }
-
-            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null, hostnameVerifier);
-            httpClient = HttpClientBuilder.create().
-                    setDefaultCredentialsProvider(credsProvider).
-                    setSSLSocketFactory(sslsf).
-                    build();
-
-        } catch (Exception e) {
-            log.error("Failed to create https client", e);
-
-        }
+    public HttpAsdcClient(String asdcAddress, HttpClientFactory httpClientFactory, HttpRequestFactory httpRequestFactory) {
+        this.serverFqdn = asdcAddress;
+        this.httpRequestFactory = httpRequestFactory;
 
-        return;
+        Pair<String, CloseableHttpClient> httpClientPair = httpClientFactory.createInstance();
+        this.httpSchema = httpClientPair.getFirst();
+        this.httpClient = httpClientPair.getSecond();
     }
 
     public HttpAsdcResponse postRequest(String requestUrl, HttpEntity entity, Map<String, String> headersMap) {
-        return postRequest(requestUrl, entity, headersMap, true).getFirst();
+        return postRequest(requestUrl, entity, headersMap, ALWAYS_CLOSE_THE_REQUEST_CONNECTION).getFirst();
     }
 
     public Pair<HttpAsdcResponse, CloseableHttpResponse> postRequest(String requestUrl, HttpEntity entity, Map<String, String> headersMap, boolean closeTheRequest) {
         Pair<HttpAsdcResponse, CloseableHttpResponse> ret;
+        final String url = resolveUrl(requestUrl);
+        log.debug("url to send {}", url);
+        HttpPost httpPost = httpRequestFactory.createHttpPostRequest(url, headersMap, entity);
+
         CloseableHttpResponse httpResponse = null;
         HttpAsdcResponse response = null;
-        HttpPost httpPost = new HttpPost(getScheme() + serverFqdn + requestUrl);
-        List<Header> headers = addHeadersToHttpRequest(headersMap);
-        for (Header header : headers) {
-            httpPost.addHeader(header);
-        }
-
-        httpPost.setHeader(AUTHORIZATION_HEADER, this.authHeaderValue);
-
-        httpPost.setEntity(entity);
         try {
             httpResponse = httpClient.execute(httpPost);
             response = new HttpAsdcResponse(httpResponse.getStatusLine().getStatusCode(), httpResponse.getEntity());
-
         } catch (IOException e) {
-            log.error("failed to send request to url: " + requestUrl);
-            StringEntity errorEntity = null;
-            try {
-                errorEntity = new StringEntity("failed to send request");
-            } catch (UnsupportedEncodingException e1) {
-            }
-
-            response = new HttpAsdcResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, errorEntity);
-
+            log.error("failed to send request to url: {}", requestUrl);
+            response = createHttpResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "failed to send request");
         } finally {
-            if (closeTheRequest) {
-                if (httpResponse != null) {
-                    try {
-                        httpResponse.close();
-
-                    } catch (IOException e) {
-                        log.error("failed to close http response");
-                    }
-                }
-                ret = new Pair<>(response, null);
-            } else {
-                ret = new Pair<>(response, httpResponse);
-            }
+            ret = finalizeHttpRequest(closeTheRequest, httpResponse, response);
         }
 
         return ret;
     }
 
     public HttpAsdcResponse getRequest(String requestUrl, Map<String, String> headersMap) {
-
-        return getRequest(requestUrl, headersMap, true).getFirst();
-
+        return getRequest(requestUrl, headersMap, ALWAYS_CLOSE_THE_REQUEST_CONNECTION).getFirst();
     }
 
     public Pair<HttpAsdcResponse, CloseableHttpResponse> getRequest(String requestUrl, Map<String, String> headersMap, boolean closeTheRequest) {
         Pair<HttpAsdcResponse, CloseableHttpResponse> ret;
-        CloseableHttpResponse httpResponse = null;
-        String url = getScheme() + serverFqdn + requestUrl;
-        log.debug("url to send {}", url);
-        HttpGet httpGet = new HttpGet(url);
-        List<Header> headers = addHeadersToHttpRequest(headersMap);
-        for (Header header : headers) {
-            httpGet.addHeader(header);
-        }
 
-        httpGet.setHeader(AUTHORIZATION_HEADER, this.authHeaderValue);
+        final String url = resolveUrl(requestUrl);
+        log.debug("url to send {}", url);
+        HttpGet httpGet = httpRequestFactory.createHttpGetRequest(url, headersMap);
 
+        CloseableHttpResponse httpResponse = null;
         HttpAsdcResponse response = null;
         try {
             httpResponse = httpClient.execute(httpGet);
@@ -302,73 +126,52 @@ public class HttpAsdcClient implements IHttpAsdcClient {
 
         } catch (UnknownHostException | ConnectException e) {
             log.error("failed to connect to url: {}", requestUrl, e);
-            StringEntity errorEntity = null;
-            try {
-                errorEntity = new StringEntity("failed to connect");
-            } catch (UnsupportedEncodingException e1) {
-            }
-
-            response = new HttpAsdcResponse(HttpStatus.SC_BAD_GATEWAY, errorEntity);
-
+            response = createHttpResponse(HttpStatus.SC_BAD_GATEWAY, "failed to connect");
         } catch (IOException e) {
-            log.error("failed to send request to url: " + requestUrl + " error " + e.getMessage());
-            StringEntity errorEntity = null;
-            try {
-                errorEntity = new StringEntity("failed to send request " + e.getMessage());
-            } catch (UnsupportedEncodingException e1) {
-            }
+            log.error("failed to send request to url: {} error {}", requestUrl, e.getMessage());
+            response = createHttpResponse(HttpStatus.SC_BAD_GATEWAY, "failed to send request " + e.getMessage());
+        } finally {
+            ret = finalizeHttpRequest(closeTheRequest, httpResponse, response);
+        }
 
-            response = new HttpAsdcResponse(HttpStatus.SC_BAD_GATEWAY, errorEntity);
+        return ret;
+    }
 
-        } finally {
+    String getHttpSchema(){
+        return this.httpSchema;
+    }
 
-            if (closeTheRequest) {
-                if (httpResponse != null) {
-                    try {
-                        httpResponse.close();
+    private String resolveUrl(String requestUrl) {
+        return this.httpSchema + serverFqdn + requestUrl;
+    }
 
-                    } catch (IOException e) {
-                        log.error("failed to close http response");
-                    }
+    private Pair<HttpAsdcResponse, CloseableHttpResponse> finalizeHttpRequest(boolean closeTheRequest, CloseableHttpResponse httpResponse, HttpAsdcResponse response) {
+        Pair<HttpAsdcResponse, CloseableHttpResponse> ret;
+        if (closeTheRequest) {
+            if (httpResponse != null) {
+                try {
+                    httpResponse.close();
+                } catch (IOException e) {
+                    log.error("failed to close http response");
                 }
-                ret = new Pair<HttpAsdcResponse, CloseableHttpResponse>(response, null);
-            } else {
-                ret = new Pair<HttpAsdcResponse, CloseableHttpResponse>(response, httpResponse);
             }
+            ret = new Pair<>(response, null);
+        } else {
+            ret = new Pair<>(response, httpResponse);
         }
 
         return ret;
+    }
 
+    static HttpAsdcResponse createHttpResponse(int httpStatusCode, String httpMessage) {
+        return new HttpAsdcResponse(httpStatusCode, new StringEntity(httpMessage, StandardCharsets.UTF_8));
     }
 
     public void closeHttpClient() {
         try {
             httpClient.close();
         } catch (IOException e) {
-            // TODO Auto-generated catch block
             log.error("failed to close http client");
         }
-
     }
-
-    private List<Header> addHeadersToHttpRequest(Map<String, String> headersMap) {
-
-        List<Header> requestHeaders = new ArrayList<Header>();
-
-        Set<String> headersKyes = headersMap.keySet();
-        for (String key : headersKyes) {
-            Header requestHeader = new BasicHeader(key, headersMap.get(key));
-            requestHeaders.add(requestHeader);
-        }
-
-        return requestHeaders;
-    }
-
-    private String getScheme() {
-        if (this.use_ssl) {
-            return HTTPS;
-        }
-        return HTTP;
-    }
-
 }
diff --git a/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClientException.java b/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClientException.java
new file mode 100644 (file)
index 0000000..8d6a527
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.sdc.http;
+
+public class HttpAsdcClientException extends RuntimeException {
+
+    public HttpAsdcClientException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpClientFactory.java b/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpClientFactory.java
new file mode 100644 (file)
index 0000000..db1164d
--- /dev/null
@@ -0,0 +1,202 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.sdc.http;
+
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.onap.sdc.api.consumer.IConfiguration;
+import org.onap.sdc.utils.Pair;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+class HttpClientFactory {
+    private static final int AUTHORIZATION_SCOPE_PLAIN_PORT = 80;
+    private static final int AUTHORIZATION_SCOPE_PORT = 443;
+    private static final KeyStore DEFAULT_INIT_KEY_STORE_VALUE = null;
+    private static final String TLS = "TLSv1.2";
+    static final String HTTP = "http://";
+    static final String HTTPS = "https://";
+    private final IConfiguration configuration;
+
+    HttpClientFactory(IConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    Pair<String, CloseableHttpClient> createInstance() {
+        boolean isHttpsRequired = configuration.isUseHttpsWithSDC();
+        Pair<String, CloseableHttpClient> httpClientPair;
+        if (isHttpsRequired) {
+            httpClientPair = createHttpsClient(configuration);
+        } else {
+            httpClientPair = createHttpClient(configuration);
+        }
+        return httpClientPair;
+    }
+
+    private Pair<String, CloseableHttpClient> createHttpsClient(IConfiguration configuration) {
+        return new Pair<>(
+                HTTPS,
+                initSSL(configuration.getUser(),
+                        configuration.getPassword(),
+                        configuration.getKeyStorePath(),
+                        configuration.getKeyStorePassword(),
+                        configuration.activateServerTLSAuth()
+                )
+        );
+    }
+
+    private Pair<String, CloseableHttpClient> createHttpClient(IConfiguration configuration) {
+        CredentialsProvider credsProvider = new BasicCredentialsProvider();
+        credsProvider.setCredentials(new AuthScope("localhost", AUTHORIZATION_SCOPE_PLAIN_PORT), new UsernamePasswordCredentials(configuration.getUser(), configuration.getPassword()));
+        return new Pair<>(HTTP, HttpClientBuilder.create().setDefaultCredentialsProvider(credsProvider).build());
+    }
+
+    private CloseableHttpClient initSSL(String username, String password, String keyStorePath, String keyStorePass, boolean isSupportSSLVerification) {
+
+        try {
+
+            // SSLContextBuilder is not thread safe
+            CredentialsProvider credsProvider = new BasicCredentialsProvider();
+            credsProvider.setCredentials(new AuthScope("localhost", AUTHORIZATION_SCOPE_PORT), new UsernamePasswordCredentials(username, password));
+            SSLContext sslContext;
+            sslContext = SSLContext.getInstance(TLS);
+            TrustManagerFactory tmf = createTrustManagerFactory();
+            TrustManager[] tms = tmf.getTrustManagers();
+            if (isSupportSSLVerification) {
+
+                if (keyStorePath != null && !keyStorePath.isEmpty()) {
+                    // Using null here initialises the TMF with the default trust store.
+
+                    // Get hold of the default trust manager
+                    X509TrustManager defaultTm = null;
+                    for (TrustManager tm : tmf.getTrustManagers()) {
+                        if (tm instanceof X509TrustManager) {
+                            defaultTm = (X509TrustManager) tm;
+                            break;
+                        }
+                    }
+
+                    // Do the same with your trust store this time
+                    // Adapt how you load the keystore to your needs
+                    KeyStore trustStore = loadKeyStore(keyStorePath, keyStorePass);
+
+                    tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+                    tmf.init(trustStore);
+
+                    // Get hold of the default trust manager
+                    X509TrustManager myTm = null;
+                    for (TrustManager tm : tmf.getTrustManagers()) {
+                        if (tm instanceof X509TrustManager) {
+                            myTm = (X509TrustManager) tm;
+                            break;
+                        }
+                    }
+
+                    // Wrap it in your own class.
+                    final X509TrustManager finalDefaultTm = defaultTm;
+                    final X509TrustManager finalMyTm = myTm;
+                    X509TrustManager customTm = new X509TrustManager() {
+                        @Override
+                        public X509Certificate[] getAcceptedIssuers() {
+                            // If you're planning to use client-cert auth,
+                            // merge results from "defaultTm" and "myTm".
+                            return finalDefaultTm.getAcceptedIssuers();
+                        }
+
+                        @Override
+                        public void checkServerTrusted(X509Certificate[] chain, String authType)
+                                throws CertificateException {
+                            try {
+                                finalMyTm.checkServerTrusted(chain, authType);
+                            } catch (CertificateException e) {
+                                // This will throw another CertificateException if this fails too.
+                                finalDefaultTm.checkServerTrusted(chain, authType);
+                            }
+                        }
+
+                        @Override
+                        public void checkClientTrusted(X509Certificate[] chain, String authType)
+                                throws CertificateException {
+                            // If you're planning to use client-cert auth,
+                            // do the same as checking the server.
+                            finalDefaultTm.checkClientTrusted(chain, authType);
+                        }
+                    };
+
+                    tms = new TrustManager[]{customTm};
+
+                }
+
+                sslContext.init(null, tms, null);
+                SSLContext.setDefault(sslContext);
+
+
+            } else {
+
+                SSLContextBuilder builder = new SSLContextBuilder();
+
+                builder.loadTrustMaterial(null, (chain, authType) -> true);
+
+                sslContext = builder.build();
+            }
+
+            HostnameVerifier hostnameVerifier = (hostname, session) -> hostname.equalsIgnoreCase(session.getPeerHost());
+            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{TLS}, null, hostnameVerifier);
+            return HttpClientBuilder.create().
+                    setDefaultCredentialsProvider(credsProvider).
+                    setSSLSocketFactory(sslsf).
+                    build();
+        } catch (Exception e) {
+            throw new HttpAsdcClientException("Failed to create https client", e);
+        }
+    }
+
+    private TrustManagerFactory createTrustManagerFactory() throws NoSuchAlgorithmException, KeyStoreException {
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        tmf.init(DEFAULT_INIT_KEY_STORE_VALUE);
+        return tmf;
+    }
+
+    private KeyStore loadKeyStore(String keyStorePath, String keyStorePass) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
+        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        try (FileInputStream keyStoreData = new FileInputStream(keyStorePath)) {
+            trustStore.load(keyStoreData, keyStorePass.toCharArray());
+        }
+        return trustStore;
+    }
+}
diff --git a/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpRequestFactory.java b/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpRequestFactory.java
new file mode 100644 (file)
index 0000000..0049d90
--- /dev/null
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.sdc.http;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.message.BasicHeader;
+
+import java.util.Base64;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+class HttpRequestFactory {
+
+    public static final String AUTHORIZATION = "Authorization";
+    private static final String BASIC_AUTH_FORMAT = "%s:%s";
+    private final String authHeaderValue;
+
+    HttpRequestFactory(String user, String password) {
+        this.authHeaderValue = "Basic " + Base64.getEncoder().encodeToString(createAuthHeaderData(user, password));
+    }
+
+    public HttpGet createHttpGetRequest(String url, Map<String, String> headersMap) {
+        HttpGet httpGet = new HttpGet(url);
+        httpGet.setHeaders(createHttpRequestHeaders(headersMap, authHeaderValue));
+
+        return httpGet;
+    }
+
+    public HttpPost createHttpPostRequest(String url, Map<String, String> headersMap, HttpEntity entity) {
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeaders(createHttpRequestHeaders(headersMap, authHeaderValue));
+        httpPost.setEntity(entity);
+
+        return httpPost;
+    }
+
+    private Header[] createHttpRequestHeaders(Map<String, String> headersMap, String authorizationValue) {
+        final List<Header> headers = headersMap.entrySet().stream()
+                .map(it -> new BasicHeader(it.getKey(), it.getValue()))
+                .collect(Collectors.toList());
+        headers.add(new BasicHeader(AUTHORIZATION, authorizationValue));
+        return convertToArray(headers);
+    }
+
+    private Header[] convertToArray(List<Header> headers) {
+        return headers.toArray(new Header[0]);
+    }
+
+    private byte[] createAuthHeaderData(String user, String password) {
+        return (String.format(BASIC_AUTH_FORMAT, user, password)).getBytes();
+    }
+}
index ee13944..2999ebe 100644 (file)
@@ -58,7 +58,7 @@ import com.google.gson.reflect.TypeToken;
 import fj.data.Either;
 
 public class SdcConnectorClient {
-    private final static Logger log = LoggerFactory.getLogger(SdcConnectorClient.class.getName());
+    private static final Logger log = LoggerFactory.getLogger(SdcConnectorClient.class.getName());
     static final String CONTENT_DISPOSITION_HEADER = "Content-Disposition";
 
     private final IConfiguration configuration;
diff --git a/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpAsdcClientResponseTest.java b/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpAsdcClientResponseTest.java
new file mode 100644 (file)
index 0000000..eb5c1eb
--- /dev/null
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.sdc.http;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpStatus;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collection;
+
+
+@RunWith(value = Parameterized.class)
+public class HttpAsdcClientResponseTest {
+    @Parameterized.Parameter
+    public int httpStatusCode;
+
+    @Parameterized.Parameter(value = 1)
+    public String httpMessage;
+
+    @Parameterized.Parameters(name = "{index}: test({0},{1}) = {0} {1}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {HttpStatus.SC_INTERNAL_SERVER_ERROR, "failed to send request"},
+                {HttpStatus.SC_BAD_GATEWAY, "failed to connect"},
+                {HttpStatus.SC_BAD_GATEWAY, "failed to send request "}
+        });
+    }
+
+    @Test
+    public void shouldCreateHttpResponse() throws IOException {
+        // when
+        final HttpAsdcResponse response = HttpAsdcClient.createHttpResponse(httpStatusCode, httpMessage);
+
+        // then
+        Assert.assertEquals(httpStatusCode, response.getStatus());
+        Assert.assertEquals(httpMessage, getResponseMessage(response));
+    }
+
+    private String getResponseMessage(HttpAsdcResponse response) throws IOException {
+        return IOUtils.toString(response.getMessage().getContent(), StandardCharsets.UTF_8);
+    }
+}
diff --git a/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpAsdcClientTest.java b/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpAsdcClientTest.java
new file mode 100644 (file)
index 0000000..4e74080
--- /dev/null
@@ -0,0 +1,179 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.sdc.http;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.StatusLine;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.message.BasicHeader;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.sdc.utils.Pair;
+import org.onap.sdc.utils.TestConfiguration;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class HttpAsdcClientTest {
+
+    private static final String URL = "http://127.0.0.1:8080/target";
+    private static final int HTTP_OK = 200;
+    private static final String K_1 = "k1";
+    private static final String V_1 = "v1";
+    private static final String K_2 = "k2";
+    private static final String V_2 = "v2";
+    private static final Header[] HEADERS = new Header[]{new BasicHeader(K_1, V_1), new BasicHeader(K_2, V_2)};
+    private static final HashMap<String, String> HEADERS_MAP = new HashMap<String, String>() {{
+        put("key1", "key2");
+    }};
+
+    @Mock
+    private CloseableHttpClient httpClient;
+    @Mock
+    private HttpEntity httpEntity;
+
+    @Test
+    public void shouldCreateInitializedHttpClient() {
+        // given
+        TestConfiguration configuration = new TestConfiguration();
+        configuration.setUseHttpsWithSDC(false);
+
+        // when
+        final HttpRequestFactory httpRequestFactory = new HttpRequestFactory(
+                configuration.getUser(),
+                configuration.getPassword());
+        final HttpAsdcClient httpAsdcClient = new HttpAsdcClient(
+                configuration.getAsdcAddress(),
+                new HttpClientFactory(configuration),
+                httpRequestFactory);
+
+        // then
+        assertNotNull(httpAsdcClient);
+        assertEquals(HttpClientFactory.HTTP, httpAsdcClient.getHttpSchema());
+    }
+
+    @Test
+    public void shouldCreateInitializedHttpsClient() {
+        // given
+        TestConfiguration configuration = new TestConfiguration();
+        configuration.setUseHttpsWithSDC(true);
+
+        // when
+        final HttpRequestFactory httpRequestFactory = new HttpRequestFactory(
+                configuration.getUser(),
+                configuration.getPassword());
+        final HttpAsdcClient httpAsdcClient = new HttpAsdcClient(
+                configuration.getAsdcAddress(),
+                new HttpClientFactory(configuration),
+                httpRequestFactory);
+
+        // then
+        assertNotNull(httpAsdcClient);
+        assertEquals(HttpClientFactory.HTTPS, httpAsdcClient.getHttpSchema());
+    }
+
+    @Test
+    public void shouldSendGetRequestWithoutAnyError() throws IOException {
+        // given
+        TestConfiguration configuration = givenHttpConfiguration();
+        final HttpAsdcClient httpAsdcClient = createTestObj(HttpClientFactory.HTTP, configuration, httpClient);
+        CloseableHttpResponse httpResponse = givenHttpResponse();
+
+        // when
+        final HttpAsdcResponse response = httpAsdcClient.getRequest(URL, HEADERS_MAP);
+
+        // then
+        assertThat(response).isNotNull();
+        assertThat(response.getStatus()).isEqualTo(HTTP_OK);
+        assertThat(response.getHeadersMap()).containsAllEntriesOf(new HashMap<String, String>() {{
+            put(K_1, V_1);
+            put(K_2, V_2);
+        }});
+        assertThat(response.getMessage()).isEqualTo(httpEntity);
+        verify(httpResponse).close();
+
+    }
+
+    @Test
+    public void shouldSendPostRequestWithoutAnyError() throws IOException {
+        // given
+        TestConfiguration configuration = givenHttpConfiguration();
+        final HttpAsdcClient httpAsdcClient = createTestObj(HttpClientFactory.HTTP, configuration, httpClient);
+        CloseableHttpResponse httpResponse = givenHttpResponse();
+
+        // when
+        final HttpAsdcResponse response = httpAsdcClient.postRequest(URL,httpEntity, HEADERS_MAP);
+
+        // then
+        assertThat(response).isNotNull();
+        assertThat(response.getStatus()).isEqualTo(HTTP_OK);
+        assertThat(response.getMessage()).isEqualTo(httpEntity);
+        verify(httpResponse).close();
+
+    }
+
+    private HttpAsdcClient createTestObj(String httpProtocol, TestConfiguration configuration, CloseableHttpClient httpClient) {
+        final HttpRequestFactory httpRequestFactory = new HttpRequestFactory(
+                configuration.getUser(),
+                configuration.getPassword());
+        HttpClientFactory httpClientFactory = mock(HttpClientFactory.class);
+        when(httpClientFactory.createInstance()).thenReturn(new Pair<>(httpProtocol, httpClient));
+        final HttpAsdcClient httpAsdcClient = new HttpAsdcClient(
+                configuration.getAsdcAddress(),
+                httpClientFactory,
+                httpRequestFactory);
+        return httpAsdcClient;
+    }
+
+    private CloseableHttpResponse givenHttpResponse(HttpEntity httpEntity, Header[] headers) {
+        CloseableHttpResponse httpResponse = mock(CloseableHttpResponse.class);
+        StatusLine statusLine = mock(StatusLine.class);
+        when(statusLine.getStatusCode()).thenReturn(HTTP_OK);
+        when(httpResponse.getStatusLine()).thenReturn(statusLine);
+        when(httpResponse.getAllHeaders()).thenReturn(headers);
+        when(httpResponse.getEntity()).thenReturn(httpEntity);
+        return httpResponse;
+    }
+
+    private TestConfiguration givenHttpConfiguration() {
+        TestConfiguration configuration = new TestConfiguration();
+        configuration.setUseHttpsWithSDC(false);
+        return configuration;
+    }
+
+    private CloseableHttpResponse givenHttpResponse() throws IOException {
+        CloseableHttpResponse httpResponse = givenHttpResponse(httpEntity, HEADERS);
+        when(httpClient.execute(any())).thenReturn(httpResponse);
+        return httpResponse;
+    }
+}
diff --git a/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpRequestFactoryTest.java b/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpRequestFactoryTest.java
new file mode 100644 (file)
index 0000000..ba42703
--- /dev/null
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.sdc.http;
+
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.junit.Test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class HttpRequestFactoryTest {
+
+    private static final String URL = "https://127.0.0.1:8080/target";
+    private static final String EXPECTED_AUTHORIZATION_VALUE = "Basic dXNlcjpwYXNzd29yZA==";
+    private static final String HEADER_KEY_1 = "key1";
+    private static final String HEADER_KEY_2 = "key2";
+    private static final String HEADER_VALUE_1 = "value1";
+    private static final String HEADER_VALUE_2 = "value2";
+    private static final Map<String, String> HEADERS = new HashMap<String, String>(){
+        {
+            put(HEADER_KEY_1, HEADER_VALUE_1);
+            put(HEADER_KEY_2, HEADER_VALUE_2);
+        }
+    };
+
+    private HttpRequestFactory testObj = new HttpRequestFactory("user", "password");
+
+    @Test
+    public void shouldCreateValidGetHttpRequest() throws URISyntaxException {
+        // when
+        final HttpGet httpGetRequest = testObj.createHttpGetRequest(URL, HEADERS);
+
+        // then
+        assertThat(httpGetRequest.getURI()).isEqualTo(new URI(URL));
+        assertThat(httpGetRequest.getFirstHeader(HEADER_KEY_1).getValue())
+                .isEqualTo(HEADER_VALUE_1);
+        assertThat(httpGetRequest.getFirstHeader(HEADER_KEY_2).getValue())
+                .isEqualTo(HEADER_VALUE_2);
+        assertThat(httpGetRequest.getFirstHeader(HttpRequestFactory.AUTHORIZATION).getValue())
+                .isEqualTo(EXPECTED_AUTHORIZATION_VALUE);
+    }
+
+    @Test
+    public void shouldCreateValidPostHttpRequest() throws URISyntaxException {
+        // given
+        final HttpEntity httpEntity = mock(HttpEntity.class);
+
+        // when
+        final HttpPost httpPostRequest = testObj.createHttpPostRequest(URL, HEADERS, httpEntity);
+
+        // then
+        assertThat(httpPostRequest.getURI()).isEqualTo(new URI(URL));
+        assertThat(httpPostRequest.getEntity()).isEqualTo(httpEntity);
+        assertThat(httpPostRequest.getFirstHeader(HEADER_KEY_1).getValue())
+                .isEqualTo(HEADER_VALUE_1);
+        assertThat(httpPostRequest.getFirstHeader(HEADER_KEY_2).getValue())
+                .isEqualTo(HEADER_VALUE_2);
+        assertThat(httpPostRequest.getFirstHeader(HttpRequestFactory.AUTHORIZATION).getValue())
+                .isEqualTo(EXPECTED_AUTHORIZATION_VALUE);
+    }
+}
index c52910d..6ff0f9b 100644 (file)
@@ -115,7 +115,7 @@ public class SdcConnectorClientTest {
         doAnswer(new Answer<Pair<HttpAsdcResponse, CloseableHttpResponse>>() {
             @Override
             public Pair<HttpAsdcResponse, CloseableHttpResponse> answer(InvocationOnMock invocation) throws Throwable {
-                lastHttpEntity = invocation.getArgumentAt(1, HttpEntity.class);
+                lastHttpEntity = invocation.getArgument(1, HttpEntity.class);
                 return mockPair;
             }
         }).when(httpClient).postRequest(Mockito.eq(AsdcUrls.POST_FOR_TOPIC_REGISTRATION), Mockito.any(HttpEntity.class),