Sync Integ to Master
[sdc.git] / common-app-api / src / main / java / org / openecomp / sdc / common / http / client / api / HttpClient.java
1 package org.openecomp.sdc.common.http.client.api;
2
3 import java.io.IOException;
4 import java.net.URI;
5 import java.util.Properties;
6
7 import org.apache.commons.lang3.StringUtils;
8 import org.apache.http.HttpEntity;
9 import org.apache.http.HttpHeaders;
10 import org.apache.http.HttpHost;
11 import org.apache.http.auth.AuthScheme;
12 import org.apache.http.auth.AuthScope;
13 import org.apache.http.auth.UsernamePasswordCredentials;
14 import org.apache.http.client.AuthCache;
15 import org.apache.http.client.CredentialsProvider;
16 import org.apache.http.client.methods.CloseableHttpResponse;
17 import org.apache.http.client.methods.HttpDelete;
18 import org.apache.http.client.methods.HttpGet;
19 import org.apache.http.client.methods.HttpPatch;
20 import org.apache.http.client.methods.HttpPost;
21 import org.apache.http.client.methods.HttpPut;
22 import org.apache.http.client.methods.HttpRequestBase;
23 import org.apache.http.client.protocol.HttpClientContext;
24 import org.apache.http.impl.auth.BasicScheme;
25 import org.apache.http.impl.client.BasicAuthCache;
26 import org.apache.http.impl.client.BasicCredentialsProvider;
27 import org.apache.http.impl.client.CloseableHttpClient;
28 import org.openecomp.sdc.be.config.BeEcompErrorManager;
29 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
30 import org.openecomp.sdc.common.api.Constants;
31 import org.openecomp.sdc.common.datastructure.FunctionalInterfaces.FunctionThrows;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 public class HttpClient {
36     private static final Logger logger = LoggerFactory.getLogger(HttpClient.class);
37     
38     private final CloseableHttpClient client;
39     private final HttpClientConfigImmutable configImmutable;
40     
41     HttpClient(CloseableHttpClient client, HttpClientConfigImmutable configImmutable) {
42         this.client = client;
43         this.configImmutable = configImmutable; 
44     }
45     
46     <T> HttpResponse<T> get(String url, Properties headers, FunctionThrows<CloseableHttpResponse, HttpResponse<T>, Exception> responseBuilder) throws HttpExecuteException {
47         HttpGet httpGet = new HttpGet(url);
48         return execute(httpGet, headers, responseBuilder);
49     }
50
51     <T> HttpResponse<T> put(String url, Properties headers, HttpEntity entity, FunctionThrows<CloseableHttpResponse, HttpResponse<T>, Exception> responseBuilder) throws HttpExecuteException {
52         HttpPut httpPut = new HttpPut(url);
53         httpPut.setEntity(entity);
54         return execute(httpPut, headers, responseBuilder);
55     }
56
57     <T> HttpResponse<T> post(String url, Properties headers, HttpEntity entity, FunctionThrows<CloseableHttpResponse, HttpResponse<T>, Exception> responseBuilder) throws HttpExecuteException {
58         HttpPost httpPost = new HttpPost(url);
59         httpPost.setEntity(entity);
60         return execute(httpPost, headers, responseBuilder);
61     }
62
63     <T> HttpResponse<T> patch(String url, Properties headers, HttpEntity entity, FunctionThrows<CloseableHttpResponse, HttpResponse<T>, Exception> responseBuilder) throws HttpExecuteException {
64         HttpPatch httpPatch = new HttpPatch(url);
65         httpPatch.setEntity(entity);
66         return execute(httpPatch, headers, responseBuilder);
67     }
68
69     <T> HttpResponse<T> delete(String url, Properties headers, FunctionThrows<CloseableHttpResponse, HttpResponse<T>, Exception> responseBuilder) throws HttpExecuteException {
70         HttpDelete httpDelete = new HttpDelete(url);
71         return execute(httpDelete, headers, responseBuilder);
72     }
73     
74     void close() {
75         try {
76             client.close();
77         }
78         catch (IOException e) {
79             logger.debug("Close http client failed with exception ", e);
80         }
81     }
82     
83     private <T> HttpResponse<T> execute(HttpRequestBase request, Properties headers, FunctionThrows<CloseableHttpResponse, HttpResponse<T>, Exception> responseBuilder) throws HttpExecuteException {
84         if(configImmutable.getHeaders() != null) {
85             configImmutable.getHeaders().forEach((k, v) -> request.addHeader(k, v));
86         }
87
88         if (headers != null) {
89             headers.forEach((k, v) -> request.addHeader(k.toString(), v.toString()));
90         }
91
92         HttpClientContext httpClientContext = null;
93         if(request.getHeaders(HttpHeaders.AUTHORIZATION).length == 0) {
94             httpClientContext = createHttpContext(request.getURI());
95         }
96
97         logger.debug("Execute request {}", request.getRequestLine());
98         try (CloseableHttpResponse response = client.execute(request, httpClientContext)) {
99             return responseBuilder.apply(response);
100         }
101         catch (Exception e) {
102             String description = String.format("Execute request %s failed with exception: %s", request.getRequestLine(), e.getMessage()); 
103             BeEcompErrorManager.getInstance().logInternalFlowError("ExecuteRestRequest", description, ErrorSeverity.ERROR);
104             logger.debug("{}: ",description, e);
105
106             throw new HttpExecuteException(description, e);
107         } 
108     }
109
110     private HttpClientContext createHttpContext(URI uri) {
111         if(StringUtils.isEmpty(configImmutable.getBasicAuthUserName()) || StringUtils.isEmpty(configImmutable.getBasicAuthPassword())) {
112             return null;
113         }
114
115         CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
116         int port = getPort(uri);
117         credentialsProvider.setCredentials(new AuthScope(uri.getHost(), port), 
118                 new UsernamePasswordCredentials(configImmutable.getBasicAuthUserName(), configImmutable.getBasicAuthPassword()));
119
120         HttpClientContext localContext = HttpClientContext.create();
121         localContext.setCredentialsProvider(credentialsProvider);
122
123         AuthCache authCache = new BasicAuthCache();
124         authCache.put(new HttpHost(uri.getHost(), port), (AuthScheme) new BasicScheme());
125         localContext.setAuthCache(authCache);
126
127         return localContext;
128     }
129
130     private int getPort(URI uri) {
131         int port = uri.getPort(); 
132         if(port < 0) {
133             if(Constants.HTTPS.equals(uri.getScheme())) {
134                 port = 443;
135             }
136             else
137             if (Constants.HTTP.equals(uri.getScheme())) {
138                 port = 80;
139             }
140             else {
141                 port = AuthScope.ANY_PORT;
142                 logger.debug("Protocol \"{}\" is not supported, set port to {}", uri.getScheme(), port);
143             }
144         }
145         return port;
146     }
147 }