Bug fix to add anyxml node. 35/88335/1
authorjanani <janani.b@huawei.com>
Thu, 23 May 2019 10:15:14 +0000 (15:45 +0530)
committerjanani <janani.b@huawei.com>
Thu, 23 May 2019 10:15:14 +0000 (15:45 +0530)
Anyxml node fix

Change-Id: Ice40fde63ac8f589fa9358ebaf12c32247b0ae96
Issue-ID: CCSDK-1344
Signed-off-by: janani <janani.b@huawei.com>
13 files changed:
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiUtils.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/JsonSerializer.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeJsonListener.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeWalker.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/NodeType.java
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesNode.java
restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerTest.java
restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatUtilsTest.java
restconf-client/provider/src/test/resources/yang/execution-service.yang [new file with mode: 0644]

index 3007b5a..ac0897e 100644 (file)
@@ -43,10 +43,12 @@ import org.dom4j.DocumentHelper;
 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
 import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.plugins.restapicall.Format;
 import org.onap.ccsdk.sli.plugins.restapicall.HttpResponse;
 import org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode;
 import org.onap.ccsdk.sli.plugins.restapicall.RetryException;
 import org.onap.ccsdk.sli.plugins.restapicall.RetryPolicy;
+import org.onap.ccsdk.sli.plugins.restapicall.XmlParser;
 import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatSerializer;
 import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatSerializerContext;
 import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerFactory;
