diff options
author | Bogumil Zebek <bogumil.zebek@nokia.com> | 2020-11-24 12:56:32 +0100 |
---|---|---|
committer | Zebek Bogumil <bogumil.zebek@nokia.com> | 2020-12-02 13:20:29 +0100 |
commit | f9ff1605045ad31e52fffac2da25f7195d5c7455 (patch) | |
tree | 5b47ef4e46165fefdcb38cff3ac62902df8beadb | |
parent | d2b10d0697934a82868878c6027962e5cb5d1882 (diff) |
Improve code quality
- 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
11 files changed, 872 insertions, 424 deletions
@@ -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> @@ -123,7 +122,7 @@ </execution> </executions> </plugin> - + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> @@ -148,7 +147,7 @@ <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> @@ -156,7 +155,7 @@ </plugin> </plugins> </build> - + <repositories> <repository> <id>central</id> diff --git a/sdc-distribution-client/pom.xml b/sdc-distribution-client/pom.xml index f774af3..596d3d3 100644 --- a/sdc-distribution-client/pom.xml +++ b/sdc-distribution-client/pom.xml @@ -1,146 +1,160 @@ <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> diff --git a/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClient.java b/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClient.java index 44f1295..14c9c7f 100644 --- a/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClient.java +++ b/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClient.java @@ -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. @@ -21,273 +21,97 @@ 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 index 0000000..8d6a527 --- /dev/null +++ b/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpAsdcClientException.java @@ -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 index 0000000..db1164d --- /dev/null +++ b/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpClientFactory.java @@ -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 index 0000000..0049d90 --- /dev/null +++ b/sdc-distribution-client/src/main/java/org/onap/sdc/http/HttpRequestFactory.java @@ -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(); + } +} diff --git a/sdc-distribution-client/src/main/java/org/onap/sdc/http/SdcConnectorClient.java b/sdc-distribution-client/src/main/java/org/onap/sdc/http/SdcConnectorClient.java index ee13944..2999ebe 100644 --- a/sdc-distribution-client/src/main/java/org/onap/sdc/http/SdcConnectorClient.java +++ b/sdc-distribution-client/src/main/java/org/onap/sdc/http/SdcConnectorClient.java @@ -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 index 0000000..eb5c1eb --- /dev/null +++ b/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpAsdcClientResponseTest.java @@ -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 index 0000000..4e74080 --- /dev/null +++ b/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpAsdcClientTest.java @@ -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 index 0000000..ba42703 --- /dev/null +++ b/sdc-distribution-client/src/test/java/org/onap/sdc/http/HttpRequestFactoryTest.java @@ -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); + } +} diff --git a/sdc-distribution-client/src/test/java/org/onap/sdc/http/SdcConnectorClientTest.java b/sdc-distribution-client/src/test/java/org/onap/sdc/http/SdcConnectorClientTest.java index c52910d..6ff0f9b 100644 --- a/sdc-distribution-client/src/test/java/org/onap/sdc/http/SdcConnectorClientTest.java +++ b/sdc-distribution-client/src/test/java/org/onap/sdc/http/SdcConnectorClientTest.java @@ -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), |