2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.mso.adapters.sdnc.impl;
24 import java.io.BufferedReader;
25 import java.io.DataOutputStream;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.net.HttpURLConnection;
29 import java.net.MalformedURLException;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.List;
37 import javax.xml.XMLConstants;
38 import javax.xml.bind.DatatypeConverter;
39 import javax.xml.parsers.DocumentBuilder;
40 import javax.xml.parsers.DocumentBuilderFactory;
41 import javax.xml.ws.BindingProvider;
42 import javax.xml.ws.handler.MessageContext;
43 import javax.xml.xpath.XPath;
44 import javax.xml.xpath.XPathConstants;
45 import javax.xml.xpath.XPathFactory;
47 import org.w3c.dom.Document;
48 import org.w3c.dom.Element;
49 import org.w3c.dom.Node;
50 import org.w3c.dom.NodeList;
52 import org.openecomp.mso.adapters.sdnc.SDNCAdapterRequest;
53 import org.openecomp.mso.adapters.sdnc.client.CallbackHeader;
54 import org.openecomp.mso.adapters.sdnc.client.SDNCAdapterCallbackRequest;
55 import org.openecomp.mso.adapters.sdnc.client.SDNCCallbackAdapterPortType;
56 import org.openecomp.mso.adapters.sdnc.client.SDNCCallbackAdapterService;
57 import org.openecomp.mso.adapters.sdnc.util.SDNCRequestIdUtil;
58 import org.openecomp.mso.logger.MsoAlarmLogger;
59 import org.openecomp.mso.logger.MsoLogger;
60 import org.openecomp.mso.logger.MessageEnum;
61 import org.openecomp.mso.properties.MsoJavaProperties;
62 import org.openecomp.mso.properties.MsoPropertiesFactory;
64 //SDNCAdapter to SDNC Rest Client
65 public class SDNCRestClient implements Runnable {
67 private MsoPropertiesFactory msoPropertiesFactory;
69 private SDNCAdapterRequest bpelRequest;
71 private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
72 private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger();
73 public static final String MSO_PROP_SDNC_ADAPTER="MSO_PROP_SDNC_ADAPTER";
76 public SDNCRestClient(SDNCAdapterRequest bpelRequest,MsoPropertiesFactory msoPropFactory) {
77 this.bpelRequest = bpelRequest;
78 msoPropertiesFactory = msoPropFactory;
85 String action = bpelRequest.getRequestHeader().getSvcAction();
86 String operation = bpelRequest.getRequestHeader().getSvcOperation();
87 String bpelReqId = bpelRequest.getRequestHeader().getRequestId();
88 String callbackUrl = bpelRequest.getRequestHeader().getCallbackUrl();
89 MsoLogger.setLogContext(SDNCRequestIdUtil.getSDNCOriginalRequestId (bpelReqId), bpelRequest.getRequestHeader().getSvcInstanceId());
90 MsoLogger.setServiceName("SDNCRestClient");
92 String sdncReqBody = null;
94 msoLogger.debug("BPEL Request:" + bpelRequest.toString());
96 RequestTunables rt = new RequestTunables(bpelReqId,
97 bpelRequest.getRequestHeader().getMsoAction(),
98 bpelRequest.getRequestHeader().getSvcOperation(),
99 bpelRequest.getRequestHeader().getSvcAction(),msoPropertiesFactory);
101 rt.setSdncaNotificationUrl(SDNCAdapterPortTypeImpl.getProperty(Constants.MY_URL_PROP, Constants.DEFAULT_MY_URL,msoPropertiesFactory));
104 if ("POST".equals(rt.getReqMethod()))
108 RequestsDatabase.updateBpelUrl(bpelReqId, callbackUrl);
112 logger.error("Failed to update DB ActiveRequests with SDNC_CALLBACK_BPEL_URL. Default CallbackUrl will be used for SDNC async notifications", e1);
116 Node node = (Node) bpelRequest.getRequestData();
117 Document reqDoc = node.getOwnerDocument();
118 sdncReqBody = Utils.genSdncReq(reqDoc, rt);
121 //should be more generic if we do RPC then we add the input tags etc, if it is pure REST this is not needed
122 else if("PUT".equals(rt.getReqMethod())){
123 Node node = (Node) bpelRequest.getRequestData();
124 Document reqDoc = node.getOwnerDocument();
125 sdncReqBody = Utils.genSdncPutReq(reqDoc, rt);
127 long sdncStartTime = System.currentTimeMillis();
128 SDNCResponse sdncResp = getSdncResp(sdncReqBody, rt, msoPropertiesFactory);
129 msoLogger.recordMetricEvent (sdncStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from SDNC", "SDNC", action + "." + operation, null);
131 msoLogger.debug ("Got the SDNC Response: " + sdncResp.getSdncRespXml());
132 msoLogger.debug("Sending reponse to bpel from SDNC rest client");
133 long bpelStartTime = System.currentTimeMillis();
134 sendRespToBpel(callbackUrl, sdncResp,msoPropertiesFactory);
135 msoLogger.recordMetricEvent (bpelStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully send reauest to BPEL", "BPMN", callbackUrl, null);
139 public static SDNCResponse getSdncResp(String sdncReqBody, RequestTunables rt, MsoPropertiesFactory msoPropertiesFactoryp)
143 HttpURLConnection con = null;
144 DataOutputStream out = null;
145 BufferedReader in = null;
146 SDNCResponse sdncResp = new SDNCResponse(rt.getReqId());
147 StringBuffer response = new StringBuffer();
149 msoLogger.info(MessageEnum.RA_SEND_REQUEST_SDNC, rt.toString(), "SDNC", "");
150 msoLogger.debug("SDNC Request Body:\n" + sdncReqBody);
154 url = new URL(rt.getSdncUrl());
156 con = (HttpURLConnection) url.openConnection();
157 con.setConnectTimeout(Integer.parseInt(SDNCAdapterPortTypeImpl.getProperty(Constants.SDNC_CONNECTTIME_PROP, "2000",msoPropertiesFactoryp)));
158 con.setReadTimeout(Integer.parseInt(rt.getTimeout()));
159 con.setRequestProperty("Accept", "application/yang.data+xml"); //for response in xml
160 String userCredentials = msoPropertiesFactoryp.getMsoJavaProperties(MSO_PROP_SDNC_ADAPTER).getEncryptedProperty(Constants.SDNC_AUTH_PROP, Constants.DEFAULT_SDNC_AUTH, Constants.ENCRYPTION_KEY);
162 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
163 con.setRequestProperty ("Authorization", basicAuth);
164 con.setRequestMethod(rt.getReqMethod());
166 // Add request headers
167 if ("POST".equals(rt.getReqMethod()) || "PUT".equals(rt.getReqMethod()))
169 con.setRequestProperty("Content-type", "application/xml");
170 con.setRequestProperty("Content-length",String.valueOf(sdncReqBody.length()));
171 con.setDoOutput(true);
172 out = new DataOutputStream(con.getOutputStream());
173 out.writeBytes(sdncReqBody);
179 sdncResp.setRespCode(con.getResponseCode());
180 sdncResp.setRespMsg(con.getResponseMessage());
182 in = new BufferedReader(new InputStreamReader(con.getInputStream()));
185 //Not parsing the response -it contains a responseHdr section and data section
186 while ((inputLine = in.readLine()) != null) {
187 response.append(inputLine);
191 sdncResp.setSdncRespXml(response.toString());
192 msoLogger.info(MessageEnum.RA_RESPONSE_FROM_SDNC, sdncResp.toString(), "SDNC", "");
197 msoLogger.error(MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception processing request to SDNC", e);
199 sdncResp.setRespCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
200 String respMsg = "Error processing request to SDNC. ";
201 String sdncErrMsg = null;
203 if (e instanceof java.net.SocketTimeoutException )
205 sdncResp.setRespCode(HttpURLConnection.HTTP_CLIENT_TIMEOUT);
206 respMsg = "Request to SDNC timed out. ";
211 if (con.getResponseCode() != HttpURLConnection.HTTP_OK) //seen in SocketException connection reset
212 sdncResp.setRespCode(con.getResponseCode());
213 respMsg = respMsg + con.getResponseMessage() + ". ";
214 InputStream is = con.getErrorStream();
217 XPathFactory xpathFactory = XPathFactory.newInstance();
218 XPath xpath = xpathFactory.newXPath();
219 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
220 dbf.setFeature (XMLConstants.FEATURE_SECURE_PROCESSING, true);
224 db = dbf.newDocumentBuilder();
226 NodeList errors = (NodeList)xpath.evaluate("errors/error", doc, XPathConstants.NODESET);
227 for (int i = 0; i < errors.getLength(); i++)
229 Element error = (Element) errors.item(i);
232 eType = xpath.evaluate("error-type", error);
233 sdncErrMsg = ". SDNC Returned-[error-type:" + eType;
234 } catch (Exception e3) {
235 msoLogger.error (MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-type", error.toString(), "SDNC", "", MsoLogger.ErrorCode.DataError, "Exception while evaluate xpath", e3);
240 eTag = xpath.evaluate( "error-tag", error);
241 sdncErrMsg = sdncErrMsg + ", error-tag:" + eTag;
242 } catch (Exception e3) {
243 msoLogger.error (MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-tag", error.toString(), "SDNC", "", MsoLogger.ErrorCode.DataError, "Exception while evaluate xpath", e3);
248 eMsg = xpath.evaluate("error-message", error);
249 sdncErrMsg = sdncErrMsg + ", error-message:" + eMsg + "]";
250 } catch (Exception e3) {
251 msoLogger.error (MessageEnum.RA_EVALUATE_XPATH_ERROR, "error-message", error.toString(), "SDNC", "", MsoLogger.ErrorCode.DataError, "Exception while evaluate xpath", e3);
254 } catch (Exception e2) {
255 msoLogger.error (MessageEnum.RA_ANALYZE_ERROR_EXC, "SDNC", "", MsoLogger.ErrorCode.DataError, "Exception while analyse error", e2);
258 } catch (Exception e1) {
259 msoLogger.error (MessageEnum.RA_ERROR_GET_RESPONSE_SDNC, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while get SDNC response", e1);
263 if (e.getMessage() != null) {
264 respMsg = respMsg + e.getMessage();
266 if (sdncErrMsg != null) {
267 respMsg = respMsg + sdncErrMsg;
270 sdncResp.setRespMsg(respMsg);
272 msoLogger.error(MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC, "SDNC", "", MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with SDNC", e);
273 alarmLogger.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, respMsg);
284 public static void sendRespToBpel(String bpelUrl, SDNCResponse sdncResp,MsoPropertiesFactory msoPropertiesFactoryp)
289 SDNCAdapterCallbackRequest cbReq = new SDNCAdapterCallbackRequest();
290 cbReq.setCallbackHeader(new CallbackHeader(sdncResp.getReqId(), Integer.toString(sdncResp.getRespCode()), sdncResp.getRespMsg()));
291 if (sdncResp.getSdncRespXml() != null)
293 cbReq.setRequestData(sdncResp.getSdncRespXml());
295 msoLogger.info(MessageEnum.RA_CALLBACK_BPEL, cbReq.toString(), "Camunda", "");
299 wsdlUrl = new URL (bpelUrl);
300 } catch (MalformedURLException e1) {
301 error = "Caught exception initializing Callback wsdl " + e1.getMessage();
302 msoLogger.error(MessageEnum.RA_INIT_CALLBACK_WSDL_ERR, "Camunda", "", MsoLogger.ErrorCode.DataError, "Exception initializing Callback wsdl", e1);
303 alarmLogger.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
306 SDNCCallbackAdapterService cbSvc = new SDNCCallbackAdapterService();
308 SDNCCallbackAdapterPortType cbPort = cbSvc.getSDNCCallbackAdapterSoapHttpPort();
310 BindingProvider bp = (BindingProvider)cbPort;
312 bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlUrl.toExternalForm());
317 Map<String, Object> req_ctx = bp.getRequestContext();
318 Map<String, List<String>> headers = new HashMap<String, List<String>>();
319 String userCredentials = msoPropertiesFactoryp.getMsoJavaProperties(MSO_PROP_SDNC_ADAPTER).getEncryptedProperty(Constants.BPEL_AUTH_PROP, Constants.DEFAULT_BPEL_AUTH, Constants.ENCRYPTION_KEY);
321 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
322 req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
323 headers.put ("Authorization", Collections.singletonList(basicAuth));
325 catch (Exception e2) {
326 error = "Unable to set authorization in callback request " + e2.getMessage();
327 msoLogger.error(MessageEnum.RA_SET_CALLBACK_AUTH_EXC, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - Unable to set authorization in callback request", e2);
328 alarmLogger.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
331 msoLogger.debug("Invoking Bpel Callback. BpelCallbackUrl:" + bpelUrl);
332 cbPort.sdncAdapterCallback(cbReq);
337 error = "Error sending BpelCallback request" + e.getMessage();
338 msoLogger.error(MessageEnum.RA_CALLBACK_BPEL_EXC, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending BpelCallback request", e);
339 alarmLogger.sendAlarm("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
341 msoLogger.info(MessageEnum.RA_CALLBACK_BPEL_COMPLETE, "Camunda", "");