Replaced all tabs with spaces in java and pom.xml
[so.git] / adapters / mso-sdnc-adapter / src / main / java / org / onap / so / adapters / sdnc / impl / SDNCRestClient.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
7  * ================================================================================
8  * Modifications Copyright (C) 2018 IBM.
9  * Modifications Copyright (c) 2019 Samsung
10  * ================================================================================
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  * 
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  * 
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.so.adapters.sdnc.impl;
26
27
28 import java.io.BufferedReader;
29 import java.io.DataOutputStream;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.net.HttpURLConnection;
33 import java.net.MalformedURLException;
34 import java.net.URL;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 import javax.xml.XMLConstants;
40 import javax.xml.bind.DatatypeConverter;
41 import javax.xml.parsers.DocumentBuilder;
42 import javax.xml.parsers.DocumentBuilderFactory;
43 import javax.xml.ws.BindingProvider;
44 import javax.xml.ws.handler.MessageContext;
45 import javax.xml.xpath.XPath;
46 import javax.xml.xpath.XPathConstants;
47 import javax.xml.xpath.XPathFactory;
48 import org.onap.so.logger.ErrorCode;
49 import org.onap.so.utils.CryptoUtils;
50 import org.onap.so.adapters.sdnc.SDNCAdapterRequest;
51 import org.onap.so.adapters.sdnc.client.CallbackHeader;
52 import org.onap.so.adapters.sdnc.client.SDNCAdapterCallbackRequest;
53 import org.onap.so.adapters.sdnc.client.SDNCCallbackAdapterPortType;
54 import org.onap.so.adapters.sdnc.client.SDNCCallbackAdapterService;
55 import org.onap.so.logger.MessageEnum;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58 import org.springframework.beans.factory.annotation.Autowired;
59 import org.springframework.core.env.Environment;
60 import org.springframework.scheduling.annotation.Async;
61 import org.springframework.stereotype.Component;
62 import org.w3c.dom.Document;
63 import org.w3c.dom.Element;
64 import org.w3c.dom.Node;
65 import org.w3c.dom.NodeList;
66
67
68 @Component
69 public class SDNCRestClient {
70
71     @Autowired
72     private Environment env;
73
74     @Autowired
75     private MapRequestTunables tunablesMapper;
76
77     private static Logger logger = LoggerFactory.getLogger(SDNCRestClient.class);
78
79     private static final String EXCEPTION_MSG = "Exception while evaluate xpath";
80     private static final String MSO_INTERNAL_ERROR = "MsoInternalError";
81     private static final String CAMUNDA = "Camunda";
82
83     @Async
84     public void executeRequest(SDNCAdapterRequest bpelRequest) {
85
86         logger.debug("BPEL Request:" + bpelRequest.toString());
87
88         // Added delay to allow completion of create request to SDNC
89         // before executing activate of create request.
90         try {
91             Thread.sleep(5000);
92         } catch (InterruptedException e) {
93             logger.error("{} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION.toString(), "SDNC",
94                     ErrorCode.UnknownError.getValue(), "Exception processing request to SDNC", e);
95
96             Thread.currentThread().interrupt();
97         }
98
99         String action = bpelRequest.getRequestHeader().getSvcAction();
100         String operation = bpelRequest.getRequestHeader().getSvcOperation();
101         String bpelReqId = bpelRequest.getRequestHeader().getRequestId();
102         String callbackUrl = bpelRequest.getRequestHeader().getCallbackUrl();
103
104         String sdncReqBody = null;
105
106         RequestTunables rt = new RequestTunables(bpelReqId, bpelRequest.getRequestHeader().getMsoAction(),
107                 bpelRequest.getRequestHeader().getSvcOperation(), bpelRequest.getRequestHeader().getSvcAction());
108         rt = tunablesMapper.setTunables(rt);
109         rt.setSdncaNotificationUrl(env.getProperty(Constants.MY_URL_PROP));
110
111
112         if ("POST".equals(rt.getReqMethod())) {
113             Node node = (Node) bpelRequest.getRequestData();
114             Document reqDoc = node.getOwnerDocument();
115             sdncReqBody = Utils.genSdncReq(reqDoc, rt);
116         } else if ("PUT".equals(rt.getReqMethod())) {
117             Node node = (Node) bpelRequest.getRequestData();
118             Document reqDoc = node.getOwnerDocument();
119             sdncReqBody = Utils.genSdncPutReq(reqDoc, rt);
120         }
121         long sdncStartTime = System.currentTimeMillis();
122         SDNCResponse sdncResp = getSdncResp(sdncReqBody, rt);
123         logger.debug("Got the SDNC Response: {}", sdncResp.getSdncRespXml());
124         long bpelStartTime = System.currentTimeMillis();
125         sendRespToBpel(callbackUrl, sdncResp);
126         return;
127     }
128
129     public SDNCResponse getSdncResp(String sdncReqBody, RequestTunables rt) {
130
131         URL url;
132         HttpURLConnection con = null;
133         DataOutputStream out = null;
134         BufferedReader in = null;
135         SDNCResponse sdncResp = new SDNCResponse(rt.getReqId());
136         StringBuilder response = new StringBuilder();
137
138         logger.info("{} :\n {} {}", MessageEnum.RA_SEND_REQUEST_SDNC.name(), rt.toString(), "SDNC");
139         logger.trace("SDNC Request Body:{} \n", sdncReqBody);
140
141         try {
142
143             url = new URL(rt.getSdncUrl());
144
145             con = (HttpURLConnection) url.openConnection();
146             con.setConnectTimeout(Integer.parseInt(env.getProperty(Constants.SDNC_CONNECTTIME_PROP)));
147             con.setReadTimeout(Integer.parseInt(rt.getTimeout()));
148             con.setRequestProperty("Accept", "application/yang.data+xml"); // for response in xml
149             String userCredentials = CryptoUtils.decrypt(env.getProperty(Constants.SDNC_AUTH_PROP),
150                     env.getProperty(Constants.ENCRYPTION_KEY_PROP));
151
152             String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
153             con.setRequestProperty("Authorization", basicAuth);
154             con.setRequestMethod(rt.getReqMethod());
155
156             // Add request headers
157             if ("POST".equals(rt.getReqMethod()) || "PUT".equals(rt.getReqMethod())) {
158                 con.setRequestProperty("Content-type", "application/xml");
159                 con.setRequestProperty("Content-length", String.valueOf(sdncReqBody.length()));
160                 con.setDoOutput(true);
161                 out = new DataOutputStream(con.getOutputStream());
162                 out.writeBytes(sdncReqBody);
163                 out.flush();
164                 out.close();
165             }
166
167             // Get response
168             sdncResp.setRespCode(con.getResponseCode());
169             sdncResp.setRespMsg(con.getResponseMessage());
170
171             if (con.getResponseCode() >= 200 && con.getResponseCode() <= 299) {
172                 in = new BufferedReader(new InputStreamReader(con.getInputStream()));
173                 String inputLine;
174                 // Not parsing the response -it contains a responseHdr section and data section
175                 while ((inputLine = in.readLine()) != null) {
176                     response.append(inputLine);
177                 }
178                 in.close();
179             }
180
181             sdncResp.setSdncRespXml(response.toString());
182             logger.info("{} :\n {} {}", MessageEnum.RA_RESPONSE_FROM_SDNC.name(), sdncResp.toString(), "SDNC");
183             return (sdncResp);
184         } catch (Exception e) {
185             logger.error("{} {} {} {}", MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC.toString(), "SDNC",
186                     ErrorCode.BusinessProcesssError.getValue(), "Exception processing request to SDNC", e);
187             // default
188             sdncResp.setRespCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
189             String respMsg = "Error processing request to SDNC. ";
190             StringBuilder sdncErrMsg = new StringBuilder();
191
192             if (e instanceof java.net.SocketTimeoutException) {
193                 sdncResp.setRespCode(HttpURLConnection.HTTP_CLIENT_TIMEOUT);
194                 respMsg = "Request to SDNC timed out. ";
195             }
196             if (con != null) {
197                 try { // e1
198                     if (con.getResponseCode() != HttpURLConnection.HTTP_OK) // seen in SocketException connection reset
199                         sdncResp.setRespCode(con.getResponseCode());
200                     respMsg = respMsg + con.getResponseMessage() + ". ";
201                     InputStream is = con.getErrorStream();
202                     if (is != null) {
203                         XPathFactory xpathFactory = XPathFactory.newInstance();
204                         XPath xpath = xpathFactory.newXPath();
205                         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
206                         dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
207                         dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
208                         dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
209                         DocumentBuilder db;
210                         Document doc = null;
211                         try { // e2
212                             db = dbf.newDocumentBuilder();
213                             doc = db.parse(is);
214                             NodeList errors = (NodeList) xpath.evaluate("errors/error", doc, XPathConstants.NODESET);
215                             for (int i = 0; i < errors.getLength(); i++) {
216                                 Element error = (Element) errors.item(i);
217                                 String eType = null;
218                                 try {
219                                     eType = xpath.evaluate("error-type", error);
220                                     sdncErrMsg = new StringBuilder(". SDNC Returned-[error-type:" + eType);
221                                 } catch (Exception e3) {
222                                     logger.error("{} {} {} {} {} {}", MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
223                                             "error-type", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
224                                             EXCEPTION_MSG, e3);
225                                 }
226
227                                 String eTag = null;
228                                 try {
229                                     eTag = xpath.evaluate("error-tag", error);
230                                     sdncErrMsg.append(", error-tag:").append(eTag);
231                                 } catch (Exception e3) {
232                                     logger.error("{} {} {} {} {} {}", MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
233                                             "error-tag", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
234                                             EXCEPTION_MSG, e3);
235                                 }
236
237                                 String eMsg = null;
238                                 try {
239                                     eMsg = xpath.evaluate("error-message", error);
240                                     sdncErrMsg.append(", error-message:").append(eMsg).append("]");
241                                 } catch (Exception e3) {
242                                     logger.error("{} {} {} {} {} {}", MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
243                                             "error-message", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
244                                             EXCEPTION_MSG, e3);
245                                 }
246                             }
247                         } catch (Exception e2) {
248                             logger.error("{} {} {} {}", MessageEnum.RA_ANALYZE_ERROR_EXC.toString(), "SDNC",
249                                     ErrorCode.DataError.getValue(), "Exception while analyse error", e2);
250                         }
251                     } // is != null
252                 } catch (Exception e1) {
253                     logger.error("{} {} {} {}", MessageEnum.RA_ERROR_GET_RESPONSE_SDNC.toString(), "SDNC",
254                             ErrorCode.BusinessProcesssError.getValue(), "Exception while get SDNC response", e1);
255                 }
256             } // con != null
257
258             if (e.getMessage() != null) {
259                 respMsg = respMsg + e.getMessage();
260             }
261             respMsg = respMsg + sdncErrMsg;
262
263             sdncResp.setRespMsg(respMsg);
264
265             logger.error("{} {} {} {}", MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC.toString(), "SDNC",
266                     ErrorCode.AvailabilityError.getValue(), "Exception while communicate with SDNC", e);
267
268             return sdncResp;
269         } finally {
270             if (con != null) {
271                 con.disconnect();
272             }
273         }
274     }
275
276     public void sendRespToBpel(String bpelUrl, SDNCResponse sdncResp) {
277         String error;
278         try {
279             SDNCAdapterCallbackRequest cbReq = new SDNCAdapterCallbackRequest();
280             cbReq.setCallbackHeader(new CallbackHeader(sdncResp.getReqId(), Integer.toString(sdncResp.getRespCode()),
281                     sdncResp.getRespMsg()));
282             if (sdncResp.getSdncRespXml() != null) {
283                 cbReq.setRequestData(sdncResp.getSdncRespXml());
284             }
285             logger.info("{} :\n {} {}", MessageEnum.RA_CALLBACK_BPEL.name(), cbReq.toString(), CAMUNDA);
286
287             URL wsdlUrl = null;
288             try {
289                 wsdlUrl = new URL(bpelUrl);
290             } catch (MalformedURLException e1) {
291                 error = "Caught exception initializing Callback wsdl " + e1.getMessage();
292                 logger.error("{} {} {} {}", MessageEnum.RA_INIT_CALLBACK_WSDL_ERR.toString(), CAMUNDA,
293                         ErrorCode.DataError.getValue(), "Exception initializing Callback wsdl", e1);
294
295             }
296
297             SDNCCallbackAdapterService cbSvc = new SDNCCallbackAdapterService();
298
299             SDNCCallbackAdapterPortType cbPort = cbSvc.getSDNCCallbackAdapterSoapHttpPort();
300
301             BindingProvider bp = (BindingProvider) cbPort;
302
303             if (null != wsdlUrl) {
304                 bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlUrl.toExternalForm());
305             } else {
306                 logger.debug("wsdlUrl is NULL:");
307             }
308
309             // authentication
310             try {
311                 Map<String, Object> reqCtx = bp.getRequestContext();
312                 Map<String, List<String>> headers = new HashMap<>();
313                 String userCredentials = CryptoUtils.decrypt(env.getProperty(Constants.BPEL_AUTH_PROP),
314                         env.getProperty(Constants.ENCRYPTION_KEY_PROP));
315
316                 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
317                 reqCtx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
318                 headers.put("Authorization", Collections.singletonList(basicAuth));
319             } catch (Exception e2) {
320                 error = "Unable to set authorization in callback request " + e2.getMessage();
321                 logger.error("{} {} {} {}", MessageEnum.RA_SET_CALLBACK_AUTH_EXC.toString(), CAMUNDA,
322                         ErrorCode.BusinessProcesssError.getValue(),
323                         "Exception - Unable to set authorization in callback request", e2);
324
325             }
326
327             logger.debug("Invoking Bpel Callback. BpelCallbackUrl:{}", bpelUrl);
328             cbPort.sdncAdapterCallback(cbReq);
329
330         } catch (Exception e) {
331             error = "Error sending BpelCallback request" + e.getMessage();
332             logger.error("Error {} - {} - {}", ErrorCode.BusinessProcesssError.getValue(),
333                     MessageEnum.RA_CALLBACK_BPEL_EXC.toString(), error, e);
334         }
335         logger.info(MessageEnum.RA_CALLBACK_BPEL_COMPLETE.name(), CAMUNDA);
336         return;
337     }
338 }