Change the header to SO
[so.git] / adapters / mso-sdnc-adapter / src / main / java / org / openecomp / mso / 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  * ================================================================================
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.mso.adapters.sdnc.impl;
22
23
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;
30 import java.net.URL;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import javax.ejb.EJB;
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;
46
47 import org.w3c.dom.Document;
48 import org.w3c.dom.Element;
49 import org.w3c.dom.Node;
50 import org.w3c.dom.NodeList;
51 import org.openecomp.mso.adapters.sdnc.SDNCAdapterRequest;
52 import org.openecomp.mso.adapters.sdnc.client.CallbackHeader;
53 import org.openecomp.mso.adapters.sdnc.client.SDNCAdapterCallbackRequest;
54 import org.openecomp.mso.adapters.sdnc.client.SDNCCallbackAdapterPortType;
55 import org.openecomp.mso.adapters.sdnc.client.SDNCCallbackAdapterService;
56 import org.openecomp.mso.adapters.sdnc.util.SDNCRequestIdUtil;
57 import org.openecomp.mso.logger.MsoAlarmLogger;
58 import org.openecomp.mso.logger.MsoLogger;
59 import org.openecomp.mso.logger.MessageEnum;
60 import org.openecomp.mso.properties.MsoJavaProperties;
61 import org.openecomp.mso.properties.MsoPropertiesFactory;
62
63 //SDNCAdapter to SDNC Rest Client
64 public class SDNCRestClient implements Runnable {
65
66         private MsoPropertiesFactory msoPropertiesFactory;
67         
68         private SDNCAdapterRequest bpelRequest;
69
70         private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
71         private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger();
72         public static final String MSO_PROP_SDNC_ADAPTER="MSO_PROP_SDNC_ADAPTER";
73
74
75         public SDNCRestClient(SDNCAdapterRequest bpelRequest,MsoPropertiesFactory msoPropFactory) {
76                 this.bpelRequest = bpelRequest;
77                 msoPropertiesFactory = msoPropFactory;
78         }
79
80         @Override
81         public void run()
82         {
83
84                 String action = bpelRequest.getRequestHeader().getSvcAction();
85                 String operation = bpelRequest.getRequestHeader().getSvcOperation();
86                 String bpelReqId = bpelRequest.getRequestHeader().getRequestId();
87                 String callbackUrl = bpelRequest.getRequestHeader().getCallbackUrl();
88                 MsoLogger.setLogContext(SDNCRequestIdUtil.getSDNCOriginalRequestId (bpelReqId), bpelRequest.getRequestHeader().getSvcInstanceId());
89                 MsoLogger.setServiceName("SDNCRestClient");
90
91                 String sdncReqBody = null;
92
93                 msoLogger.debug("BPEL Request:" + bpelRequest.toString());
94
95                 RequestTunables rt = new RequestTunables(bpelReqId,
96                                 bpelRequest.getRequestHeader().getMsoAction(),
97                                 bpelRequest.getRequestHeader().getSvcOperation(),
98                                 bpelRequest.getRequestHeader().getSvcAction(),msoPropertiesFactory);
99                 rt.setTunables();
100                 rt.setSdncaNotificationUrl(SDNCAdapterPortTypeImpl.getProperty(Constants.MY_URL_PROP, Constants.DEFAULT_MY_URL,msoPropertiesFactory));
101
102
103                 if ("POST".equals(rt.getReqMethod()))
104                 {
105                         /* TODO Hibernate
106                         try {
107                                 RequestsDatabase.updateBpelUrl(bpelReqId, callbackUrl);
108                         }
109                         catch (Exception e1)
110                         {
111                                 logger.error("Failed to update DB ActiveRequests with SDNC_CALLBACK_BPEL_URL. Default CallbackUrl will be used for SDNC async notifications", e1);
112                         }
113                         */
114
115                         Node node = (Node)      bpelRequest.getRequestData();
116                 Document reqDoc = node.getOwnerDocument();
117                         sdncReqBody = Utils.genSdncReq(reqDoc, rt);
118
119                 }
120                 //should be more generic if we do RPC then we add the input tags etc, if it is pure REST this is not needed
121                 else if("PUT".equals(rt.getReqMethod())){
122                         Node node = (Node)      bpelRequest.getRequestData();
123                 Document reqDoc = node.getOwnerDocument();
124                         sdncReqBody = Utils.genSdncPutReq(reqDoc, rt);
125                 }
126                 long sdncStartTime = System.currentTimeMillis();
127                 SDNCResponse sdncResp = getSdncResp(sdncReqBody, rt, msoPropertiesFactory);
128                 msoLogger.recordMetricEvent (sdncStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from SDNC", "SDNC", action + "." + operation, null);
129
130                 msoLogger.debug ("Got the SDNC Response: " + sdncResp.getSdncRespXml());
131                 msoLogger.debug("Sending reponse to bpel from SDNC rest client");
132                 long bpelStartTime = System.currentTimeMillis();
133                 sendRespToBpel(callbackUrl, sdncResp,msoPropertiesFactory);
134                 msoLogger.recordMetricEvent (bpelStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully send reauest to BPEL", "BPMN", callbackUrl, null);
135                 return;
136         }
137
138         public static SDNCResponse getSdncResp(String sdncReqBody, RequestTunables rt, MsoPropertiesFactory msoPropertiesFactoryp)
139         {
140
141                 URL url;
142                 HttpURLConnection con = null;
143                 DataOutputStream out = null;
144                 BufferedReader in = null;
145                 SDNCResponse sdncResp = new SDNCResponse(rt.getReqId());
146                 StringBuffer response = new StringBuffer();
147
148                 msoLogger.info(MessageEnum.RA_SEND_REQUEST_SDNC, rt.toString(), "SDNC", "");
149                 msoLogger.debug("SDNC Request Body:\n" + sdncReqBody);
150
151                 try {
152
153                         url = new URL(rt.getSdncUrl());
154
155                         con = (HttpURLConnection) url.openConnection();
156                     con.setConnectTimeout(Integer.parseInt(SDNCAdapterPortTypeImpl.getProperty(Constants.SDNC_CONNECTTIME_PROP, "2000",msoPropertiesFactoryp)));
157                     con.setReadTimeout(Integer.parseInt(rt.getTimeout()));
158                         con.setRequestProperty("Accept", "application/yang.data+xml"); //for response in xml
159                         String userCredentials = msoPropertiesFactoryp.getMsoJavaProperties(MSO_PROP_SDNC_ADAPTER).getEncryptedProperty(Constants.SDNC_AUTH_PROP, Constants.DEFAULT_SDNC_AUTH, Constants.ENCRYPTION_KEY);
160
161                         String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
162                         con.setRequestProperty ("Authorization", basicAuth);
163                     con.setRequestMethod(rt.getReqMethod());
164
165                         // Add request headers
166                     if ("POST".equals(rt.getReqMethod()) || "PUT".equals(rt.getReqMethod()))
167                     {
168                         con.setRequestProperty("Content-type", "application/xml");
169                         con.setRequestProperty("Content-length",String.valueOf(sdncReqBody.length()));
170                                 con.setDoOutput(true);
171                                 out = new DataOutputStream(con.getOutputStream());
172                                 out.writeBytes(sdncReqBody);
173                                 out.flush();
174                                 out.close();
175                     }
176
177                         //Get response
178                         sdncResp.setRespCode(con.getResponseCode());
179                         sdncResp.setRespMsg(con.getResponseMessage());
180
181                         if (con.getResponseCode()>= 200 && con.getResponseCode()<=299) { 
182                                 in = new BufferedReader(new InputStreamReader(con.getInputStream()));   
183                                 String inputLine;
184                                 //Not parsing the response -it contains a responseHdr section and data section
185                                 while ((inputLine = in.readLine()) != null) {
186                                         response.append(inputLine);
187                                 }
188                                 in.close();
189                         }
190                         
191                         sdncResp.setSdncRespXml(response.toString());
192                         msoLogger.info(MessageEnum.RA_RESPONSE_FROM_SDNC, sdncResp.toString(), "SDNC", "");
193                         return(sdncResp);
194                 }
195                 catch (Exception e)
196                 {
197                         msoLogger.error(MessageEnum.RA_EXCEPTION_COMMUNICATE_SDNC, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception processing request to SDNC", e);
198                         //default
199                         sdncResp.setRespCode(HttpURLConnection.HTTP_INTERNAL_ERROR);
200                         String respMsg = "Error processing request to SDNC. ";
201                         String sdncErrMsg = null;
202
203                         if (e instanceof java.net.SocketTimeoutException )
204                         {
205                                 sdncResp.setRespCode(HttpURLConnection.HTTP_CLIENT_TIMEOUT);
206                                 respMsg = "Request to SDNC timed out. ";
207                         }
208                         if (con != null)
209                         {
210                                 try { //e1
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();
215                                         if (is != null)
216                                         {
217                                                 XPathFactory xpathFactory = XPathFactory.newInstance();
218                                             XPath xpath = xpathFactory.newXPath();
219                                                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
220                         dbf.setFeature (XMLConstants.FEATURE_SECURE_PROCESSING, true);
221                                                 DocumentBuilder db;
222                                                 Document doc = null;
223                                                 try { //e2
224                                                         db = dbf.newDocumentBuilder();
225                                                         doc = db.parse(is);
226                                                         NodeList errors = (NodeList)xpath.evaluate("errors/error", doc, XPathConstants.NODESET);
227                                                         for (int i = 0; i < errors.getLength(); i++)
228                                                         {
229                                                                 Element error = (Element) errors.item(i);
230                                                                 String eType = null;
231                                                                 try {
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);
236                                                                 }
237
238                                                                 String eTag = null;
239                                                                 try {
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);
244                                                                 }
245
246                                                                 String eMsg = null;
247                                                                 try {
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);
252                                                                 }
253                                                         }
254                                                 } catch (Exception e2) {
255                                                     msoLogger.error (MessageEnum.RA_ANALYZE_ERROR_EXC, "SDNC", "", MsoLogger.ErrorCode.DataError, "Exception while analyse error", e2);
256                                                 }
257                                         } //is != null
258                                 } catch (Exception e1) {
259                                         msoLogger.error (MessageEnum.RA_ERROR_GET_RESPONSE_SDNC, "SDNC", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while get SDNC response", e1);
260                                 }
261                         } //con != null
262
263                         if (e.getMessage() != null) {
264                 respMsg = respMsg + e.getMessage();
265             }
266                         if (sdncErrMsg != null) {
267                 respMsg = respMsg + sdncErrMsg;
268             }
269
270                         sdncResp.setRespMsg(respMsg);
271
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);
274                         return(sdncResp);
275                 }
276                 finally
277                 {
278                         if (con != null) {
279                 con.disconnect();
280             }
281                 }
282         }
283
284         public static void sendRespToBpel(String bpelUrl, SDNCResponse sdncResp,MsoPropertiesFactory msoPropertiesFactoryp)
285         {
286                 String error;
287                 try
288                 {
289                         SDNCAdapterCallbackRequest cbReq = new SDNCAdapterCallbackRequest();
290                         cbReq.setCallbackHeader(new CallbackHeader(sdncResp.getReqId(), Integer.toString(sdncResp.getRespCode()), sdncResp.getRespMsg()));
291                         if (sdncResp.getSdncRespXml() != null)
292                         {
293                                 cbReq.setRequestData(sdncResp.getSdncRespXml());
294                         }
295                         msoLogger.info(MessageEnum.RA_CALLBACK_BPEL, cbReq.toString(), "Camunda", "");
296
297                         URL wsdlUrl = null;
298                         try {
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);
304                         }
305
306                         SDNCCallbackAdapterService cbSvc = new SDNCCallbackAdapterService();
307
308                         SDNCCallbackAdapterPortType cbPort = cbSvc.getSDNCCallbackAdapterSoapHttpPort();
309
310                         BindingProvider bp = (BindingProvider)cbPort;
311
312                         bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlUrl.toExternalForm());
313
314                         //authentication
315                         try
316                         {
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);
320
321                                 String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes());
322                                 req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
323                                 headers.put ("Authorization", Collections.singletonList(basicAuth));
324                         }
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);
329                         }
330
331                         msoLogger.debug("Invoking Bpel Callback. BpelCallbackUrl:" + bpelUrl);
332                         cbPort.sdncAdapterCallback(cbReq);
333
334                 }
335                 catch (Exception e)
336                 {
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);
340                 }
341                 msoLogger.info(MessageEnum.RA_CALLBACK_BPEL_COMPLETE, "Camunda", "");
342                 return;
343         }
344
345 }