Fix for radio buttons
[sdc.git] / catalog-fe / src / main / java / org / openecomp / sdc / fe / client / BackendClient.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.fe.client;
22
23 import java.io.IOException;
24 import java.util.List;
25 import java.util.Map;
26
27 import javax.net.ssl.HostnameVerifier;
28 import javax.net.ssl.SSLContext;
29 import javax.net.ssl.SSLSession;
30 import javax.ws.rs.container.AsyncResponse;
31 import javax.ws.rs.core.Response;
32
33 import org.apache.http.HttpStatus;
34 import org.apache.http.client.methods.CloseableHttpResponse;
35 import org.apache.http.client.methods.HttpPost;
36 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
37 import org.apache.http.entity.InputStreamEntity;
38 import org.apache.http.impl.client.CloseableHttpClient;
39 import org.apache.http.impl.client.HttpClientBuilder;
40 import org.apache.http.impl.client.HttpClients;
41 import org.apache.http.ssl.SSLContextBuilder;
42 import org.openecomp.sdc.common.api.Constants;
43 import org.openecomp.sdc.common.api.ResponseInfo;
44 import org.openecomp.sdc.common.api.ResponseInfo.ResponseStatusEnum;
45 import org.openecomp.sdc.fe.impl.Audit;
46 import org.openecomp.sdc.fe.impl.HttpRequestInfo;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 public class BackendClient {
51
52         private static Logger log = LoggerFactory.getLogger(BackendClient.class.getName());
53
54         private HostnameVerifier hostnameVerifier = null;
55
56         private CloseableHttpClient backendHttpClient;
57         private String backendHost;
58         private String backendContext;
59
60         public BackendClient(String protocol, String backendHost, String backendContext) {
61
62                 this.backendContext = backendContext;
63                 hostnameVerifier = new HostnameVerifier() {
64
65                         public boolean verify(String hostname, SSLSession session) {
66
67                                 return true;
68                         }
69                 };
70
71                 if (protocol == null || protocol.isEmpty() || protocol.equals(Constants.HTTP)) {
72                         backendHttpClient = HttpClients.createDefault();
73                         this.backendHost = Constants.HTTP + "://" + backendHost;
74                 } else {
75                         // NULL can be returned in case of error
76                         backendHttpClient = getSslClient();
77                         this.backendHost = Constants.HTTPS + "://" + backendHost;
78                 }
79
80         }
81
82         public HostnameVerifier getHostnameVerifier() {
83                 return hostnameVerifier;
84         }
85
86         private CloseableHttpClient getSslClient() {
87
88                 CloseableHttpClient httpClient = null;
89                 try {
90
91                         // SSLContextBuilder is not thread safe
92                         SSLContextBuilder builder = new SSLContextBuilder();
93                         builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
94                         SSLContext sslContext = builder.build();
95
96                         httpClient = HttpClientBuilder.create().setSSLHostnameVerifier(hostnameVerifier).setSslcontext(sslContext)
97                                         .build();
98
99                 } catch (Exception e) {
100                         log.error("Failed to create https client", e);
101                         return null;
102                 }
103
104                 return httpClient;
105
106         }
107
108         public ResponseInfo forwardRequestToBackend(HttpRequestInfo requestInfo, List<String> requiredHeaders,
109                         AsyncResponse asyncResponse) {
110
111                 ResponseInfo responseInfo = null;
112                 log.debug("forwardRequestToBackend");
113                 if (backendHttpClient == null) {
114                         responseInfo = new ResponseInfo(ResponseStatusEnum.INTERNAL_ERROR, "Failed to create https client");
115                         Audit.error(log, requestInfo, HttpStatus.SC_INTERNAL_SERVER_ERROR);
116                         asyncResponse.resume(
117                                         Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(responseInfo.toString()).build());
118                         return responseInfo;
119                 }
120
121                 CloseableHttpResponse response = null;
122                 int status = HttpStatus.SC_INTERNAL_SERVER_ERROR;
123                 HttpPost httpPost = new HttpPost(backendHost + backendContext);
124                 try {
125
126                         log.debug("Executing request {}", httpPost.getRequestLine());
127                         httpPost.setEntity(new InputStreamEntity(requestInfo.getRequestData()));
128                         boolean allHeadersAreSet = copyHeadersToRequest(requiredHeaders, requestInfo, httpPost);
129                         if (!allHeadersAreSet) {
130                                 responseInfo = new ResponseInfo(ResponseStatusEnum.MISSING_HEADERS, "Required headers are missing");
131                                 asyncResponse
132                                                 .resume(Response.status(HttpStatus.SC_BAD_REQUEST).entity(responseInfo.toString()).build());
133                                 Audit.error(log, requestInfo, HttpStatus.SC_BAD_REQUEST);
134                         } else {
135                                 response = backendHttpClient.execute(httpPost);
136                                 status = response.getStatusLine().getStatusCode();
137                                 asyncResponse.resume(Response.status(status).entity(response.getEntity()).build());
138                         }
139                         Audit.info(log, requestInfo, status);
140
141                 } catch (IOException e) {
142                         log.error("connection with backend failed with exception", e);
143                         responseInfo = new ResponseInfo(ResponseStatusEnum.INTERNAL_ERROR, e.getMessage());
144                         Audit.error(log, requestInfo, HttpStatus.SC_INTERNAL_SERVER_ERROR);
145                         asyncResponse.resume(
146                                         Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(responseInfo.toString()).build());
147                 } finally {
148                         try {
149                                 if (response != null) {
150                                         response.close();
151                                 }
152                                 backendHttpClient.close();
153                         } catch (IOException e) {
154                                 log.error("failed to close httpClient: {}", e.getMessage());
155                         }
156
157                 }
158
159                 return responseInfo;
160
161         }
162
163         private boolean copyHeadersToRequest(List<String> requiredHeaders, HttpRequestInfo requestInfo, HttpPost httpPost) {
164                 boolean allHeadersAreSet = false;
165                 Map<String, String> originalHeaders = requestInfo.getHeaders();
166                 for (String headerName : requiredHeaders) {
167                         String headerValue = originalHeaders.get(headerName);
168                         if (headerValue != null) {
169                                 httpPost.setHeader(headerName, headerValue);
170                         } else {
171                                 log.error("missing required header {}", headerName);
172                                 return allHeadersAreSet;
173                         }
174                 }
175                 allHeadersAreSet = true;
176                 return allHeadersAreSet;
177         }
178
179 }