@@ -195,10 +197,14 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin {
 
             String response = getResponse(ctx, p, pp, r);
             if (response != null) {
-                Map<String, String> resProp = serializeResponse(
-                        p, uri, response, insIdCtx);
-                for (Map.Entry<String, String> pro : resProp.entrySet()) {
-                    ctx.setAttribute(pro.getKey(), pro.getValue());
+                try {
+                    Map<String, String> resProp = serializeResponse(
+                            p, uri, response, insIdCtx);
+                    for (Map.Entry<String, String> pro : resProp.entrySet()) {
+                        ctx.setAttribute(pro.getKey(), pro.getValue());
+                    }
+                } catch (SvcLogicException e) {
+                    convertToNormalRes(ctx, p, pp, response);
                 }
             }
         } catch (SvcLogicException e) {
@@ -241,6 +247,27 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin {
         }
     }
 
+    private void convertToNormalRes(SvcLogicContext ctx ,
+                                    YangParameters p, String pp, String body)
+            throws SvcLogicException {
+        if (p.convertResponse) {
+            Map<String, String> mm = null;
+            if (p.format == Format.XML) {
+                mm = XmlParser.convertToProperties(body, p.listNameList);
+            } else if (p.format == Format.JSON) {
+                mm = org.onap.ccsdk.sli.plugins.restapicall.JsonParser
+                        .convertToProperties(body);
+            }
+
+            if (mm != null) {
+                for (Map.Entry<String, String> entry : mm.entrySet()) {
+                    ctx.setAttribute(pp + entry.getKey(),
+                                     entry.getValue());
+                }
+            }
+        }
+    }
+
     /**
      * Serializes the request message to JSON or XML from the properties.
      *
index 505089c..1309102 100644 (file)
@@ -167,6 +167,18 @@ public final class RestconfApiUtils {
             }
             secondHalf = path.substring(p[0].length() + 1);
             return firstHalf + COLON + secondHalf;
+        } else if (path.contains(SLASH)) {
+            String[] p = path.split(SLASH);
+            if (p.length > 4) {
+                String actual = p[3] + COLON + p[4];
+                if (p.length > 5) {
+                    secondHalf = path.substring(
+                           p[1].length() + p[2].length() + actual.length() + 3);
+                    path = actual + secondHalf;
+                } else {
+                    path = actual;
+                }
+            }
         }
         return path;
     }
index 1be1309..91adb81 100644 (file)
@@ -22,18 +22,20 @@ package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.onap.ccsdk.sli.core.sli.SvcLogicException;
-import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.DefaultPropertiesNodeWalker;
-import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
-import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeWalker;
 
 import java.io.IOException;
 import java.io.Writer;
 import java.util.List;
 import java.util.Map;
 
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.DefaultPropertiesNodeWalker;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
+import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeWalker;
+
 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormat.JSON;
-import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.*;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.JSON_LIS_ERR;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.JSON_TREE_ERR;
 
 /**
  * Representation of JSON serializer which encodes properties to JSON and
index e51ccf7..0f03039 100644 (file)
 package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
 
 import com.google.gson.stream.JsonWriter;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Collection;
+import java.util.Map;
+
 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.DefaultPropertiesNodeWalker;
 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.LeafNode;
@@ -29,12 +36,6 @@ import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeListener;
 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.RootNode;
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.Map;
-
 import static com.google.common.base.Strings.repeat;
 import static java.lang.String.format;
 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.JSON_WRITE_ERR;
@@ -116,6 +117,16 @@ public class PropertiesNodeJsonListener implements PropertiesNodeListener{
                     jsonWriter.value(val);
                     break;
 
+                case ANY_XML_NODE:
+                    jsonWriter.name(nodeName);
+                    val = ((LeafNode) node).value();
+                    try {
+                        jsonWriter.jsonValue(val);
+                    } catch (IOException e) {
+                        throw new SvcLogicException(JSON_WRITE_ERR, e);
+                    }
+                    break;
+
                 default:
                     throw new SvcLogicException(format(
                             NODE_TYPE_ERR, node.nodeType().toString()));
@@ -143,6 +154,7 @@ public class PropertiesNodeJsonListener implements PropertiesNodeListener{
 
                 case  SINGLE_INSTANCE_LEAF_NODE:
                 case MULTI_INSTANCE_LEAF_NODE:
+                case ANY_XML_NODE:
                     break;
 
                 default:
@@ -174,7 +186,9 @@ public class PropertiesNodeJsonListener implements PropertiesNodeListener{
         PropertiesNode parent = node.parent();
         if (parent instanceof RootNode || !parent.namespace().moduleName()
                 .equals(node.namespace().moduleName())) {
-            return node.namespace().moduleName() + ":" + node.name();
+            if (!parent.nonAppend()) {
+                return node.namespace().moduleName() + ":" + node.name();
+            }
         }
         return node.name();
     }
index f234526..5034530 100644 (file)
 
 package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
 
-import org.onap.ccsdk.sli.core.sli.SvcLogicException;
-
 import java.util.Collection;
 import java.util.Map;
 
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
 /**
  * Implementation of properties node walker which helps in forming a new tree from properties node.
  *
@@ -110,6 +110,7 @@ public class DefaultPropertiesNodeWalker<T extends NodeChild> implements Propert
                         .children());
             case SINGLE_INSTANCE_LEAF_NODE:
             case MULTI_INSTANCE_LEAF_NODE:
+            case ANY_XML_NODE:
                 return null;
             default:
                 throw new IllegalArgumentException("No more types allowed");
index 0711a7c..1cf99b2 100644 (file)
 
 package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.addToAugmentations;
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.createNode;
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getAugmentationNode;
@@ -112,15 +112,18 @@ public abstract class InnerNode<T extends NodeChild> extends PropertiesNode {
         }
 
         AugmentationSchemaNode augSchema = null;
-        if (((DataSchemaNode) appInfo).isAugmenting()) {
-            augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()),
-                                                 ((DataSchemaNode) appInfo));
-        }
-
         String uri = getUri(this, name, namespace);
         node = new LeafNode(name, namespace, uri, this,
                             appInfo, type, value);
-        node.valueNs(valueNs);
+
+        if (type != NodeType.ANY_XML_NODE) {
+            if (((DataSchemaNode) appInfo).isAugmenting()) {
+                augSchema = findCorrespondingAugment(
+                        ((DataSchemaNode) this.appInfo()),
+                        ((DataSchemaNode) appInfo));
+            }
+            node.valueNs(valueNs);
+        }
 
         if (augSchema != null && !isNamespaceAsParent(this, node)) {
             addToAugmentations(augSchema, this, node);
index 0eca40d..8a6e756 100644 (file)
@@ -44,6 +44,7 @@ import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPrope
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision;
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getValueNamespace;
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName;
+import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.ANY_XML_NODE;
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE;
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE;
 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE;
@@ -81,6 +82,8 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<Sche
 
         paramMap = convertToValidParam(paramMap);
 
+        updateModNameReq(paramMap, rootUri);
+
         for (Map.Entry<String, String> entry : paramMap.entrySet()) {
             String[] names = entry.getKey().split("\\.");
             for (int i = 0; i < names.length; i++) {
@@ -97,6 +100,15 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<Sche
         return node;
     }
 
+    private void updateModNameReq(Map<String, String> paramMap,
+                                  String rootUri) {
+        String isReqStr = rootUri + "." + "isNonAppend";
+        String val = paramMap.get(isReqStr);
+        if (val != null && val.equals("true")) {
+            node.nonAppend(true);
+        }
+    }
+
     /**
      * Converts all the params in the svc logic context into a valid param by
      * replacing the underscore in module name to colon at necessary places.
@@ -150,7 +162,7 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<Sche
             return;
         }
 
-        switch (getNodeType(index, length, name)) {
+        switch (getNodeType(index, length, name, schema)) {
             case SINGLE_INSTANCE_NODE:
                 node = node.addChild(localName, ns,
                                      SINGLE_INSTANCE_NODE, schema);
@@ -173,6 +185,13 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<Sche
                                ns, schema, name);
                 break;
 
+            case ANY_XML_NODE:
+                node = node.addChild(localName, ns, ANY_XML_NODE,
+                                     value, null, schema);
+                node = node.endNode();
+                curSchema = ((SchemaNode) node.appInfo());
+                break;
+
             default:
                 throw new SvcLogicException("Invalid node type");
         }
index 2a3b176..e6fa064 100644 (file)
@@ -33,6 +33,7 @@ import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
 import org.opendaylight.yangtools.yang.data.util.ParserStreamUtils;
 import org.opendaylight.yangtools.yang.data.util.codec.IdentityCodecUtil;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
@@ -484,8 +485,12 @@ public final class MdsalPropertiesNodeUtils {
      * @param name name of the property
      * @return the property node type
      */
-    public static NodeType getNodeType(int index, int length, String name) {
+    public static NodeType getNodeType(int index, int length, String name,
+                                       SchemaNode schema) {
         if (index == length-1) {
+            if (schema instanceof AnyXmlSchemaNode){
+                return NodeType.ANY_XML_NODE;
+            }
             return (isListEntry(name) ? NodeType.MULTI_INSTANCE_LEAF_NODE :
                     NodeType.SINGLE_INSTANCE_LEAF_NODE);
         } else {
index bb07382..7e0ad63 100644 (file)
@@ -38,6 +38,7 @@ public abstract class PropertiesNode {
     private PropertiesNode parent;
     private Object appInfo;
     private NodeType nodeType;
+    private boolean nonAppend;
     private Multimap<Object, PropertiesNode> augmentations = ArrayListMultimap.create();
 
     /**
@@ -106,6 +107,16 @@ public abstract class PropertiesNode {
         this.appInfo = appInfo;
     }
 
+    /**
+     * Sets to true if module name is required in forming a request; false
+     * otherwise.
+     *
+     * @param isNotReq true if required; false otherwise
+     */
+    public void nonAppend(boolean isNotReq) {
+        this.nonAppend = isNotReq;
+    }
+
     /**
      * Returns parent.
      *
@@ -160,6 +171,15 @@ public abstract class PropertiesNode {
         return nodeType;
     }
 
+    /**
+     * Returns if module name is required.
+     *
+     * @return status of module name if required
+     */
+    public boolean nonAppend() {
+        return nonAppend;
+    }
+
     /**
      * Returns augmentations.
      *
index 45e8eb3..aa1e50d 100644 (file)
@@ -46,8 +46,10 @@ import static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.PATCH;
 import static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.POST;
 import static org.onap.ccsdk.sli.plugins.restapicall.HttpMethod.PUT;
 import static org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiUtils.parseUrl;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.DECODE_ANYXML_RESPONSE;
 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.DECODE_FROM_JSON_RPC;
 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.DECODE_FROM_XML_RPC;
+import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_ANYXML;
 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_JSON_ID;
 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_JSON_ID_PUT;
 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_JSON_RPC;
@@ -148,6 +150,24 @@ public class DataFormatSerializerTest {
         assertThat(dfCaptor.getResult(), is(ENCODE_TO_JSON_ID));
     }
 
+    /**
+     * Verifies encoding of parameters to JSON data format any xml in it.
+     *
+     * @throws SvcLogicException when test case fails
+     */
+    @Test
+    public void encodeForAnyXml() throws SvcLogicException {
+        String pre = "execution-service_process.";
+        SvcLogicContext ctx = createAnyXmlAttList(pre);
+        p.put("dirPath", "src/test/resources");
+        p.put("format", "json");
+        p.put("httpMethod", "post");
+        p.put("restapiUrl", "http://echo.getpostman" +
+                ".com/api/v1/execution-service/process");
+        restconf.sendRequest(p, ctx);
+        assertThat(dfCaptor.getResult(), is(ENCODE_TO_ANYXML));
+    }
+
     /**
      * Verifies encoding of parameters to JSON data format with identity-ref
      * and inter-file linking for put operation-type.
@@ -500,6 +520,27 @@ public class DataFormatSerializerTest {
         verifyAttListRpc(ctx, outPre);
     }
 
+    /**
+     * Verifies encoding of and decoding from, JSON for ANYXML.
+     *
+     * @throws SvcLogicException when test case fails
+     */
+    @Test
+    public void codecForNormalAnyXml() throws SvcLogicException {
+        createMockForDecode(DECODE_ANYXML_RESPONSE);
+        String inPre = "execution-service_process.";
+        SvcLogicContext ctx = createAnyXmlAttList(inPre);
+        p.put("dirPath", "src/test/resources");
+        p.put("format", "json");
+        p.put("httpMethod", "post");
+        p.put("responsePrefix", "pp");
+        p.put("restapiUrl", "http://echo.getpostman" +
+                ".com/api/v1/execution-service/process");
+        restconf.sendRequest(p, ctx);
+        assertThat(dfCaptor.getResult(), is(ENCODE_TO_ANYXML));
+        verifyOutputOfAnyXml(ctx);
+    }
+
     /**
      * Verifies encoding of and decoding from, XML respectively for data
      * format with containers, grouping and augment.
@@ -546,6 +587,12 @@ public class DataFormatSerializerTest {
         String url8 = "https://localhost:8282/restconf/data/" + actVal;
         String url9 = "http://182.2.61.24:2250/restconf/data/" + actVal;
         String url10 = "https://182.2.61.24:2250/restconf/operations/" + actVal;
+        String url11 = "https://182.2.61.24:2250/api/v1/execution-service" +
+                "/process";
+        String url12 = "https://182.2.61.24:2250/api/v1/execution-service" +
+                "/process/payload";
+        String url13 = "https://182.2.61.24:2250/api/v1/execution-service" +
+                "/process/payload/";
         String val1 = parseUrl(url1, POST);
         String val2 = parseUrl(url2, GET);
         String val3 = parseUrl(url3, PATCH);
@@ -556,6 +603,9 @@ public class DataFormatSerializerTest {
         String val8 = parseUrl(url8, POST);
         String val9 = parseUrl(url9, GET);
         String val10 = parseUrl(url10, POST);
+        String val11 = parseUrl(url11, POST);
+        String val12 = parseUrl(url12, POST);
+        String val13 = parseUrl(url13, POST);
         assertThat(val1, is(actVal));
         assertThat(val2, is(actVal));
         assertThat(val3, is(actVal));
@@ -566,6 +616,43 @@ public class DataFormatSerializerTest {
         assertThat(val8, is(actVal));
         assertThat(val9, is(actVal));
         assertThat(val10, is(actVal));
+        assertThat(val11, is("execution-service:process"));
+        assertThat(val12, is("execution-service:process/payload"));
+        assertThat(val13, is("execution-service:process/payload/"));
+    }
+
+    /**
+     * Creates attribute list for encoding JSON or XML with ANYXML YANG
+     * file.
+     *
+     * @param pre prefix
+     * @return service logic context
+     */
+    private SvcLogicContext createAnyXmlAttList(String pre) {
+        SvcLogicContext ctx = new SvcLogicContext();
+        String pre1 = pre + "commonHeader.";
+        String pre2 = pre + "actionIdentifiers.";
+        ctx.setAttribute(pre + "isNonAppend", "true");
+        ctx.setAttribute(pre1 + "originatorId", "SDNC_DG");
+        ctx.setAttribute(pre1 + "requestId", "123456-1000");
+        ctx.setAttribute(pre1 + "subRequestId", "sub-123456-1000");
+        ctx.setAttribute(pre2 + "blueprintName",
+                         "baseconfiguration");
+        ctx.setAttribute(pre2 + "blueprintVersion", "1.0.0");
+        ctx.setAttribute(pre2 + "actionName", "assign-activate");
+        ctx.setAttribute(pre2 + "mode", "sync");
+        ctx.setAttribute(pre + "payload." +
+                                 "template-prefix", "vDNS-test");
+        ctx.setAttribute(pre + "payload.resource-assignment-request" +
+                                 ".resource-assignment-properties",
+                         "{\n" +
+                                 "                \"service-instance-id\": " +
+                                 "\"1234\",\n" +
+                                 "                \"vnf-id\": \"3526\",\n" +
+                                 "                \"customer-name\": \"htipl\",\n" +
+                                 "                \"subscriber-name\": \"huawei\"\n" +
+                                 "            }");
+        return ctx;
     }
 
     /**
@@ -834,6 +921,51 @@ public class DataFormatSerializerTest {
         assertThat(ctx.getAttribute(pre + "cont13.leaf28"), is("abc"));
     }
 
+    /**
+     * Verifies the attribute list for decoding from JSON or XML with
+     * ANYXML YANG file.
+     *
+     * @param ctx service logic context
+     */
+    private void verifyOutputOfAnyXml(SvcLogicContext ctx) {
+        System.out.println(ctx.getAttribute("pp.status.eventType"));
+        assertThat(ctx.getAttribute("pp.status.eventType"), is(
+                "EVENT_COMPONENT_EXECUTED"));
+        assertThat(ctx.getAttribute("pp.actionIdentifiers.blueprintName"),
+                   is("golden"));
+        assertThat(ctx.getAttribute("pp.actionIdentifiers.mode"),
+                   is("sync"));
+        assertThat(ctx.getAttribute("pp.stepData.name"),
+                   is("resource-assignment"));
+        assertThat(ctx.getAttribute("pp.status.message"),
+                   is("success"));
+        assertThat(ctx.getAttribute("pp.commonHeader.originatorId"),
+                   is("System"));
+        assertThat(ctx.getAttribute("pp.status.code"),
+                   is("200"));
+        assertThat(ctx.getAttribute("pp.commonHeader.requestId"),
+                   is("1234"));
+        assertThat(ctx.getAttribute("pp.commonHeader.subRequestId"),
+                   is("1234-12234"));
+        assertThat(ctx.getAttribute("pp.commonHeader.timestamp"),
+                   is("2019-05-18T23:42:41.658Z"));
+        assertThat(ctx.getAttribute("pp.status.timestamp"),
+                   is("2019-05-18T23:42:41.950Z"));
+        assertThat(ctx.getAttribute("pp.actionIdentifiers.blueprintV" +
+                                            "ersion"), is("1.0.0"));
+        assertThat(ctx.getAttribute("pp.actionIdentifiers.actionName"),
+                   is("resource-assignment"));
+        assertThat(ctx.getAttribute("pp.payload.resource-assignment-resp" +
+                                            "onse.meshed-template.vf-module-1"),
+                   is("<interface>\n    <description>This i" +
+                              "s the Virtual Firewall entity</description>\n" +
+                              "    <vfw>10.0.101.20/24</vfw>\n" +
+                              "</interface>"));
+        assertThat(ctx.getAttribute("pp.actionIdentifiers.actionName"),
+                   is("resource-assignment"));
+    }
+
+
     /**
      * Captures the data format messages by mocking it, which can be used in
      * testing the value.
index a7814e1..c1bb719 100644 (file)
@@ -69,6 +69,31 @@ public final class DataFormatUtilsTest {
             "    \"identity-test:l\": \"abc\"\n" +
             "}";
 
+    static final String ENCODE_TO_ANYXML = "{\n" +
+            "    \"actionIdentifiers\": {\n" +
+            "        \"mode\": \"sync\",\n" +
+            "        \"blueprintName\": \"baseconfiguration\",\n" +
+            "        \"blueprintVersion\": \"1.0.0\",\n" +
+            "        \"actionName\": \"assign-activate\"\n" +
+            "    },\n" +
+            "    \"payload\": {\n" +
+            "        \"template-prefix\": \"vDNS-test\",\n" +
+            "        \"resource-assignment-request\": {\n" +
+            "            \"resource-assignment-properties\": {\n" +
+            "                \"service-instance-id\": \"1234\",\n" +
+            "                \"vnf-id\": \"3526\",\n" +
+            "                \"customer-name\": \"htipl\",\n" +
+            "                \"subscriber-name\": \"huawei\"\n" +
+            "            }\n" +
+            "        }\n" +
+            "    },\n" +
+            "    \"commonHeader\": {\n" +
+            "        \"subRequestId\": \"sub-123456-1000\",\n" +
+            "        \"requestId\": \"123456-1000\",\n" +
+            "        \"originatorId\": \"SDNC_DG\"\n" +
+            "    }\n" +
+            "}";
+
     static final String ENCODE_TO_JSON_ID_PUT = "{\n" +
             "    \"identity-test:test\": {\n" +
             "        \"con1\": {" + addSpace(ENCODE_TO_JSON_ID_COMMON, 4) +
@@ -485,6 +510,45 @@ public final class DataFormatUtilsTest {
             "    }\n" +
             "}";
 
+    static final String DECODE_ANYXML_RESPONSE = "{\n" +
+            "    \"commonHeader\": {\n" +
+            "        \"timestamp\": \"2019-05-18T23:42:41.658Z\",\n" +
+            "        \"originatorId\": \"System\",\n" +
+            "        \"requestId\": \"1234\",\n" +
+            "        \"subRequestId\": \"1234-12234\",\n" +
+            "        \"flags\": null\n" +
+            "    },\n" +
+            "    \"actionIdentifiers\": {\n" +
+            "        \"blueprintName\": \"golden\",\n" +
+            "        \"blueprintVersion\": \"1.0.0\",\n" +
+            "        \"actionName\": \"resource-assignment\",\n" +
+            "        \"mode\": \"sync\"\n" +
+            "    },\n" +
+            "    \"status\": {\n" +
+            "        \"code\": 200,\n" +
+            "        \"eventType\": \"EVENT_COMPONENT_EXECUTED\",\n" +
+            "        \"timestamp\": \"2019-05-18T23:42:41.950Z\",\n" +
+            "        \"errorMessage\": null,\n" +
+            "        \"message\": \"success\"\n" +
+            "    },\n" +
+            "    \"payload\": {\n" +
+            "        \"resource-assignment-response\": {\n" +
+            "            \"meshed-template\": {\n" +
+            "                \"vf-module-1\": \"<interface>\\n   " +
+            " <description>This is the Virtual Firewall entity</" +
+            "description>\\n    <vfw>10.0.101.20/24</vfw>\\n</interface>\"\n" +
+            "            }\n" +
+            "        }\n" +
+            "    },\n" +
+            "    \"stepData\": {\n" +
+            "        \"name\": \"resource-assignment\",\n" +
+            "        \"properties\": {\n" +
+            "            \"resource-assignment-params\": null,\n" +
+            "            \"status\": null\n" +
+            "        }\n" +
+            "    }\n" +
+            "}";
+
     static final String ENCODE_TO_XML_RPC = "<?xml version=\"1.0\" encoding" +
             "=\"UTF-8\" standalone=\"no\"?>\n" +
             "<input xmlns=\"urn:opendaylight:params:xml:ns:yang:test\">\n" +
diff --git a/restconf-client/provider/src/test/resources/yang/execution-service.yang b/restconf-client/provider/src/test/resources/yang/execution-service.yang
new file mode 100644 (file)
index 0000000..d7cf68f
--- /dev/null
@@ -0,0 +1,43 @@
+module execution-service {
+    yang-version 1.1;
+    namespace "cds:workflow:rest";
+    prefix "cds";
+
+    revision "2019-05-21";
+
+    container process {
+        container commonHeader {
+            leaf originatorId {
+                type string;
+            }
+            leaf requestId {
+                type string;
+            }
+            leaf subRequestId {
+                type string;
+            }
+        }
+        container actionIdentifiers {
+            leaf blueprintName {
+                type string;
+            }
+            leaf blueprintVersion {
+                type string;
+            }
+            leaf actionName {
+                type string;
+            }
+            leaf mode {
+                type string;
+            }
+        }
+        container payload {
+            leaf-list template-prefix {
+                type string;
+            }
+            container resource-assignment-request {
+                anyxml resource-assignment-properties;
+            }
+        }
+    }
+}