summaryrefslogtreecommitdiffstats
path: root/bpmn
diff options
context:
space:
mode:
authorJim Hahn <jrh3@att.com>2017-10-30 15:58:19 -0400
committerJim Hahn <jrh3@att.com>2017-10-30 15:58:19 -0400
commit7754fb8e889bae843d7382b7dee4b2e21a4ef56c (patch)
tree4ce34db3917ecd5a503547d5f32fddff4258db1f /bpmn
parent364e214921ec080cbc991a0863fe7bfdf8825ea3 (diff)
Handle embedded "<" in SDNC responses
Modified the code to use an actual XML parser when decoding the SDNC response-data element, instead of using the simple-minded replace("&amp;", "&") approach. The latter did not function correctly when XML elements contained other xml-encoded data. Change-Id: Ied6b8b19f307f728b8da1a2b410b9e239ec62ab6 Issue-Id: SO-115 Signed-off-by: Jim Hahn <jrh3@att.com>
Diffstat (limited to 'bpmn')
-rw-r--r--bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtils.groovy29
-rw-r--r--bpmn/MSOCommonBPMN/src/test/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtilsTest.groovy180
2 files changed, 194 insertions, 15 deletions
diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtils.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtils.groovy
index b35616680b..c43f88434d 100644
--- a/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtils.groovy
+++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtils.groovy
@@ -24,7 +24,7 @@ import org.apache.commons.lang3.*
import org.camunda.bpm.engine.delegate.BpmnError
import org.camunda.bpm.engine.runtime.Execution
import org.openecomp.mso.bpmn.core.WorkflowException
-import org.openecomp.mso.bpmn.core.json.JsonUtils;
+import org.openecomp.mso.bpmn.core.json.JsonUtils
import org.springframework.web.util.UriUtils
@@ -730,13 +730,8 @@ class SDNCAdapterUtils {
taskProcessor.utils.log("DEBUG", response + ' is empty');
exceptionUtil.buildAndThrowWorkflowException(execution, 500, "SDNCAdapter Workflow Response is Empty")
}else{
-
// we need to peer into the request data for error
- def String sdncAdapterWorkflowResponse = taskProcessor.utils.getNodeXml(response, 'response-data', false)
- def String decodedXml = decodeXML(sdncAdapterWorkflowResponse).replace('<?xml version="1.0" encoding="UTF-8"?>', "")
-
- // change '&' to "&amp; (if present as data, ex: subscriber-name = 'FOUR SEASONS HEATING & COOLING_8310006378683'
- decodedXml = decodedXml.replace("&", "&amp;")
+ def String decodedXml = taskProcessor.utils.getNodeText1(response, "RequestData")
taskProcessor.utils.log("DEBUG","decodedXml:\n" + decodedXml, isDebugLogEnabled)
@@ -745,12 +740,14 @@ class SDNCAdapterUtils {
try{
if (taskProcessor.utils.nodeExists(decodedXml, "response-message")) {
- requestDataResponseMessage = taskProcessor.utils.getNodeText(decodedXml, "response-message")
- } else if (taskProcessor.utils.nodeExists(decodedXml, "ResponseMessage")) {
- requestDataResponseMessage = taskProcessor.utils.getNodeText(decodedXml, "ResponseMessage")
+ requestDataResponseMessage = taskProcessor.utils.getNodeText1(decodedXml, "response-message")
+
+ // note: ResponseMessage appears within "response", not "decodedXml"
+ } else if (taskProcessor.utils.nodeExists(response, "ResponseMessage")) {
+ requestDataResponseMessage = taskProcessor.utils.getNodeText1(response, "ResponseMessage")
}
}catch(Exception e){
- taskProcessor.utils.log("DEBUG", 'Error caught while decoding resposne ' + e.getMessage(), isDebugLogEnabled)
+ taskProcessor.utils.log("DEBUG", 'Error caught while decoding response ' + e.getMessage(), isDebugLogEnabled)
}
if(taskProcessor.utils.nodeExists(decodedXml, "response-code")) {
@@ -761,18 +758,20 @@ class SDNCAdapterUtils {
taskProcessor.utils.log("DEBUG","response-code node is empty", isDebugLogEnabled)
requestDataResponseCode = 0
}else{
- requestDataResponseCode = code.toInteger()
+ requestDataResponseCode = code as Integer
taskProcessor.utils.log("DEBUG","response-code is: " + requestDataResponseCode, isDebugLogEnabled)
}
- }else if(taskProcessor.utils.nodeExists(decodedXml, "ResponseCode")){
+
+ // note: ResponseCode appears within "response", not "decodedXml"
+ }else if(taskProcessor.utils.nodeExists(response, "ResponseCode")){
taskProcessor.utils.log("DEBUG","ResponseCode node Exist ", isDebugLogEnabled)
- String code = taskProcessor.utils.getNodeText1(decodedXml, "ResponseCode")
+ String code = taskProcessor.utils.getNodeText1(response, "ResponseCode")
if(code.isEmpty() || code.equals("")){
// if ResponseCode blank then Success
taskProcessor.utils.log("DEBUG","ResponseCode node is empty", isDebugLogEnabled)
requestDataResponseCode = 0
}else{
- requestDataResponseCode = code.toInteger()
+ requestDataResponseCode = code as Integer
taskProcessor.utils.log("DEBUG","ResponseCode is: " + requestDataResponseCode, isDebugLogEnabled)
}
}else{
diff --git a/bpmn/MSOCommonBPMN/src/test/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtilsTest.groovy b/bpmn/MSOCommonBPMN/src/test/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtilsTest.groovy
new file mode 100644
index 0000000000..2b63100510
--- /dev/null
+++ b/bpmn/MSOCommonBPMN/src/test/groovy/org/openecomp/mso/bpmn/common/scripts/SDNCAdapterUtilsTest.groovy
@@ -0,0 +1,180 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.mso.bpmn.common.scripts;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*
+
+import org.junit.Before
+import org.junit.Test
+import org.camunda.bpm.engine.delegate.BpmnError
+import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity
+import org.camunda.bpm.engine.runtime.Execution
+import org.openecomp.mso.bpmn.core.WorkflowException
+import org.openecomp.mso.bpmn.common.scripts.SDNCAdapterUtils
+
+import org.openecomp.mso.bpmn.mock.FileUtil
+
+public class SDNCAdapterUtilsTest {
+
+ private def map
+ private ExecutionEntity svcex
+ private WorkflowException wfex
+ private AbstractServiceTaskProcessor tp
+ private String resp
+ private SDNCAdapterUtils utils
+
+ @Before
+ public void init()
+ {
+ map = new HashMap<String,Object>()
+ svcex = mock(ExecutionEntity.class)
+ wfex = null
+ tp = new AbstractServiceTaskProcessor() {
+ @Override
+ public void preProcessRequest(Execution execution) {
+ }
+ };
+ utils = new SDNCAdapterUtils(tp)
+
+ // svcex gets its variables from "map"
+ when(svcex.getVariable(any())).thenAnswer(
+ { invocation ->
+ return map.get(invocation.getArgumentAt(0, String.class)) })
+
+ // svcex puts its variables into "map"
+ when(svcex.setVariable(any(), any())).thenAnswer(
+ { invocation ->
+ return map.put(
+ invocation.getArgumentAt(0, String.class),
+ invocation.getArgumentAt(1, String.class)) })
+
+ map.put("isDebugLogEnabled", "true")
+ map.put("prefix", "mypfx-")
+ map.put("testProcessKey", "mykey")
+ }
+
+ @Test
+ public void testValidateSDNCResponse_Success_NoCode() {
+ resp = """<no-response/>"""
+
+ utils.validateSDNCResponse(svcex, resp, wfex, true)
+
+ assertEquals(true, map.get("mypfx-sdncResponseSuccess"))
+ assertEquals("0", map.get("mypfx-sdncRequestDataResponseCode"))
+ assertFalse(map.containsKey("WorkflowException"))
+ }
+
+ @Test
+ public void testValidateSDNCResponse_200() {
+ utils.validateSDNCResponse(svcex, makeResp("200", "OK", ""), wfex, true)
+
+ assertEquals(true, map.get("mypfx-sdncResponseSuccess"))
+ assertEquals("200", map.get("mypfx-sdncRequestDataResponseCode"))
+ assertFalse(map.containsKey("WorkflowException"))
+ }
+
+ @Test
+ public void testValidateSDNCResponse_408() {
+ try {
+ utils.validateSDNCResponse(svcex, makeResp("408", "failed", ""), wfex, true)
+
+ // this has been commented out as, currently, the code doesn't
+ // throw an exception in this case
+// fail("missing exception")
+
+ } catch(BpmnError ex) {
+ ex.printStackTrace()
+ }
+
+ assertEquals(false, map.get("mypfx-sdncResponseSuccess"))
+ assertEquals("408", map.get("mypfx-sdncRequestDataResponseCode"))
+
+ wfex = map.get("WorkflowException")
+ assertNotNull(wfex)
+
+ assertEquals(5320, wfex.getErrorCode())
+ assertEquals("Received error from SDN-C: failed", wfex.getErrorMessage())
+ }
+
+ @Test
+ public void testValidateSDNCResponse_408_200() {
+
+ utils.validateSDNCResponse(svcex, makeResp("408", "failed", makeReq("200", "ok")), wfex, true)
+
+ assertEquals(true, map.get("mypfx-sdncResponseSuccess"))
+ assertEquals("200", map.get("mypfx-sdncRequestDataResponseCode"))
+ assertFalse(map.containsKey("WorkflowException"))
+ }
+
+ @Test
+ public void testValidateSDNCResponse_408_200_WithEmbeddedLt() {
+
+ utils.validateSDNCResponse(svcex, makeResp("408", "failed", makeReq("200", "<success> message")), wfex, true)
+
+ assertEquals(true, map.get("mypfx-sdncResponseSuccess"))
+ assertEquals("200", map.get("mypfx-sdncRequestDataResponseCode"))
+ assertFalse(map.containsKey("WorkflowException"))
+ }
+
+
+ private String makeResp(String respcode, String respmsg, String reqdata) {
+ def rc = encodeXml(respcode)
+ def rm = encodeXml(respmsg)
+
+ return """
+<sdncadapterworkflow:SDNCAdapterWorkflowResponse xmlns:sdncadapterworkflow="http://org.openecomp/mso/workflow/schema/v1"
+ xmlns:tag0="http://org.openecomp/workflow/sdnc/adapter/schema/v1"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <sdncadapterworkflow:response-data>
+ <tag0:CallbackHeader>
+ <tag0:RequestId>myreq</tag0:RequestId>
+ <tag0:ResponseCode>${rc}</tag0:ResponseCode>
+ <tag0:ResponseMessage>${rm}</tag0:ResponseMessage>
+ </tag0:CallbackHeader>
+ ${reqdata}
+ </sdncadapterworkflow:response-data>
+</sdncadapterworkflow:SDNCAdapterWorkflowResponse>
+"""
+
+ }
+
+ private String makeReq(String respcode, String respmsg) {
+ def rc = encodeXml(respcode)
+ def rm = encodeXml(respmsg)
+
+ def output = """
+<output xmlns="org:onap:sdnc:northbound:generic-resource">
+ <svc-request-id>8b46e36e-b44f-4085-9404-427be1bc8a3</svc-request-id>
+ <response-code>${rc}</response-code>
+ <response-message>${rm}</response-message>
+ <ack-final-indicator>Y</ack-final-indicator>
+</output>
+"""
+ output = encodeXml(output)
+
+ return """<tag0:RequestData xsi:type="xs:string">${output}</tag0:RequestData>"""
+ }
+
+ private String encodeXml(String txt) {
+ return txt.replace("&", "&amp;").replace("<", "&lt;")
+ }
+}