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) 2019 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.LoggingAnchor;
49 import org.onap.so.logger.ErrorCode;
50 import org.onap.so.utils.CryptoUtils;
51 import org.onap.so.adapters.sdnc.SDNCAdapterRequest;
52 import org.onap.so.adapters.sdnc.client.CallbackHeader;
53 import org.onap.so.adapters.sdnc.client.SDNCAdapterCallbackRequest;
54 import org.onap.so.adapters.sdnc.client.SDNCCallbackAdapterPortType;
55 import org.onap.so.adapters.sdnc.client.SDNCCallbackAdapterService;
56 import org.onap.so.logger.MessageEnum;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59 import org.springframework.beans.factory.annotation.Autowired;
60 import org.springframework.core.env.Environment;
61 import org.springframework.scheduling.annotation.Async;
62 import org.springframework.stereotype.Component;
63 import org.w3c.dom.Document;
64 import org.w3c.dom.Element;
65 import org.w3c.dom.Node;
66 import org.w3c.dom.NodeList;
70 public class SDNCRestClient {
73 private Environment env;
76 private MapRequestTunables tunablesMapper;
78 private static Logger logger = LoggerFactory.getLogger(SDNCRestClient.class);
80 private static final String EXCEPTION_MSG = "Exception while evaluate xpath";
81 private static final String CAMUNDA = "Camunda";
84 public void executeRequest(SDNCAdapterRequest bpelRequest) {
86 logger.debug("BPEL Request: {}", bpelRequest);
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(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION.toString(), "SDNC",
94 ErrorCode.UnknownError.getValue(), "Exception processing request to SDNC", e);
96 Thread.currentThread().interrupt();
99 String bpelReqId = bpelRequest.getRequestHeader().getRequestId();
100 String callbackUrl = bpelRequest.getRequestHeader().getCallbackUrl();
102 String sdncReqBody = null;
104 RequestTunables rt = new RequestTunables(bpelReqId, bpelRequest.getRequestHeader().getMsoAction(),
105 bpelRequest.getRequestHeader().getSvcOperation(), bpelRequest.getRequestHeader().getSvcAction());
106 rt = tunablesMapper.setTunables(rt);
107 rt.setSdncaNotificationUrl(env.getProperty(Constants.MY_URL_PROP));
110 if ("POST".equals(rt.getReqMethod())) {
111 Node node = (Node) bpelRequest.getRequestData();
112 Document reqDoc = node.getOwnerDocument();
113 sdncReqBody = Utils.genSdncReq(reqDoc, rt);
114 } else if ("PUT".equals(rt.getReqMethod())) {
115 Node node = (Node) bpelRequest.getRequestData();
116 Document reqDoc = node.getOwnerDocument();
117 sdncReqBody = Utils.genSdncPutReq(reqDoc, rt);
119 SDNCResponse sdncResp = getSdncResp(sdncReqBody, rt);
120 logger.debug("Got the SDNC Response: {}", sdncResp.getSdncRespXml());
121 sendRespToBpel(callbackUrl, sdncResp);
124 public SDNCResponse getSdncResp(String sdncReqBody, RequestTunables rt) {
127 HttpURLConnection con = null;
128 DataOutputStream out = null;
129 BufferedReader in = null;
130 SDNCResponse sdncResp = new SDNCResponse(rt.getReqId());
131 StringBuilder response = new StringBuilder();
133 logger.info("{} :\n {} {}", MessageEnum.RA_SEND_REQUEST_SDNC.name(), rt.toString(), "SDNC");
134 logger.trace("SDNC Request Body:{} \n", sdncReqBody);
138 url = new URL(rt.getSdncUrl());
140 con = (HttpURLConnection) url.openConnection();
141 con.setConnectTimeout(Integer.parseInt(env.getProperty(Constants.SDNC_CONNECTTIME_PROP)));
142 con.setReadTimeout(Integer.parseInt(rt.getTimeout()));
143 con.setRequestProperty("Accept", "application/yang.data+xml"); // for response in xml
144 String userCredentials = CryptoUtils.decrypt(env.getProperty(Constants.SDNC_AUTH_PROP),
145 env.getProperty(Constants.ENCRYPTION_KEY_PROP));
147 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
148 con.setRequestProperty("Authorization", basicAuth);
149 con.setRequestMethod(rt.getReqMethod());
151 // Add request headers
152 if ("POST".equals(rt.getReqMethod()) || "PUT".equals(rt.getReqMethod())) {
153 con.setRequestProperty("Content-type", "application/xml");
154 con.setRequestProperty("Content-length", String.valueOf(sdncReqBody.length()));
155 con.setDoOutput(true);
156 out = new DataOutputStream(con.getOutputStream());
157 out.writeBytes(sdncReqBody);
163 sdncResp.setRespCode(con.getResponseCode());
164 sdncResp.setRespMsg(con.getResponseMessage());
166 if (con.getResponseCode() >= 200 && con.getResponseCode() <= 299) {
167 in = new BufferedReader(new InputStreamReader(con.getInputStream()));
169 // Not parsing the response -it contains a responseHdr section and data section
170 while ((inputLine = in.readLine()) != null) {
171 response.append(inputLine);
176 sdncResp.setSdncRespXml(response.toString());
177 logger.info("{} :\n {} {}", MessageEnum.RA_RESPONSE_FROM_SDNC.name(), sdncResp.toString(), "SDNC");
179 } catch (Exception e) {
180 logger.error(LoggingAnchor.FOUR, MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC.toString(), "SDNC",
181 ErrorCode.BusinessProcesssError.getValue(), "Exception processing request to SDNC", e);
183 sdncResp.setRespCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
184 String respMsg = "Error processing request to SDNC. ";
185 StringBuilder sdncErrMsg = new StringBuilder();
187 if (e instanceof java.net.SocketTimeoutException) {
188 sdncResp.setRespCode(HttpURLConnection.HTTP_CLIENT_TIMEOUT);
189 respMsg = "Request to SDNC timed out. ";
193 if (con.getResponseCode() != HttpURLConnection.HTTP_OK) // seen in SocketException connection reset
194 sdncResp.setRespCode(con.getResponseCode());
195 respMsg = respMsg + con.getResponseMessage() + ". ";
196 InputStream is = con.getErrorStream();
198 XPathFactory xpathFactory = XPathFactory.newInstance();
199 XPath xpath = xpathFactory.newXPath();
200 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
201 dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
202 dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
203 dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
207 db = dbf.newDocumentBuilder();
209 NodeList errors = (NodeList) xpath.evaluate("errors/error", doc, XPathConstants.NODESET);
210 for (int i = 0; i < errors.getLength(); i++) {
211 Element error = (Element) errors.item(i);
214 eType = xpath.evaluate("error-type", error);
215 sdncErrMsg = new StringBuilder(". SDNC Returned-[error-type:" + eType);
216 } catch (Exception e3) {
217 logger.error(LoggingAnchor.SIX, MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
218 "error-type", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
224 eTag = xpath.evaluate("error-tag", error);
225 sdncErrMsg.append(", error-tag:").append(eTag);
226 } catch (Exception e3) {
227 logger.error(LoggingAnchor.SIX, MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
228 "error-tag", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
234 eMsg = xpath.evaluate("error-message", error);
235 sdncErrMsg.append(", error-message:").append(eMsg).append("]");
236 } catch (Exception e3) {
237 logger.error(LoggingAnchor.SIX, MessageEnum.RA_EVALUATE_XPATH_ERROR.toString(),
238 "error-message", error.toString(), "SDNC", ErrorCode.DataError.getValue(),
242 } catch (Exception e2) {
243 logger.error(LoggingAnchor.FOUR, MessageEnum.RA_ANALYZE_ERROR_EXC.toString(), "SDNC",
244 ErrorCode.DataError.getValue(), "Exception while analyse error", e2);
247 } catch (Exception e1) {
248 logger.error(LoggingAnchor.FOUR, MessageEnum.RA_ERROR_GET_RESPONSE_SDNC.toString(), "SDNC",
249 ErrorCode.BusinessProcesssError.getValue(), "Exception while get SDNC response", e1);
253 if (e.getMessage() != null) {
254 respMsg = respMsg + e.getMessage();
256 respMsg = respMsg + sdncErrMsg;
258 sdncResp.setRespMsg(respMsg);
260 logger.error(LoggingAnchor.FOUR, MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC.toString(), "SDNC",
261 ErrorCode.AvailabilityError.getValue(), "Exception while communicate with SDNC", e);
271 public void sendRespToBpel(String bpelUrl, SDNCResponse sdncResp) {
274 SDNCAdapterCallbackRequest cbReq = new SDNCAdapterCallbackRequest();
275 cbReq.setCallbackHeader(new CallbackHeader(sdncResp.getReqId(), Integer.toString(sdncResp.getRespCode()),
276 sdncResp.getRespMsg()));
277 if (sdncResp.getSdncRespXml() != null) {
278 cbReq.setRequestData(sdncResp.getSdncRespXml());
280 logger.info("{} :\n {} {}", MessageEnum.RA_CALLBACK_BPEL.name(), cbReq.toString(), CAMUNDA);
284 wsdlUrl = new URL(bpelUrl);
285 } catch (MalformedURLException e1) {
286 logger.error(LoggingAnchor.FOUR, MessageEnum.RA_INIT_CALLBACK_WSDL_ERR.toString(), CAMUNDA,
287 ErrorCode.DataError.getValue(), "Exception initializing Callback wsdl", e1);
291 SDNCCallbackAdapterService cbSvc = new SDNCCallbackAdapterService();
293 SDNCCallbackAdapterPortType cbPort = cbSvc.getSDNCCallbackAdapterSoapHttpPort();
295 BindingProvider bp = (BindingProvider) cbPort;
297 if (null != wsdlUrl) {
298 bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlUrl.toExternalForm());
300 logger.debug("wsdlUrl is NULL:");
305 Map<String, Object> reqCtx = bp.getRequestContext();
306 Map<String, List<String>> headers = new HashMap<>();
307 String userCredentials = CryptoUtils.decrypt(env.getProperty(Constants.BPEL_AUTH_PROP),
308 env.getProperty(Constants.ENCRYPTION_KEY_PROP));
310 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
311 reqCtx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
312 headers.put("Authorization", Collections.singletonList(basicAuth));
313 } catch (Exception e2) {
314 logger.error(LoggingAnchor.FOUR, MessageEnum.RA_SET_CALLBACK_AUTH_EXC.toString(), CAMUNDA,
315 ErrorCode.BusinessProcesssError.getValue(),
316 "Exception - Unable to set authorization in callback request", e2);
320 logger.debug("Invoking Bpel Callback. BpelCallbackUrl:{}", bpelUrl);
321 cbPort.sdncAdapterCallback(cbReq);
323 } catch (Exception e) {
324 error = "Error sending BpelCallback request" + e.getMessage();
325 logger.error("Error {} - {} - {}", ErrorCode.BusinessProcesssError.getValue(),
326 MessageEnum.RA_CALLBACK_BPEL_EXC.toString(), error, e);
328 logger.info(MessageEnum.RA_CALLBACK_BPEL_COMPLETE.name(), CAMUNDA);