2 * ============LICENSE_START=======================================================
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
15 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
25 package org.onap.so.adapters.sdnc.impl;
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;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.List;
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;
69 public class SDNCRestClient {
72 private Environment env;
75 private MapRequestTunables tunablesMapper;
77 private static Logger logger = LoggerFactory.getLogger(SDNCRestClient.class);
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";
84 public void executeRequest(SDNCAdapterRequest bpelRequest) {
86 logger.debug("BPEL Request:" + bpelRequest.toString());
88 // Added delay to allow completion of create request to SDNC
89 // before executing activate of create request.
92 } catch (InterruptedException e) {
93 logger.error("{} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION.toString(), "SDNC",
94 ErrorCode.UnknownError.getValue(), "Exception processing request to SDNC", e);
96 Thread.currentThread().interrupt();
99 String action = bpelRequest.getRequestHeader().getSvcAction();
100 String operation = bpelRequest.getRequestHeader().getSvcOperation();
101 String bpelReqId = bpelRequest.getRequestHeader().getRequestId();
102 String callbackUrl = bpelRequest.getRequestHeader().getCallbackUrl();
104 String sdncReqBody = null;
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));
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);
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);
129 public SDNCResponse getSdncResp(String sdncReqBody, RequestTunables rt) {
132 HttpURLConnection con = null;
133 DataOutputStream out = null;
134 BufferedReader in = null;
135 SDNCResponse sdncResp = new SDNCResponse(rt.getReqId());
136 StringBuilder response = new StringBuilder();
138 logger.info("{} :\n {} {}", MessageEnum.RA_SEND_REQUEST_SDNC.name(), rt.toString(), "SDNC");
139 logger.trace("SDNC Request Body:{} \n", sdncReqBody);
143 url = new URL(rt.getSdncUrl());
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));
152 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
153 con.setRequestProperty("Authorization", basicAuth);
154 con.setRequestMethod(rt.getReqMethod());
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);
168 sdncResp.setRespCode(con.getResponseCode());
169 sdncResp.setRespMsg(con.getResponseMessage());
171 if (con.getResponseCode() >= 200 && con.getResponseCode() <= 299) {
172 in = new BufferedReader(new InputStreamReader(con.getInputStream()));
174 // Not parsing the response -it contains a responseHdr section and data section
175 while ((inputLine = in.readLine()) != null) {
176 response.append(inputLine);
181 sdncResp.setSdncRespXml(response.toString());
182 logger.info("{} :\n {} {}", MessageEnum.RA_RESPONSE_FROM_SDNC.name(), sdncResp.toString(), "SDNC");
184 } catch (Exception e) {
185 logger.error("{} {} {} {}", MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC.toString(), "SDNC",
186 ErrorCode.BusinessProcesssError.getValue(), "Exception processing request to SDNC", e);
188 sdncResp.setRespCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
189 String respMsg = "Error processing request to SDNC. ";
190 StringBuilder sdncErrMsg = new StringBuilder();
192 if (e instanceof java.net.SocketTimeoutException) {
193 sdncResp.setRespCode(HttpURLConnection.HTTP_CLIENT_TIMEOUT);
194 respMsg = "Request to SDNC timed out. ";
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();
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);
212 db = dbf.newDocumentBuilder();
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);
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(),
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(),
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(),
247 } catch (Exception e2) {
248 logger.error("{} {} {} {}", MessageEnum.RA_ANALYZE_ERROR_EXC.toString(), "SDNC",
249 ErrorCode.DataError.getValue(), "Exception while analyse error", e2);
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);
258 if (e.getMessage() != null) {
259 respMsg = respMsg + e.getMessage();
261 respMsg = respMsg + sdncErrMsg;
263 sdncResp.setRespMsg(respMsg);
265 logger.error("{} {} {} {}", MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC.toString(), "SDNC",
266 ErrorCode.AvailabilityError.getValue(), "Exception while communicate with SDNC", e);
276 public void sendRespToBpel(String bpelUrl, SDNCResponse sdncResp) {
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());
285 logger.info("{} :\n {} {}", MessageEnum.RA_CALLBACK_BPEL.name(), cbReq.toString(), CAMUNDA);
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);
297 SDNCCallbackAdapterService cbSvc = new SDNCCallbackAdapterService();
299 SDNCCallbackAdapterPortType cbPort = cbSvc.getSDNCCallbackAdapterSoapHttpPort();
301 BindingProvider bp = (BindingProvider) cbPort;
303 if (null != wsdlUrl) {
304 bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlUrl.toExternalForm());
306 logger.debug("wsdlUrl is NULL:");
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));
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);
327 logger.debug("Invoking Bpel Callback. BpelCallbackUrl:{}", bpelUrl);
328 cbPort.sdncAdapterCallback(cbReq);
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);
335 logger.info(MessageEnum.RA_CALLBACK_BPEL_COMPLETE.name(), CAMUNDA);