022fb7bf8967cab11c092c7d1e6fea4457f5c266
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.adapters.sdnc.sdncrest;
24
25 import java.io.StringWriter;
26 import javax.xml.XMLConstants;
27 import javax.xml.parsers.DocumentBuilder;
28 import javax.xml.parsers.DocumentBuilderFactory;
29 import javax.xml.transform.OutputKeys;
30 import javax.xml.transform.Transformer;
31 import javax.xml.transform.TransformerFactory;
32 import javax.xml.transform.dom.DOMSource;
33 import javax.xml.transform.stream.StreamResult;
34 import com.google.common.base.Strings;
35 import org.apache.http.HttpStatus;
36 import org.onap.so.adapters.sdnc.exception.SDNCAdapterException;
37 import org.onap.so.adapters.sdncrest.RequestInformation;
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.ErrorCode;
42 import org.onap.so.logger.MessageEnum;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.beans.factory.annotation.Autowired;
46 import org.springframework.scheduling.annotation.Async;
47 import org.springframework.stereotype.Component;
48 import org.w3c.dom.Document;
49 import org.w3c.dom.Element;
50
51 @Component
52 public class SDNCServiceRequestTask {
53     private static final Logger logger = LoggerFactory.getLogger(SDNCServiceRequestTask.class);
54
55     @Autowired
56     private SDNCServiceRequestConnector connector;
57
58     @Autowired
59     MapTypedRequestTunablesData mapTunables;
60
61     @Autowired
62     private BPRestCallback bpRestCallback;
63
64     @Async
65     public void runRequest(SDNCServiceRequest request, String msoRequestId, String msoServiceInstanceId,
66             String myUrlSuffix) {
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         long bpStartTime = System.currentTimeMillis();
95         boolean callbackSuccess = bpRestCallback.send(request.getBPNotificationUrl(), response.toJson());
96     }
97
98     private Element addChild(Element parent, String tag) {
99         Element child = parent.getOwnerDocument().createElement(tag);
100         parent.appendChild(child);
101         return child;
102     }
103
104     private void addTextChild(Element parent, String tag, String text) {
105         if (text != null) {
106             Element child = parent.getOwnerDocument().createElement(tag);
107             child.setTextContent(text);
108             parent.appendChild(child);
109         }
110     }
111
112     private String genSdncReq(SDNCServiceRequest request, TypedRequestTunables rt) {
113         Document doc;
114
115         try {
116             DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
117             DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
118
119             doc = documentBuilder.newDocument();
120             Element root = doc.createElementNS(rt.getNamespace(), "input");
121             doc.appendChild(root);
122
123             Element hdr = addChild(root, rt.getHeaderName());
124             addTextChild(hdr, "svc-request-id", rt.getReqId());
125             addTextChild(hdr, "svc-notification-url", rt.getMyUrl());
126
127             RequestInformation requestInfo = request.getRequestInformation();
128             Element requestInformation = addChild(root, "request-information");
129             addTextChild(requestInformation, "request-id", requestInfo.getRequestId());
130
131
132             if (requestInfo.getRequestAction() != null) {
133                 addTextChild(requestInformation, "request-action", requestInfo.getRequestAction());
134             }
135             if (requestInfo.getRequestSubAction() != null) {
136                 addTextChild(requestInformation, "request-sub-action", requestInfo.getRequestSubAction());
137             }
138             if (requestInfo.getOrderNumber() != null && !requestInfo.getOrderNumber().isEmpty()) {
139                 addTextChild(requestInformation, "order-number", requestInfo.getOrderNumber());
140             }
141
142             if (requestInfo.getOrderVersion() != null && !requestInfo.getOrderVersion().isEmpty()) {
143                 addTextChild(requestInformation, "order-version", requestInfo.getOrderVersion());
144             }
145
146
147             addTextChild(requestInformation, "source", requestInfo.getSource());
148             addTextChild(requestInformation, "notification-url", requestInfo.getNotificationUrl());
149
150             Element serviceInformation = addChild(root, "service-information");
151             addTextChild(serviceInformation, "service-type", request.getServiceInformation().getServiceType());
152             addTextChild(serviceInformation, "service-instance-id",
153                     request.getServiceInformation().getServiceInstanceId());
154             addTextChild(serviceInformation, "subscriber-name", request.getServiceInformation().getSubscriberName());
155             addTextChild(serviceInformation, "subscriber-global-id",
156                     request.getServiceInformation().getSubscriberGlobalId());
157
158             Element agnosticServiceInformation = addChild(root, "agnostic-service-information");
159             addTextChild(agnosticServiceInformation, "operation", request.getSdncOperation());
160             addTextChild(agnosticServiceInformation, "service", request.getSdncService());
161
162             // anydata is mandatory in the SDNC schema, so if the data we got is null,
163             // set use an empty string instead to ensure we generate an empty element.
164
165             String anydata = request.getSdncServiceData();
166             if (anydata == null) {
167                 anydata = "";
168             }
169
170             // content-type is also mandatory.
171
172             String contentType = request.getSdncServiceDataType();
173
174             if (contentType == null || contentType.isEmpty()) {
175                 if (anydata.isEmpty()) {
176                     contentType = "XML";
177                 } else {
178                     if (anydata.startsWith("<")) {
179                         contentType = "XML";
180                     } else {
181                         contentType = "JSON";
182                     }
183                 }
184             }
185
186             addTextChild(agnosticServiceInformation, "content-type", contentType);
187             addTextChild(agnosticServiceInformation, "anydata", anydata);
188         } catch (Exception e) {
189             logger.error(Strings.repeat("{} ", 4), MessageEnum.RA_ERROR_CREATE_SDNC_REQUEST.toString(), "SDNC",
190                     ErrorCode.BusinessProcesssError.getValue(), "Exception in genSdncReq", e);
191             return null;
192         }
193
194         String xml;
195
196         try {
197             StringWriter writer = new StringWriter();
198             TransformerFactory factory = TransformerFactory.newInstance();
199             factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
200             factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
201             Transformer transformer = factory.newTransformer();
202             transformer.setOutputProperty(OutputKeys.INDENT, "yes");
203             transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
204             transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
205             transformer.transform(new DOMSource(doc), new StreamResult(writer));
206             xml = writer.toString();
207         } catch (Exception e) {
208             logger.error(Strings.repeat("{} ", 3), MessageEnum.RA_ERROR_CONVERT_XML2STR.toString(),
209                     ErrorCode.DataError.getValue(), "Exception - domToStr", e);
210             return null;
211         }
212
213         logger.trace("Formatted SDNC service request XML:\n {}", xml);
214         return xml;
215     }
216 }