deb39ac54e30e1a04edc4c790b84fd3bd7716873
[so.git] /
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.onap.so.adapters.sdnc.sdncrest;
22
23 import java.io.StringWriter;
24
25 import javax.xml.XMLConstants;
26 import javax.xml.parsers.DocumentBuilder;
27 import javax.xml.parsers.DocumentBuilderFactory;
28 import javax.xml.transform.OutputKeys;
29 import javax.xml.transform.Transformer;
30 import javax.xml.transform.TransformerFactory;
31 import javax.xml.transform.dom.DOMSource;
32 import javax.xml.transform.stream.StreamResult;
33
34 import org.apache.http.HttpStatus;
35 import org.onap.so.adapters.sdnc.exception.SDNCAdapterException;
36 import org.onap.so.adapters.sdncrest.RequestInformation;
37 import org.onap.so.adapters.sdncrest.SDNCErrorCommon;
38 import org.onap.so.adapters.sdncrest.SDNCResponseCommon;
39 import org.onap.so.adapters.sdncrest.SDNCServiceError;
40 import org.onap.so.adapters.sdncrest.SDNCServiceRequest;
41 import org.onap.so.logger.MessageEnum;
42 import org.onap.so.logger.MsoLogger;
43 import org.springframework.beans.factory.annotation.Autowired;
44 import org.springframework.scheduling.annotation.Async;
45 import org.springframework.stereotype.Component;
46 import org.w3c.dom.Document;
47 import org.w3c.dom.Element;
48
49 @Component
50 public class SDNCServiceRequestTask {
51         private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA,SDNCServiceRequestTask.class);
52
53         @Autowired
54         private SDNCServiceRequestConnector connector;
55         
56         @Autowired
57         MapTypedRequestTunablesData mapTunables;
58         
59         @Autowired
60         private BPRestCallback bpRestCallback;
61
62         @Async
63         public void runRequest(SDNCServiceRequest request,String msoRequestId,String msoServiceInstanceId,String myUrlSuffix)
64         {
65                 MsoLogger.setLogContext(msoRequestId, msoServiceInstanceId);
66                 MsoLogger.setServiceName(getClass().getSimpleName());
67
68                 String sdncRequestId = request.getSdncRequestId();
69                 String sdncService = request.getSdncService();
70                 String sdncOperation = request.getSdncOperation();
71
72                 TypedRequestTunables rt = new TypedRequestTunables(sdncRequestId, myUrlSuffix);
73                 rt.setServiceKey(sdncService, sdncOperation);
74                 TypedRequestTunables mappedTunables;
75                 try {
76                         mappedTunables = mapTunables.setTunables(rt);
77                 } catch(SDNCAdapterException e) {
78                         bpRestCallback.send(request.getBPNotificationUrl(), e.getMessage());
79                         return;
80                 }
81                 if (!mappedTunables.getError().isEmpty()) {
82                         // Note that the error was logged and alarmed by setTunables()
83                         SDNCServiceError error = new SDNCServiceError(request.getSdncRequestId(),
84                                 String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR), mappedTunables.getError(), "Y");
85                         bpRestCallback.send(request.getBPNotificationUrl(), error.toJson());
86                         return;
87                 }
88
89                 String xml = genSdncReq(request, mappedTunables);
90
91                 long sdncStartTime = System.currentTimeMillis();                
92                 SDNCResponseCommon response = connector.send(xml, mappedTunables);
93
94                 if (response instanceof SDNCErrorCommon) {
95                         LOGGER.recordMetricEvent(sdncStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
96                                 "Received success response from SDNC", "SDNC", sdncService + "." + sdncOperation, null);
97                 } else {
98                         LOGGER.recordMetricEvent(sdncStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
99                                 "Received error response from SDNC", "SDNC", sdncService + "." + sdncOperation, null);
100                 }
101
102                 long bpStartTime = System.currentTimeMillis();
103                 boolean callbackSuccess = bpRestCallback.send(request.getBPNotificationUrl(), response.toJson());
104
105                 if (callbackSuccess) {
106                         LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
107                                 "Sent notification", "BPMN", request.getBPNotificationUrl(), null);
108                 } else {
109                         LOGGER.recordMetricEvent(bpStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
110                                 "Failed to send notification", "BPMN", request.getBPNotificationUrl(), null);
111                 }
112         }
113
114         private Element addChild(Element parent, String tag) {
115                 Element child = parent.getOwnerDocument().createElement(tag);
116                 parent.appendChild(child);
117                 return child;
118         }
119
120         private void addTextChild(Element parent, String tag, String text) {
121                 if (text != null) {
122                         Element child = parent.getOwnerDocument().createElement(tag);
123                         child.setTextContent(text);
124                         parent.appendChild(child);
125                 }
126         }
127
128         private String genSdncReq(SDNCServiceRequest request, TypedRequestTunables rt) {
129                 Document doc;
130
131                 try {
132                         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
133                         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
134
135                         doc = documentBuilder.newDocument();
136                         Element root = doc.createElementNS(rt.getNamespace(), "input");
137                         doc.appendChild(root);
138
139                         Element hdr = addChild(root, rt.getHeaderName());
140                         addTextChild(hdr, "svc-request-id", rt.getReqId());
141                         addTextChild(hdr, "svc-notification-url", rt.getMyUrl());
142
143                         RequestInformation requestInfo = request.getRequestInformation();
144                         Element requestInformation = addChild(root, "request-information");
145                         addTextChild(requestInformation, "request-id", requestInfo.getRequestId());
146                 
147                         
148                         if(requestInfo.getRequestAction()!= null) {
149                                 addTextChild(requestInformation, "request-action",
150                                                 requestInfo.getRequestAction());
151                         }
152                         if(requestInfo.getRequestSubAction()!= null) {
153                                 addTextChild(requestInformation, "request-sub-action",
154                                                 requestInfo.getRequestSubAction());
155                         }
156                         if(requestInfo.getOrderNumber() != null &&
157                                         !requestInfo.getOrderNumber().isEmpty() ) {
158                                 addTextChild(requestInformation, "order-number",
159                                                 requestInfo.getOrderNumber());
160                         }
161                         
162                         if(requestInfo.getOrderVersion() != null &&
163                                         !requestInfo.getOrderVersion().isEmpty() ) {
164                                 addTextChild(requestInformation, "order-version",
165                                                 requestInfo.getOrderVersion());
166                         }
167                         
168                         
169                         addTextChild(requestInformation, "source", requestInfo.getSource());
170                         addTextChild(requestInformation, "notification-url", requestInfo.getNotificationUrl());
171
172                         Element serviceInformation = addChild(root, "service-information");
173                         addTextChild(serviceInformation, "service-type", request.getServiceInformation().getServiceType());
174                         addTextChild(serviceInformation, "service-instance-id", request.getServiceInformation().getServiceInstanceId());
175                         addTextChild(serviceInformation, "subscriber-name", request.getServiceInformation().getSubscriberName());
176                         addTextChild(serviceInformation, "subscriber-global-id", request.getServiceInformation().getSubscriberGlobalId());
177
178                         Element agnosticServiceInformation = addChild(root, "agnostic-service-information");
179                         addTextChild(agnosticServiceInformation, "operation", request.getSdncOperation());
180                         addTextChild(agnosticServiceInformation, "service", request.getSdncService());
181
182                         // anydata is mandatory in the SDNC schema, so if the data we got is null,
183                         // set use an empty string instead to ensure we generate an empty element.
184
185                         String anydata = request.getSdncServiceData();
186                         if (anydata == null) {
187                                 anydata = "";
188                         }
189
190                         // content-type is also mandatory.
191
192                         String contentType = request.getSdncServiceDataType();
193
194                         if (contentType == null || contentType.isEmpty()) {
195                                 if (anydata.isEmpty()) {
196                                         contentType = "XML";
197                                 } else {
198                                         if (anydata.startsWith("<")) {
199                                                 contentType = "XML";
200                                         } else {
201                                                 contentType = "JSON";
202                                         }
203                                 }
204                         }
205
206                         addTextChild(agnosticServiceInformation, "content-type", contentType);
207                         addTextChild(agnosticServiceInformation, "anydata", anydata);
208                 } catch (Exception e) {
209                         LOGGER.error(MessageEnum.RA_ERROR_CREATE_SDNC_REQUEST, "SDNC", "",
210                                         MsoLogger.ErrorCode.BusinessProcesssError, "Exception in genSdncReq", e);
211                         return null;
212                 }
213
214                 String xml;
215
216                 try {
217                         StringWriter writer = new StringWriter();
218                         TransformerFactory factory = TransformerFactory.newInstance();
219                         factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"");
220                         factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,"");
221                         Transformer transformer = factory.newTransformer();
222                         transformer.setOutputProperty(OutputKeys.INDENT, "yes");
223                         transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
224                         transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
225                         transformer.transform(new DOMSource(doc), new StreamResult(writer));
226                         xml = writer.toString();
227                 } catch (Exception e) {
228                         LOGGER.error(MessageEnum.RA_ERROR_CONVERT_XML2STR, "", "",
229                                 MsoLogger.ErrorCode.DataError, "Exception - domToStr", e);
230                         return null;
231                 }
232
233                 LOGGER.trace("Formatted SDNC service request XML:\n" + xml);
234                 return xml;
235         }
236 }