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 * ================================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ============LICENSE_END=========================================================
24 package org.onap.so.adapters.sdnc.impl;
27 import java.io.BufferedReader;
28 import java.io.DataOutputStream;
29 import java.io.InputStream;
30 import java.io.InputStreamReader;
31 import java.net.HttpURLConnection;
32 import java.net.MalformedURLException;
34 import java.util.Collections;
35 import java.util.HashMap;
36 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.utils.CryptoUtils;
49 import org.onap.so.adapters.sdnc.SDNCAdapterRequest;
50 import org.onap.so.adapters.sdnc.client.CallbackHeader;
51 import org.onap.so.adapters.sdnc.client.SDNCAdapterCallbackRequest;
52 import org.onap.so.adapters.sdnc.client.SDNCCallbackAdapterPortType;
53 import org.onap.so.adapters.sdnc.client.SDNCCallbackAdapterService;
54 import org.onap.so.logger.MessageEnum;
55 import org.onap.so.logger.MsoAlarmLogger;
56 import org.onap.so.logger.MsoLogger;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.core.env.Environment;
59 import org.springframework.scheduling.annotation.Async;
60 import org.springframework.stereotype.Component;
61 import org.w3c.dom.Document;
62 import org.w3c.dom.Element;
63 import org.w3c.dom.Node;
64 import org.w3c.dom.NodeList;
68 public class SDNCRestClient{
71 private Environment env;
74 private MapRequestTunables tunablesMapper;
76 private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA,SDNCRestClient.class);
77 private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger();
78 private static final String EXCEPTION_MSG="Exception while evaluate xpath";
79 private static final String MSO_INTERNAL_ERROR="MsoInternalError";
80 private static final String CAMUNDA="Camunda";
82 public void executeRequest(SDNCAdapterRequest bpelRequest)
85 msoLogger.debug("BPEL Request:" + bpelRequest.toString());
87 String action = bpelRequest.getRequestHeader().getSvcAction();
88 String operation = bpelRequest.getRequestHeader().getSvcOperation();
89 String bpelReqId = bpelRequest.getRequestHeader().getRequestId();
90 String callbackUrl = bpelRequest.getRequestHeader().getCallbackUrl();
92 String sdncReqBody = null;
96 RequestTunables rt = new RequestTunables(bpelReqId,
97 bpelRequest.getRequestHeader().getMsoAction(),
98 bpelRequest.getRequestHeader().getSvcOperation(),
99 bpelRequest.getRequestHeader().getSvcAction());
100 rt = tunablesMapper.setTunables(rt);
101 rt.setSdncaNotificationUrl(env.getProperty(Constants.MY_URL_PROP));
104 if ("POST".equals(rt.getReqMethod()))
106 Node node = (Node) bpelRequest.getRequestData();
107 Document reqDoc = node.getOwnerDocument();
108 sdncReqBody = Utils.genSdncReq(reqDoc, rt);
110 else if("PUT".equals(rt.getReqMethod())){
111 Node node = (Node) bpelRequest.getRequestData();
112 Document reqDoc = node.getOwnerDocument();
113 sdncReqBody = Utils.genSdncPutReq(reqDoc, rt);
115 long sdncStartTime = System.currentTimeMillis();
116 SDNCResponse sdncResp = getSdncResp(sdncReqBody, rt);
117 msoLogger.recordMetricEvent (sdncStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from SDNC", "SDNC", action + "." + operation, null);
118 msoLogger.debug ("Got the SDNC Response: " + sdncResp.getSdncRespXml());
119 long bpelStartTime = System.currentTimeMillis();
120 sendRespToBpel(callbackUrl, sdncResp);
121 msoLogger.recordMetricEvent (bpelStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully send reauest to BPEL", "BPMN", callbackUrl, null);
125 public SDNCResponse getSdncResp(String sdncReqBody, RequestTunables rt)
129 HttpURLConnection con = null;
130 DataOutputStream out = null;
131 BufferedReader in = null;
132 SDNCResponse sdncResp = new SDNCResponse(rt.getReqId());
133 StringBuilder response = new StringBuilder();
135 msoLogger.info(MessageEnum.RA_SEND_REQUEST_SDNC.name() + ":\n" + rt.toString(), "SDNC", "");
136 msoLogger.trace("SDNC Request Body:\n" + sdncReqBody);
140 url = new URL(rt.getSdncUrl());
142 con = (HttpURLConnection) url.openConnection();
143 con.setConnectTimeout(Integer.parseInt(env.getProperty(Constants.SDNC_CONNECTTIME_PROP)));
144 con.setReadTimeout(Integer.parseInt(rt.getTimeout()));
145 con.setRequestProperty("Accept", "application/yang.data+xml"); //for response in xml
146 String userCredentials = CryptoUtils.decryptProperty(env.getProperty(Constants.SDNC_AUTH_PROP), Constants.DEFAULT_SDNC_AUTH, Constants.ENCRYPTION_KEY);
148 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
149 con.setRequestProperty ("Authorization", basicAuth);
150 con.setRequestMethod(rt.getReqMethod());
152 // Add request headers
153 if ("POST".equals(rt.getReqMethod()) || "PUT".equals(rt.getReqMethod()))
155 con.setRequestProperty("Content-type", "application/xml");
156 con.setRequestProperty("Content-length",String.valueOf(sdncReqBody.length()));
157 con.setDoOutput(true);
158 out = new DataOutputStream(con.getOutputStream());
159 out.writeBytes(sdncReqBody);
165 sdncResp.setRespCode(con.getResponseCode());
166 sdncResp.setRespMsg(con.getResponseMessage());
168 if (con.getResponseCode()>= 200 && con.getResponseCode()<=299) {
169 in = new BufferedReader(new InputStreamReader(con.getInputStream()));
171 //Not parsing the response -it contains a responseHdr section and data section
172 while ((inputLine = in.readLine()) != null) {
173 response.append(inputLine);
178 sdncResp.setSdncRespXml(response.toString());
179 msoLogger.info(MessageEnum.RA_RESPONSE_FROM_SDNC.name() + ":\n" + sdncResp.toString(), "SDNC", "");
184 msoLogger.error(MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception processing request to SDNC", e);
186 sdncResp.setRespCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
187 String respMsg = "Error processing request to SDNC. ";
188 StringBuilder sdncErrMsg = new StringBuilder();
190 if (e instanceof java.net.SocketTimeoutException )
192 sdncResp.setRespCode(HttpURLConnection.HTTP_CLIENT_TIMEOUT);
193 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();
204 XPathFactory xpathFactory = XPathFactory.newInstance();
205 XPath xpath = xpathFactory.newXPath();
206 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
207 dbf.setFeature (XMLConstants.FEATURE_SECURE_PROCESSING, true);
208 dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
209 dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
213 db = dbf.newDocumentBuilder();
215 NodeList errors = (NodeList)xpath.evaluate("errors/error", doc, XPathConstants.NODESET);
216 for (int i = 0; i < errors.getLength(); i++)
218 Element error = (Element) errors.item(i);
221 eType = xpath.evaluate("error-type", error);
222 sdncErrMsg = new StringBuilder(". SDNC Returned-[error-type:" + eType);
223 } catch (Exception e3) {
224 msoLogger.error (MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-type", error.toString(), "SDNC", "", MsoLogger.ErrorCode.DataError, EXCEPTION_MSG, e3);
229 eTag = xpath.evaluate( "error-tag", error);
230 sdncErrMsg.append(", error-tag:").append(eTag);
231 } catch (Exception e3) {
232 msoLogger.error (MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-tag", error.toString(), "SDNC", "", MsoLogger.ErrorCode.DataError, EXCEPTION_MSG, e3);
237 eMsg = xpath.evaluate("error-message", error);
238 sdncErrMsg.append(", error-message:").append(eMsg).append("]");
239 } catch (Exception e3) {
240 msoLogger.error (MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-message", error.toString(), "SDNC", "", MsoLogger.ErrorCode.DataError, EXCEPTION_MSG, e3);
243 } catch (Exception e2) {
244 msoLogger.error (MessageEnum.RA_ANALYZE_ERROR_EXC, "SDNC", "", MsoLogger.ErrorCode.DataError, "Exception while analyse error", e2);
247 } catch (Exception e1) {
248 msoLogger.error (MessageEnum.RA_ERROR_GET_RESPONSE_SDNC, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while get SDNC response", e1);
252 if (e.getMessage() != null) {
253 respMsg = respMsg + e.getMessage();
255 respMsg = respMsg + sdncErrMsg;
257 sdncResp.setRespMsg(respMsg);
259 msoLogger.error(MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC, "SDNC", "", MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with SDNC", e);
260 alarmLogger.sendAlarm(MSO_INTERNAL_ERROR, MsoAlarmLogger.CRITICAL, respMsg);
271 public void sendRespToBpel(String bpelUrl, SDNCResponse sdncResp)
276 SDNCAdapterCallbackRequest cbReq = new SDNCAdapterCallbackRequest();
277 cbReq.setCallbackHeader(new CallbackHeader(sdncResp.getReqId(), Integer.toString(sdncResp.getRespCode()), sdncResp.getRespMsg()));
278 if (sdncResp.getSdncRespXml() != null)
280 cbReq.setRequestData(sdncResp.getSdncRespXml());
282 msoLogger.info(MessageEnum.RA_CALLBACK_BPEL.name() + ":\n" + cbReq.toString(), CAMUNDA, "");
286 wsdlUrl = new URL (bpelUrl);
287 } catch (MalformedURLException e1) {
288 error = "Caught exception initializing Callback wsdl " + e1.getMessage();
289 msoLogger.error(MessageEnum.RA_INIT_CALLBACK_WSDL_ERR, CAMUNDA, "", MsoLogger.ErrorCode.DataError, "Exception initializing Callback wsdl", e1);
290 alarmLogger.sendAlarm(MSO_INTERNAL_ERROR, MsoAlarmLogger.CRITICAL, error);
293 SDNCCallbackAdapterService cbSvc = new SDNCCallbackAdapterService();
295 SDNCCallbackAdapterPortType cbPort = cbSvc.getSDNCCallbackAdapterSoapHttpPort();
297 BindingProvider bp = (BindingProvider)cbPort;
299 if(null != wsdlUrl) {
300 bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlUrl.toExternalForm());
303 msoLogger.debug("wsdlUrl is NULL:");
309 Map<String, Object> reqCtx = bp.getRequestContext();
310 Map<String, List<String>> headers = new HashMap<>();
311 String userCredentials = CryptoUtils.decryptProperty(env.getProperty(Constants.BPEL_AUTH_PROP), Constants.DEFAULT_BPEL_AUTH, Constants.ENCRYPTION_KEY);
313 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
314 reqCtx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
315 headers.put ("Authorization", Collections.singletonList(basicAuth));
317 catch (Exception e2) {
318 error = "Unable to set authorization in callback request " + e2.getMessage();
319 msoLogger.error(MessageEnum.RA_SET_CALLBACK_AUTH_EXC, CAMUNDA, "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - Unable to set authorization in callback request", e2);
320 alarmLogger.sendAlarm(MSO_INTERNAL_ERROR, MsoAlarmLogger.CRITICAL, error);
323 msoLogger.debug("Invoking Bpel Callback. BpelCallbackUrl:" + bpelUrl);
324 cbPort.sdncAdapterCallback(cbReq);
329 error = "Error sending BpelCallback request" + e.getMessage();
330 msoLogger.error("Error " + MsoLogger.ErrorCode.BusinessProcesssError + " - " + MessageEnum.RA_CALLBACK_BPEL_EXC + " - " + error, e);
331 alarmLogger.sendAlarm(MSO_INTERNAL_ERROR, MsoAlarmLogger.CRITICAL, error);
333 msoLogger.info(MessageEnum.RA_CALLBACK_BPEL_COMPLETE.name(), CAMUNDA, "");