2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2018 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.onap.so.bpmn.infrastructure.sdnc.tasks;
23 import java.io.StringReader;
24 import java.io.StringWriter;
25 import javax.xml.parsers.DocumentBuilder;
26 import javax.xml.parsers.DocumentBuilderFactory;
27 import javax.xml.transform.Transformer;
28 import javax.xml.transform.TransformerFactory;
29 import javax.xml.transform.dom.DOMSource;
30 import javax.xml.transform.stream.StreamResult;
31 import javax.xml.xpath.XPath;
32 import javax.xml.xpath.XPathFactory;
33 import org.camunda.bpm.engine.delegate.DelegateExecution;
34 import org.onap.logging.filter.base.ONAPComponents;
35 import org.onap.so.bpmn.infrastructure.sdnc.exceptions.SDNCErrorResponseException;
36 import org.onap.so.client.exception.BadResponseException;
37 import org.onap.so.client.exception.ExceptionBuilder;
38 import org.onap.so.client.exception.MapperException;
39 import org.onap.so.client.sdnc.SDNCClient;
40 import org.onap.so.client.sdnc.beans.SDNCRequest;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.springframework.beans.factory.annotation.Autowired;
44 import org.springframework.stereotype.Component;
45 import org.springframework.web.client.HttpClientErrorException;
46 import org.w3c.dom.Document;
47 import org.xml.sax.InputSource;
48 import com.jayway.jsonpath.JsonPath;
49 import com.jayway.jsonpath.PathNotFoundException;
50 import net.sf.saxon.lib.NamespaceConstant;
51 import net.sf.saxon.xpath.XPathFactoryImpl;
54 public class SDNCRequestTasks {
56 private static final String NET_SF_SAXON_XPATH_IMPL = "net.sf.saxon.xpath.XPathFactoryImpl";
58 private static final String XPATH_FACTORY_PROPERTY_NAME =
59 "javax.xml.xpath.XPathFactory:" + NamespaceConstant.OBJECT_MODEL_SAXON;
61 private static final Logger logger = LoggerFactory.getLogger(SDNCRequestTasks.class);
63 private static final String SDNC_REQUEST = "SDNCRequest";
64 private static final String MESSAGE = "_MESSAGE";
65 private static final String CORRELATOR = "_CORRELATOR";
66 protected static final String IS_CALLBACK_COMPLETED = "isCallbackCompleted";
67 protected static final String SDNC_SUCCESS = "200";
70 private ExceptionBuilder exceptionBuilder;
73 private SDNCClient sdncClient;
75 public void createCorrelationVariables(DelegateExecution execution) {
76 SDNCRequest request = (SDNCRequest) execution.getVariable(SDNC_REQUEST);
77 execution.setVariable(request.getCorrelationName() + CORRELATOR, request.getCorrelationValue());
78 execution.setVariable("sdncTimeout", request.getTimeOut());
81 public void callSDNC(DelegateExecution execution) {
82 SDNCRequest request = (SDNCRequest) execution.getVariable(SDNC_REQUEST);
84 String response = sdncClient.post(request.getSDNCPayload(), request.getTopology());
85 String finalMessageIndicator = JsonPath.read(response, "$.output.ack-final-indicator");
86 execution.setVariable("isSDNCCompleted", convertIndicatorToBoolean(finalMessageIndicator));
87 } catch (PathNotFoundException e) {
88 logger.error("Error Parsing SDNC Response. Could not find read final ack indicator from JSON.", e);
89 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000,
90 "Recieved invalid response from SDNC, unable to read message content.", ONAPComponents.SO);
91 } catch (MapperException e) {
92 logger.error("Failed to map SDNC object to JSON prior to POST.", e);
93 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000,
94 "Failed to map SDNC object to JSON prior to POST.", ONAPComponents.SO);
95 } catch (BadResponseException e) {
96 logger.error("Did not receive a successful response from SDNC.", e);
97 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, e.getLocalizedMessage(),
99 } catch (HttpClientErrorException e) {
100 logger.error("HttpClientErrorException: 404 Not Found, Failed to contact SDNC", e);
101 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, "SDNC cannot be contacted.",
106 public void processCallback(DelegateExecution execution) {
108 SDNCRequest request = (SDNCRequest) execution.getVariable(SDNC_REQUEST);
109 String asyncRequest = (String) execution.getVariable(request.getCorrelationName() + MESSAGE);
111 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
112 dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
113 dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
114 dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
115 DocumentBuilder db = dbf.newDocumentBuilder();
116 Document doc = db.parse(new InputSource(new StringReader(asyncRequest)));
118 String finalMessageIndicator = getXmlElement(doc, "/input/ack-final-indicator");
120 boolean isCallbackCompleted = convertIndicatorToBoolean(finalMessageIndicator);
121 execution.setVariable(IS_CALLBACK_COMPLETED, isCallbackCompleted);
122 if (isCallbackCompleted) {
123 String responseCode = getXmlElement(doc, "/input/response-code");
124 if (!SDNC_SUCCESS.equalsIgnoreCase(responseCode)) {
125 String responseMessage;
127 responseMessage = getXmlElement(doc, "/input/response-message");
128 } catch (Exception e) {
129 responseMessage = "Unknown Error in SDNC";
131 throw new SDNCErrorResponseException(responseMessage);
134 } catch (SDNCErrorResponseException e) {
135 logger.error("SDNC error response - " + e.getMessage());
136 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, e.getMessage(), ONAPComponents.SDNC);
137 } catch (Exception e) {
138 logger.error("Error processing SDNC callback", e);
139 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, "Error processing SDNC callback",
144 public void handleTimeOutException(DelegateExecution execution) {
145 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000,
146 "Error timed out waiting on SDNC Async-Response", ONAPComponents.SO);
149 protected boolean convertIndicatorToBoolean(String finalMessageIndicator) {
150 return "Y".equals(finalMessageIndicator);
153 protected String getXmlElement(final Document doc, final String exp) throws Exception {
154 final TransformerFactory tf = TransformerFactory.newInstance();
155 final Transformer transformer = tf.newTransformer();
156 final StringWriter writer = new StringWriter();
157 transformer.transform(new DOMSource(doc), new StreamResult(writer));
158 logger.debug(writer.getBuffer().toString());
160 System.setProperty(XPATH_FACTORY_PROPERTY_NAME, NET_SF_SAXON_XPATH_IMPL);
161 final XPathFactory xPathFactory = XPathFactoryImpl.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON);
162 final XPath xPath = xPathFactory.newXPath();
163 final String result = xPath.evaluate(exp, doc);
164 if (result == null || result.isEmpty()) {
165 throw new Exception("XPath Failed to find element expression: " + exp);