From 259eece936114ccacf9acc8f412eeed033fd10c4 Mon Sep 17 00:00:00 2001 From: janani b Date: Wed, 12 Sep 2018 18:30:28 +0530 Subject: [PATCH] UT and defect fixes for DF serializer UT and defect fixes Issue-ID: CCSDK-376 Change-Id: Ia5f04a0d7e07caad0e3b380fdfa6cc109ec43b4e Signed-off-by: janani b --- restconf-client/provider/pom.xml | 20 +- .../restconfapicall/RestconfApiCallNode.java | 39 +- .../dfserializer/DefaultJsonListener.java | 43 +- .../dfserializer/DefaultXmlListener.java | 41 ++ .../dfserializer/DfSerializerUtil.java | 46 +- .../dfserializer/MdsalSerializerHelper.java | 59 +- .../dfserializer/PropertiesNodeXmlListener.java | 8 +- .../DefaultPropertiesNodeListener.java | 6 +- .../MdsalPropertiesNodeSerializer.java | 15 +- .../pnserializer/MdsalPropertiesNodeUtils.java | 8 + .../blueprint/restconf-client-blueprint.xml | 10 +- .../dfserializer/DataFormatSerializerTest.java | 612 +++++++++++++++++++++ .../dfserializer/DataFormatUtilsTest.java | 504 +++++++++++++++++ .../src/test/resources/yang/identity-test.yang | 10 +- .../test/resources/yang/identity-types-second.yang | 2 +- .../src/test/resources/yang/test-augment.yang | 59 +- .../src/test/resources/yang/test-yang.yang | 114 ++-- 17 files changed, 1438 insertions(+), 158 deletions(-) create mode 100644 restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerTest.java create mode 100644 restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatUtilsTest.java diff --git a/restconf-client/provider/pom.xml b/restconf-client/provider/pom.xml index c063c9bd..db0bee06 100755 --- a/restconf-client/provider/pom.xml +++ b/restconf-client/provider/pom.xml @@ -73,6 +73,12 @@ junit test + + org.mockito + mockito-core + ${mockito.version} + test + org.glassfish.jersey.inject jersey-hk2 @@ -106,23 +112,13 @@ org.opendaylight.netconf restconf-nb-rfc8040 - 1.7.3 - test + ${odl.mdsal.version} org.opendaylight.yangtools yang-parser-impl 2.0.6.1 - - org.opendaylight.netconf - restconf-common - 1.7.3 - - - org.opendaylight.netconf - restconf-nb-bierman02 - 1.7.3 - + diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java index 42caf368..f9a1ecbf 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java @@ -36,8 +36,8 @@ import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.SerializerHelper; import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.YangParameters; import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeSerializer; import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNodeSerializer; -import org.opendaylight.netconf.sal.restconf.impl.ControllerContext; import org.opendaylight.restconf.common.context.InstanceIdentifierContext; +import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -90,6 +90,27 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin { private static final Logger log = LoggerFactory.getLogger( RestconfApiCallNode.class); + /** + * Rest api call node service instance + */ + private RestapiCallNode restapiCallNode; + + /** + * Creates an instance of restconf api call node with restapi call node. + * + * @param r restapi call node + */ + public RestconfApiCallNode(RestapiCallNode r) { + this.restapiCallNode = r; + } + + /** + * Returns the restapi call node instance. + * @return + */ + public RestapiCallNode getRestapiCallNode() { + return restapiCallNode; + } /** * Sends the restconf request using the parameters map and the memory @@ -116,7 +137,7 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin { */ public void sendRequest(Map paramMap, SvcLogicContext ctx, Integer retryCount) throws SvcLogicException { - RestapiCallNode rest = new RestapiCallNode(); + RestapiCallNode rest = getRestapiCallNode(); RetryPolicy retryPolicy = null; HttpResponse r = new HttpResponse(); try { @@ -203,7 +224,7 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin { * @return JSON or XML message to be sent * @throws SvcLogicException when serializing the request fails */ - protected String serializeRequest(Map properties, + public String serializeRequest(Map properties, YangParameters params, String uri, InstanceIdentifierContext insIdCtx) throws SvcLogicException { @@ -227,9 +248,9 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin { * @return response message as properties * @throws SvcLogicException when serializing the response fails */ - protected Map serializeResponse(YangParameters params, - String uri, String response, - InstanceIdentifierContext insIdCtx) + public Map serializeResponse(YangParameters params, + String uri, String response, + InstanceIdentifierContext insIdCtx) throws SvcLogicException { PropertiesNodeSerializer propSer = new MdsalPropertiesNodeSerializer( insIdCtx.getSchemaNode(), insIdCtx.getSchemaContext(), uri); @@ -255,9 +276,7 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin { String uri) throws SvcLogicException { SchemaContext context = getSchemaContext(params); - ControllerContext contCtx = ControllerContext.getInstance(); - contCtx.onGlobalContextUpdated(context); - return contCtx.toInstanceIdentifier(uri); + return ParserIdentifier.toInstanceIdentifier(uri, context, null); } /** @@ -294,7 +313,7 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin { * @param res http response * @return response message body */ - private String getResponse(SvcLogicContext ctx, YangParameters params, + public String getResponse(SvcLogicContext ctx, YangParameters params, String pre, HttpResponse res) { ctx.setAttribute(pre + RES_CODE, String.valueOf(res.code)); ctx.setAttribute(pre + RES_MSG, res.message); diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonListener.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonListener.java index 107585a7..45317522 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonListener.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultJsonListener.java @@ -52,6 +52,16 @@ public class DefaultJsonListener implements JsonListener { */ private String modName; + /** + * Value of the current JSON node. + */ + private String value; + + /** + * Value namespace of the current JSON node. + */ + private String valueNs; + /** * Creates an instance of default json listener with its serializer helper. * @@ -64,16 +74,18 @@ public class DefaultJsonListener implements JsonListener { @Override public void enterJsonNode(String nodeName, JsonNode node, NodeType nodeType) throws SvcLogicException { - getNodeName(nodeName); + getNodeName(nodeName, false); switch (nodeType) { case SINGLE_INSTANCE_LEAF_NODE: - serializerHelper.addNode(name, modName, node.asText(), null, + getNodeName(node.asText(), true); + serializerHelper.addNode(name, modName, value, valueNs, SINGLE_INSTANCE_LEAF_NODE); break; case MULTI_INSTANCE_LEAF_NODE: - serializerHelper.addNode(name, modName, node.asText(), null, + getNodeName(node.asText(), true); + serializerHelper.addNode(name, modName, value, valueNs, MULTI_INSTANCE_LEAF_NODE); break; @@ -105,18 +117,29 @@ public class DefaultJsonListener implements JsonListener { /** * Parses the abstract JSON name and fills the node name and node - * namespace of the current JSON node. + * namespace or value and value namespace of the current JSON node . * - * @param abstractName abstract JSON name + * @param abstractName full name value + * @param isVal if it is for value parsing */ - private void getNodeName(String abstractName) { + private void getNodeName(String abstractName, boolean isVal) { String[] val = abstractName.split(":"); if (val.length == 2) { - modName = val[0]; - name = val[1]; + if (isVal) { + valueNs = val[0]; + value = val[1]; + } else { + modName = val[0]; + name = val[1]; + } } else { - name = val[0]; + if (isVal) { + value = val[0]; + valueNs = null; + } else { + name = val[0]; + modName = null; + } } } - } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlListener.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlListener.java index 57969146..03abf44f 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlListener.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DefaultXmlListener.java @@ -21,8 +21,11 @@ package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer; import org.dom4j.Element; +import org.dom4j.Namespace; import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import java.util.List; + import static java.lang.String.format; import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.NODE_TYPE_ERR; @@ -56,6 +59,11 @@ public class DefaultXmlListener implements XmlListener { break; case OBJECT_NODE: + List cont = element.content(); + if (cont != null && cont.size() == 2 && + isValueNsForLeaf(cont, element)) { + return; + } serializerHelper.addNode(element.getName(), element.getNamespace().getURI(), null, null, null); @@ -67,6 +75,39 @@ public class DefaultXmlListener implements XmlListener { } } + /** + * Returns true if element has value namespace and adds the node to + * property tree; false otherwise. + * + * @param cont content of the element + * @param element element + * @return true if element has value namespace; false otherwise + * @throws SvcLogicException + */ + private boolean isValueNsForLeaf(List cont, Element element) + throws SvcLogicException { + for (Object c : cont) { + if (c instanceof Namespace) { + String value = element.getText(); + if (value != null) { + String[] val = value.split(":"); + String valPrefix = val[0]; + String actVal = val[1]; + if (valPrefix != null && actVal != null && + valPrefix.equals(((Namespace) c).getPrefix())) { + serializerHelper.addNode( + element.getName(), + element.getNamespace().getURI(), + actVal, + ((Namespace) c).getURI(), null); + return true; + } + } + } + } + return false; + } + @Override public void exitXmlElement(Element element) throws SvcLogicException { serializerHelper.exitNode(); diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerUtil.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerUtil.java index 6acb04a8..598b08c1 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerUtil.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DfSerializerUtil.java @@ -26,7 +26,6 @@ import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace; import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.w3c.dom.Document; import org.xml.sax.InputSource; @@ -46,6 +45,7 @@ import java.io.StringWriter; import java.io.Writer; import java.net.URI; import java.net.URISyntaxException; +import java.util.Iterator; import static javax.xml.transform.OutputKeys.INDENT; import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.XmlNodeType.OBJECT_NODE; @@ -150,40 +150,44 @@ public final class DfSerializerUtil { * Returns the resolved namespace object from the input received from the * abstract data format. * - * @param mName module name - * @param curSchema current schema - * @param ctx schema context - * @param mUri module URI - * @param pNode properties node + * @param mName module name + * @param mUri module URI + * @param ctx schema context + * @param parent parent properties node * @return namespace * @throws SvcLogicException when resolving namespace fails */ - static Namespace getResolvedNamespace(String mName, SchemaNode curSchema, - SchemaContext ctx, String mUri, - PropertiesNode pNode) + static Namespace getResolvedNamespace(String mName, String mUri, + SchemaContext ctx, + PropertiesNode parent) throws SvcLogicException { - Module m = null; - URI namespace = curSchema.getQName().getNamespace(); + if (mName == null && mUri == null) { + Namespace parentNs = parent.namespace(); + return new Namespace(parentNs.moduleName(), parentNs.moduleNs(), + parentNs.revision()); + } + Iterator it; + Module mod; if (mName != null) { - m = ctx.findModule(mName).get(); - namespace = m == null ? null : m.getNamespace(); - } - if (mUri != null) { + it = ctx.findModules(mName).iterator(); + } else { + URI modUri = null; try { - m = ctx.findModule(new URI(mUri)).get(); + modUri = new URI(mUri); } catch (URISyntaxException e) { throw new SvcLogicException(URI_ERR, e); } - namespace = m == null ? null : m.getNamespace(); - mName = m.getName(); + it = ctx.findModules(modUri).iterator(); } - if (mName == null && mUri == null) { - return pNode.namespace(); + if (!it.hasNext()) { + return null; } + mod = it.next(); - return new Namespace(mName, namespace, getRevision(m.getRevision())); + return new Namespace(mod.getName(), mod.getQNameModule().getNamespace(), + getRevision(mod.getRevision())); } /** diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java index 5a898dfc..6f9f9070 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/MdsalSerializerHelper.java @@ -25,6 +25,9 @@ import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace; import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType; import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode; import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.RootNode; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; @@ -49,6 +52,8 @@ import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.M 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; import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE; +import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findDataChildSchemaByQName; +import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findSchemaForChild; import static org.opendaylight.yangtools.yang.data.util.ParserStreamUtils.findSchemaNodeByNameAndNamespace; /** @@ -108,14 +113,17 @@ public class MdsalSerializerHelper extends SerializerHelper baseType = resolveBaseTypeFrom(type); if (baseType instanceof IdentityrefTypeDefinition) { if (nodeType == null) { - ns = getResolvedNamespace(null,schemaNode, getSchemaCtx(), - valNs, propNode); + ns = getResolvedNamespace(null, valNs, getSchemaCtx(), + propNode); } else { - ns = getResolvedNamespace(valNs, schemaNode, getSchemaCtx(), - null, propNode); + ns = getResolvedNamespace(valNs, null, getSchemaCtx(), + propNode); } } } @@ -255,14 +268,28 @@ public class MdsalSerializerHelper extends SerializerHelper dataSchema = findSchemaNodeByNameAndNamespace( - (DataSchemaNode) curSchemaNode, name, namespace.moduleNs()); - if (dataSchema != null) { - DataSchemaNode node = dataSchema.pop(); - if (node != null) { - curSchemaNode = node; - return true; + QName qname = QName.create(namespace.moduleNs(), + Revision.of(namespace.revision()), name); + SchemaNode childNode = null; + if (curSchemaNode instanceof DataSchemaNode) { + Deque dataSchema = findSchemaNodeByNameAndNamespace( + (DataSchemaNode) curSchemaNode, name, namespace.moduleNs()); + if (dataSchema != null && !dataSchema.isEmpty()) { + childNode = dataSchema.pop(); + } + + if (!dataSchema.isEmpty()) { + childNode = findSchemaForChild(((ChoiceSchemaNode) childNode), + qname); } + + } else { + childNode = findDataChildSchemaByQName(curSchemaNode, qname); + } + + if (childNode != null) { + curSchemaNode = childNode; + return true; } return false; } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeXmlListener.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeXmlListener.java index cf59b779..39a08e38 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeXmlListener.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/PropertiesNodeXmlListener.java @@ -42,6 +42,8 @@ import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializ import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.UTF_HEADER; import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.XML_PREFIX; import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DfSerializerUtil.getXmlWriter; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE; /** * Representation of XML implementation of properties node listener. @@ -193,7 +195,11 @@ public class PropertiesNodeXmlListener implements PropertiesNodeListener { */ private String getNodeNamespace(PropertiesNode node) { PropertiesNode parent = node.parent(); - if (parent instanceof RootNode || !parent.namespace().moduleName() + if (parent.nodeType() == MULTI_INSTANCE_HOLDER_NODE || + parent.nodeType() == MULTI_INSTANCE_LEAF_HOLDER_NODE) { + parent = parent.parent(); + } + if (parent instanceof RootNode || ! parent.namespace().moduleName() .equals(node.namespace().moduleName())) { return node.namespace().moduleNs().toString(); } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeListener.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeListener.java index d9120912..491dcb09 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeListener.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/DefaultPropertiesNodeListener.java @@ -54,7 +54,11 @@ public class DefaultPropertiesNodeListener implements PropertiesNodeListener { */ if (node.nodeType() == SINGLE_INSTANCE_LEAF_NODE || node.nodeType() == MULTI_INSTANCE_LEAF_NODE) { - params.put(node.uri(), ((LeafNode) node).value()); + String val = ((LeafNode) node).value(); + if (((LeafNode) node).valueNs() != null) { + val = ((LeafNode) node).valueNs().moduleName() + ":" + val; + } + params.put(node.uri(), val); } } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java index c2414626..13a5c5a0 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java @@ -33,6 +33,7 @@ import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPrope import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getListName; import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getNamespace; import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getNodeType; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getParsedValue; 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; @@ -116,26 +117,32 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer - + + + + + + diff --git a/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerTest.java b/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerTest.java new file mode 100644 index 00000000..0f46d625 --- /dev/null +++ b/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatSerializerTest.java @@ -0,0 +1,612 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - CCSDK + * ================================================================================ + * Copyright (C) 2018 Huawei Technologies Co., Ltd. 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.onap.ccsdk.sli.plugins.yangserializers.dfserializer; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.plugins.restapicall.HttpResponse; +import org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode; +import org.onap.ccsdk.sli.plugins.restconfapicall.RestconfApiCallNode; +import org.opendaylight.restconf.common.context.InstanceIdentifierContext; + +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +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_JSON_ID; +import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_JSON_RPC; +import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_JSON_YANG; +import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_XML_ID; +import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_XML_RPC; +import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatUtilsTest.ENCODE_TO_XML_YANG; + + +/** + * Unit test cases for data format serialization and restconf api call node. + */ +public class DataFormatSerializerTest { + + private Map p; + + private RestconfApiCallNode restconf; + + private RestapiCallNode restApi; + + private DfCaptor dfCaptor; + + /** + * Sets up the pre-requisite for each test case. + * + * @throws SvcLogicException when test case fails + */ + @Before + public void setUp() throws SvcLogicException { + p = new HashMap<>(); + p.put("restapiUser", "user1"); + p.put("restapiPassword", "abc123"); + p.put("responsePrefix", "response"); + p.put("skipSending", "true"); + restApi = new RestapiCallNode(); + restconf = mock(RestconfApiCallNode.class); + dfCaptor = new DfCaptor(); + createMethodMocks(); + } + + /** + * Creates method mocks using mockito for RestconfApiCallNode class. + * + * @throws SvcLogicException when test case fails + */ + private void createMethodMocks() throws SvcLogicException { + doReturn(restApi).when(restconf).getRestapiCallNode(); + doCallRealMethod().when(restconf).sendRequest( + any(Map.class), any(SvcLogicContext.class)); + doCallRealMethod().when(restconf).sendRequest( + any(Map.class), any(SvcLogicContext.class), any(Integer.class)); + doAnswer(dfCaptor).when(restconf).serializeRequest( + any(Map.class), any(YangParameters.class), any(String.class), + any(InstanceIdentifierContext.class)); + } + + /** + * Creates mock using mockito with input data for decoding. + * + * @param decodeData input data + * @throws SvcLogicException when test case fails + */ + private void createMockForDecode(String decodeData) + throws SvcLogicException { + doReturn(decodeData).when(restconf).getResponse( + any(SvcLogicContext.class), any(YangParameters.class), + any(String.class), any(HttpResponse.class)); + doCallRealMethod().when(restconf).serializeResponse( + any(YangParameters.class), any(String.class), any(String.class), + any(InstanceIdentifierContext.class)); + } + + /** + * Verifies encoding of parameters to JSON data format with identity-ref + * and inter-file linking. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void encodeToJsonId() throws SvcLogicException { + String pre = "identity-test:test."; + SvcLogicContext ctx = createAttList(pre); + ctx.setAttribute(pre + "l", "abc"); + p.put("dirPath", "src/test/resources"); + p.put("format", "json"); + p.put("httpMethod", "post"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/identity-test:test"); + restconf.sendRequest(p, ctx); + assertThat(dfCaptor.getResult(), is(ENCODE_TO_JSON_ID)); + } + + /** + * Verifies encoding of parameters to XML data format with identity-ref + * and inter-file linking. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void encodeToXmlId() throws SvcLogicException { + String pre = "identity-test:test."; + SvcLogicContext ctx = createAttList(pre); + p.put("dirPath", "src/test/resources"); + p.put("format", "xml"); + p.put("httpMethod", "post"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/identity-test:test"); + restconf.sendRequest(p, ctx); + assertThat(dfCaptor.getResult(), is(ENCODE_TO_XML_ID)); + } + + /** + * Verifies decoding of parameters from JSON data format with identity-ref + * and inter-file linking. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void decodeToJsonId() throws SvcLogicException { + createMockForDecode(ENCODE_TO_JSON_ID); + SvcLogicContext ctx = new SvcLogicContext(); + String pre = "identity-test:test."; + p.put("dirPath", "src/test/resources"); + p.put("format", "json"); + p.put("httpMethod", "get"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/identity-test:test"); + restconf.sendRequest(p, ctx); + assertThat(ctx.getAttribute(pre + "l"), is("abc")); + verifyAttList(ctx, pre); + } + + /** + * Verifies decoding of parameters from XML data format with identity-ref + * and inter-file linking. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void decodeToXmlId() throws SvcLogicException { + createMockForDecode(ENCODE_TO_XML_ID); + SvcLogicContext ctx = new SvcLogicContext(); + String pre = "identity-test:test."; + p.put("dirPath", "src/test/resources"); + p.put("format", "xml"); + p.put("httpMethod", "get"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/identity-test:test"); + restconf.sendRequest(p, ctx); + verifyAttList(ctx, pre); + } + + /** + * Verifies encoding of parameters to JSON data format with containers, + * grouping and augment. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void encodeToJsonYang() throws SvcLogicException { + String pre = "test-yang:cont1.cont2."; + SvcLogicContext ctx = createAttListYang(pre); + p.put("dirPath", "src/test/resources"); + p.put("format", "json"); + p.put("httpMethod", "post"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/test-yang:cont1"); + restconf.sendRequest(p, ctx); + assertThat(dfCaptor.getResult(), is(ENCODE_TO_JSON_YANG)); + } + + /** + * Verifies decoding of parameters from JSON data format with containers, + * grouping and augment. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void decodeToJsonYang() throws SvcLogicException { + createMockForDecode(ENCODE_TO_JSON_YANG); + SvcLogicContext ctx = new SvcLogicContext(); + String pre = "test-yang:cont1.cont2."; + p.put("dirPath", "src/test/resources"); + p.put("format", "json"); + p.put("httpMethod", "get"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/test-yang:cont1"); + restconf.sendRequest(p, ctx); + verifyAttListYang(ctx, pre); + } + + /** + * Verifies encoding of parameters to XML data format with containers, + * grouping and augment. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void encodeToXmlYang() throws SvcLogicException { + String pre = "test-yang:cont1.cont2."; + SvcLogicContext ctx = createAttListYang(pre); + p.put("dirPath", "src/test/resources"); + p.put("format", "xml"); + p.put("httpMethod", "post"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/test-yang:cont1"); + restconf.sendRequest(p, ctx); + assertThat(dfCaptor.getResult(), is(ENCODE_TO_XML_YANG)); + } + + /** + * Verifies decoding of parameters from XML data format with containers, + * grouping and augment. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void decodeToXmlYang() throws SvcLogicException { + createMockForDecode(ENCODE_TO_XML_YANG); + SvcLogicContext ctx = new SvcLogicContext(); + String pre = "test-yang:cont1.cont2."; + p.put("dirPath", "src/test/resources"); + p.put("format", "xml"); + p.put("httpMethod", "get"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/test-yang:cont1"); + restconf.sendRequest(p, ctx); + verifyAttListYang(ctx, pre); + } + + /** + * Verifies encoding of and decoding from, JSON respectively for data + * format with containers, grouping and augment. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void codecToJsonRpc() throws SvcLogicException { + createMockForDecode(DECODE_FROM_JSON_RPC); + String inPre = "test-yang:create-sfc.input."; + String outPre = "test-yang:create-sfc.output."; + SvcLogicContext ctx = createAttListRpc(inPre); + p.put("dirPath", "src/test/resources"); + p.put("format", "json"); + p.put("httpMethod", "post"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/test-yang:create-sfc"); + restconf.sendRequest(p, ctx); + assertThat(dfCaptor.getResult(), is(ENCODE_TO_JSON_RPC)); + verifyAttListRpc(ctx, outPre); + } + + /** + * Verifies encoding of and decoding from, XML respectively for data + * format with containers, grouping and augment. + * + * @throws SvcLogicException when test case fails + */ + @Test + public void codecToXmlRpc() throws SvcLogicException { + createMockForDecode(DECODE_FROM_XML_RPC); + String inPre = "test-yang:create-sfc.input."; + String outPre = "test-yang:create-sfc.output."; + SvcLogicContext ctx = createAttListRpc(inPre); + p.put("dirPath", "src/test/resources"); + p.put("format", "xml"); + p.put("httpMethod", "post"); + p.put("restapiUrl", "http://echo.getpostman" + + ".com/restconf/operations/test-yang:create-sfc"); + restconf.sendRequest(p, ctx); + assertThat(dfCaptor.getResult(), is(ENCODE_TO_XML_RPC)); + verifyAttListRpc(ctx, outPre); + } + + /** + * Creates attribute list for encoding JSON or XML with identity-ref YANG + * file. + * + * @param pre prefix + * @return service logic context + */ + private SvcLogicContext createAttList(String pre) { + SvcLogicContext ctx = new SvcLogicContext(); + String pre1 = pre + "con1.interfaces."; + ctx.setAttribute(pre + "con1.interface", "identity-types:physical"); + ctx.setAttribute(pre1 + "int-list[0].iden", "optical"); + ctx.setAttribute(pre1 + "int-list[0].available.ll[0]", "Giga"); + ctx.setAttribute(pre1 + "int-list[0].available.ll[1]", + "identity-types:Loopback"); + ctx.setAttribute(pre1 + "int-list[0].available.ll[2]", + "identity-types-second:Ethernet"); + ctx.setAttribute(pre1 + "int-list[0].available.leaf1", "58"); + ctx.setAttribute(pre1 + "int-list[0].available.leaf2", + "identity-types-second:iden2"); + + ctx.setAttribute(pre1 + "int-list[1].iden", "214748364"); + ctx.setAttribute(pre1 + "int-list[1].available.ll[0]", "Giga"); + ctx.setAttribute(pre1 + "int-list[1].available.ll[1]", + "identity-types:Loopback"); + ctx.setAttribute(pre1 + "int-list[1].available.ll[2]", + "identity-types-second:Ethernet"); + ctx.setAttribute(pre1 + "int-list[1].available.leaf1", + "8888"); + ctx.setAttribute(pre1 + "int-list[1].available.leaf2", + "identity-types-second:iden2"); + return ctx; + } + + /** + * Creates attribute list for encoding JSON or XML with container, + * grouping and augmented YANG file. + * + * @param pre prefix + * @return service logic context + */ + private SvcLogicContext createAttListYang(String pre) { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute(pre + "cont3.leaf10", "abc"); + ctx.setAttribute(pre + "list1[0].leaf1", "true"); + ctx.setAttribute(pre + "list1[0].leaf2", "abc"); + ctx.setAttribute(pre + "list1[0].leaf3", "abc"); + ctx.setAttribute(pre + "list1[0].ll1[0]", "abc"); + ctx.setAttribute(pre + "list1[0].ll1[1]", "abc"); + ctx.setAttribute(pre + "list1[0].ll2[0]", "abc"); + ctx.setAttribute(pre + "list1[0].ll2[1]", "abc"); + ctx.setAttribute(pre + "list1[0].cont4.leaf11", "abc"); + ctx.setAttribute(pre + "list1[0].list4[0].leaf8", "abc"); + ctx.setAttribute(pre + "list1[0].list4[1].leaf8", "abc"); + ctx.setAttribute(pre + "list1[0].list5[0].leaf9", "abc"); + ctx.setAttribute(pre + "list1[0].list5[1].leaf9", "abc"); + ctx.setAttribute(pre + "list1[1].leaf1", "true"); + ctx.setAttribute(pre + "list1[1].leaf2", "abc"); + ctx.setAttribute(pre + "list1[1].leaf3", "abc"); + ctx.setAttribute(pre + "list1[1].ll1[0]", "abc"); + ctx.setAttribute(pre + "list1[1].ll1[1]", "abc"); + ctx.setAttribute(pre + "list1[1].ll2[0]", "abc"); + ctx.setAttribute(pre + "list1[1].ll2[1]", "abc"); + ctx.setAttribute(pre + "list1[1].cont4.leaf11", "abc"); + ctx.setAttribute(pre + "list1[1].list4[0].leaf8", "abc"); + ctx.setAttribute(pre + "list1[1].list4[1].leaf8", "abc"); + ctx.setAttribute(pre + "list1[1].list5[0].leaf9", "abc"); + ctx.setAttribute(pre + "list1[1].list5[1].leaf9", "abc"); + ctx.setAttribute(pre + "list2[0].leaf4", "abc"); + ctx.setAttribute(pre + "list2[1].leaf4", "abc"); + ctx.setAttribute(pre + "leaf5", "abc"); + ctx.setAttribute(pre + "leaf6", "abc"); + ctx.setAttribute(pre + "ll3[0]", "abc"); + ctx.setAttribute(pre + "ll3[1]", "abc"); + ctx.setAttribute(pre + "ll4[0]", "abc"); + ctx.setAttribute(pre + "ll4[1]", "abc"); + ctx.setAttribute(pre + "cont4.leaf10", "abc"); + ctx.setAttribute(pre + "list6[0].leaf11", "abc"); + ctx.setAttribute(pre + "list6[1].leaf11", "abc"); + ctx.setAttribute(pre + "leaf12", "abc"); + ctx.setAttribute(pre + "ll5[0]", "abc"); + ctx.setAttribute(pre + "ll5[1]", "abc"); + ctx.setAttribute(pre + "cont4.test-augment:cont5.leaf13", "true"); + ctx.setAttribute(pre + "cont4.test-augment:list7[0].leaf14", "test"); + ctx.setAttribute(pre + "cont4.test-augment:list7[1].leaf14", "create"); + ctx.setAttribute(pre + "cont4.test-augment:leaf15", "abc"); + ctx.setAttribute(pre + "cont4.test-augment:ll6[0]", "unbounded"); + ctx.setAttribute(pre + "cont4.test-augment:ll6[1]", "8"); + ctx.setAttribute(pre + "cont4.test-augment:cont13.cont12.leaf26", + "abc"); + ctx.setAttribute(pre + "cont4.test-augment:cont13.list9[0].leaf27", + "abc"); + ctx.setAttribute(pre + "cont4.test-augment:cont13.list9[1].leaf27", + "abc"); + ctx.setAttribute(pre + "cont4.test-augment:cont13.leaf28", "abc"); + ctx.setAttribute(pre + "cont4.test-augment:cont13.ll9[0]", "abc"); + ctx.setAttribute(pre + "cont4.test-augment:cont13.ll9[1]", "abc"); + return ctx; + } + + /** + * Creates attribute list for encoding JSON or XML with RPC YANG file. + * + * @param pre prefix + * @return service logic context + */ + private SvcLogicContext createAttListRpc(String pre) { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute(pre + "cont14.leaf28", "abc"); + ctx.setAttribute(pre + "list10[0].leaf29", "abc"); + ctx.setAttribute(pre + "list10[1].leaf29", "abc"); + ctx.setAttribute(pre + "leaf30", "abc"); + ctx.setAttribute(pre + "ll10[0]", "abc"); + ctx.setAttribute(pre + "ll10[1]", "abc"); + ctx.setAttribute(pre + "cont15.leaf31", "abc"); + ctx.setAttribute(pre + "cont13.list9[0].leaf27", "abc"); + ctx.setAttribute(pre + "cont13.list9[1].leaf27", "abc"); + ctx.setAttribute(pre + "cont13.leaf28", "abc"); + ctx.setAttribute(pre + "cont13.ll9[0]", "abc"); + ctx.setAttribute(pre + "cont13.ll9[1]", "abc"); + return ctx; + } + + /** + * Verifies the attribute list for decoding from JSON or XML with + * identity-ref YANG file. + * + * @param ctx service logic context + * @param pre prefix + */ + private void verifyAttList(SvcLogicContext ctx, String pre) { + String pre1 = pre + "con1.interfaces."; + assertThat(ctx.getAttribute(pre + "con1.interface"), is( + "identity-types:physical")); + assertThat(ctx.getAttribute(pre + "con1.interface"), is( + "identity-types:physical")); + assertThat(ctx.getAttribute(pre1 + "int-list[0].iden"), is("optical")); + assertThat(ctx.getAttribute(pre1 + "int-list[0].available.ll[0]"), is( + "Giga")); + assertThat(ctx.getAttribute(pre1 + "int-list[0].available.ll[1]"), is( + "identity-types:Loopback")); + assertThat(ctx.getAttribute(pre1 + "int-list[0].available.ll[2]"), is( + "identity-types-second:Ethernet")); + assertThat(ctx.getAttribute(pre1 + "int-list[0].available.leaf1"), is( + "58")); + assertThat(ctx.getAttribute(pre1 + "int-list[0].available.leaf2"), is( + "identity-types-second:iden2")); + + assertThat(ctx.getAttribute(pre1 + "int-list[1].iden"), is( + "214748364")); + assertThat(ctx.getAttribute(pre1 + "int-list[1].available.ll[0]"), is( + "Giga")); + assertThat(ctx.getAttribute(pre1 + "int-list[1].available.ll[1]"), is( + "identity-types:Loopback")); + assertThat(ctx.getAttribute(pre1 + "int-list[1].available.ll[2]"), is( + "identity-types-second:Ethernet")); + assertThat(ctx.getAttribute(pre1 + "int-list[1].available.leaf1"), is( + "8888")); + assertThat(ctx.getAttribute(pre1 + "int-list[1].available.leaf2"), is( + "identity-types-second:iden2")); + } + + /** + * Verifies the attribute list for decoding from JSON or XML with + * container, grouping and augmented file. + * + * @param ctx service logic context + * @param pre prefix + */ + private void verifyAttListYang(SvcLogicContext ctx, String pre) { + assertThat(ctx.getAttribute(pre + "cont3.leaf10"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].leaf1"), is("true")); + assertThat(ctx.getAttribute(pre + "list1[0].leaf2"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].leaf3"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].ll1[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].ll1[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].ll2[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].ll2[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].cont4.leaf11"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].list4[0].leaf8"), + is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].list4[1].leaf8"), + is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].list5[0].leaf9"), + is("abc")); + assertThat(ctx.getAttribute(pre + "list1[0].list5[1].leaf9"), + is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].leaf1"), is("true")); + assertThat(ctx.getAttribute(pre + "list1[1].leaf2"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].leaf3"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].ll1[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].ll1[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].ll2[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].ll2[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].cont4.leaf11"), is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].list4[0].leaf8"), + is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].list4[1].leaf8"), + is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].list5[0].leaf9"), + is("abc")); + assertThat(ctx.getAttribute(pre + "list1[1].list5[1].leaf9"), + is("abc")); + assertThat(ctx.getAttribute(pre + "list2[0].leaf4"), is("abc")); + assertThat(ctx.getAttribute(pre + "list2[1].leaf4"), is("abc")); + assertThat(ctx.getAttribute(pre + "leaf5"), is("abc")); + assertThat(ctx.getAttribute(pre + "leaf6"), is("abc")); + assertThat(ctx.getAttribute(pre + "ll3[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "ll3[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "ll4[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "ll4[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont4.leaf10"), is( "abc")); + assertThat(ctx.getAttribute(pre + "list6[0].leaf11"), is("abc")); + assertThat(ctx.getAttribute(pre + "list6[1].leaf11"), is("abc")); + assertThat(ctx.getAttribute(pre + "leaf12"), is("abc")); + assertThat(ctx.getAttribute(pre + "ll5[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "ll5[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:cont5.leaf13"), + is("true")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:list7[0].leaf14"), + is("test")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:list7[1].leaf14"), + is("create")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:leaf15"), + is("abc")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:ll6[0]"), + is("unbounded")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:ll6[1]"), + is("8")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:cont13" + + ".cont12.leaf26"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:cont13.list9[0]" + + ".leaf27"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:cont13.list9[1]" + + ".leaf27"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:cont13.leaf28"), + is("abc")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:cont13.ll9[0]"), + is("abc")); + assertThat(ctx.getAttribute(pre + "cont4.test-augment:cont13.ll9[1]"), + is("abc")); + } + + /** + * Verifies the attribute list for decoding from JSON or XML with + * RPC YANG file. + * + * @param ctx service logic context + * @param pre prefix + */ + private void verifyAttListRpc(SvcLogicContext ctx, String pre) { + assertThat(ctx.getAttribute(pre + "cont16.leaf32"), is("abc")); + assertThat(ctx.getAttribute(pre + "list11[0].leaf33"), is("abc")); + assertThat(ctx.getAttribute(pre + "list11[1].leaf33"), is("abc")); + assertThat(ctx.getAttribute(pre + "leaf34"), is("abc")); + assertThat(ctx.getAttribute(pre + "ll11[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "ll11[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont17.leaf35"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont13.cont12.leaf26"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont13.list9[0].leaf27"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont13.list9[1].leaf27"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont13.ll9[0]"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont13.ll9[1]"), is("abc")); + assertThat(ctx.getAttribute(pre + "cont13.leaf28"), is("abc")); + } + + /** + * Captures the data format messages by mocking it, which can be used in + * testing the value. + * + * @param capturing data format + */ + public class DfCaptor implements Answer { + + private String result; + + /** + * Returns the captured data format message. + * + * @return data format message. + */ + public String getResult() { + return result; + } + + @Override + public String answer(InvocationOnMock invocationOnMock) + throws Throwable { + result = (String) invocationOnMock.callRealMethod(); + return result; + } + } + +} diff --git a/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatUtilsTest.java b/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatUtilsTest.java new file mode 100644 index 00000000..c7efdeb3 --- /dev/null +++ b/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/dfserializer/DataFormatUtilsTest.java @@ -0,0 +1,504 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - CCSDK + * ================================================================================ + * Copyright (C) 2018 Huawei Technologies Co., Ltd. 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.onap.ccsdk.sli.plugins.yangserializers.dfserializer; + +/** + * Unit test case utilities for data format serializer and restconf api call + * node. + */ +public final class DataFormatUtilsTest { + + static final String ENCODE_TO_JSON_ID = "{\n" + + " \"identity-test:con1\": {\n" + + " \"interfaces\": {\n" + + " \"int-list\": [\n" + + " {\n" + + " \"iden\": \"optical\",\n" + + " \"available\": {\n" + + " \"ll\": [\n" + + " \"Giga\",\n" + + " \"identity-types:Loopback\",\n" + + " \"identity-types-second:Ethernet" + + "\"\n" + + " ],\n" + + " \"leaf1\": \"58\",\n" + + " \"leaf2\": \"identity-types-second:iden" + + "2\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"iden\": \"214748364\",\n" + + " \"available\": {\n" + + " \"ll\": [\n" + + " \"Giga\",\n" + + " \"identity-types:Loopback\",\n" + + " \"identity-types-second:Ethernet" + + "\"\n" + + " ],\n" + + " \"leaf1\": \"8888\",\n" + + " \"leaf2\": \"identity-types-second:ide" + + "n2\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"interface\": \"identity-types:physical\"\n" + + " },\n" + + " \"identity-test:l\": \"abc\"\n" + + "}"; + + static final String ENCODE_TO_XML_ID = "\n" + + "\n" + + " \n" + + " \n" + + " optical\n" + + " \n" + + " Giga\n" + + " yangid:Loopback\n" + + " yangid:Ethernet\n" + + " 58\n" + + " yangid:iden2\n" + + " \n" + + " \n" + + " \n" + + " 214748364\n" + + " \n" + + " Giga\n" + + " yangid:Loopback\n" + + " yangid:Ethernet\n" + + " 8888\n" + + " yangid:iden2\n" + + " \n" + + " \n" + + " \n" + + " " + + "yangid:physical\n" + + "\n"; + + static final String ENCODE_TO_JSON_YANG = "{\n" + + " \"test-yang:cont2\": {\n" + + " \"list1\": [\n" + + " {\n" + + " \"ll1\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"leaf1\": \"true\",\n" + + " \"ll2\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"list5\": [\n" + + " {\n" + + " \"leaf9\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf9\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"leaf3\": \"abc\",\n" + + " \"leaf2\": \"abc\",\n" + + " \"list4\": [\n" + + " {\n" + + " \"leaf8\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf8\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"cont4\": {\n" + + " \"leaf11\": \"abc\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"ll1\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"leaf1\": \"true\",\n" + + " \"ll2\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"leaf3\": \"abc\",\n" + + " \"list5\": [\n" + + " {\n" + + " \"leaf9\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf9\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"list4\": [\n" + + " {\n" + + " \"leaf8\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf8\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"leaf2\": \"abc\",\n" + + " \"cont4\": {\n" + + " \"leaf11\": \"abc\"\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"ll3\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"ll5\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"cont4\": {\n" + + " \"leaf10\": \"abc\",\n" + + " \"test-augment:cont13\": {\n" + + " \"ll9\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"list9\": [\n" + + " {\n" + + " \"leaf27\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf27\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"leaf28\": \"abc\",\n" + + " \"cont12\": {\n" + + " \"leaf26\": \"abc\"\n" + + " }\n" + + " },\n" + + " \"test-augment:list7\": [\n" + + " {\n" + + " \"leaf14\": \"test\"\n" + + " },\n" + + " {\n" + + " \"leaf14\": \"create\"\n" + + " }\n" + + " ],\n" + + " \"test-augment:leaf15\": \"abc\",\n" + + " \"test-augment:ll6\": [\n" + + " \"unbounded\",\n" + + " \"8\"\n" + + " ],\n" + + " \"test-augment:cont5\": {\n" + + " \"leaf13\": \"true\"\n" + + " }\n" + + " },\n" + + " \"ll4\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"cont3\": {\n" + + " \"leaf10\": \"abc\"\n" + + " },\n" + + " \"leaf5\": \"abc\",\n" + + " \"list2\": [\n" + + " {\n" + + " \"leaf4\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf4\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"leaf12\": \"abc\",\n" + + " \"leaf6\": \"abc\",\n" + + " \"list6\": [\n" + + " {\n" + + " \"leaf11\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf11\": \"abc\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + + static final String ENCODE_TO_XML_YANG = "\n" + + "\n" + + " \n" + + " abc\n" + + " abc\n" + + " true\n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " \n" + + " abc\n" + + " abc\n" + + " true\n" + + " abc\n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " abc\n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " \n" + + " test\n" + + " \n" + + " \n" + + " create\n" + + " \n" + + " abc\n" + + " unbounded\n" + + " 8\n" + + " \n" + + " true\n" + + " \n" + + " \n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + "\n"; + + + static final String ENCODE_TO_JSON_RPC = "{\n" + + " \"test-yang:input\": {\n" + + " \"leaf30\": \"abc\",\n" + + " \"list10\": [\n" + + " {\n" + + " \"leaf29\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf29\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"cont15\": {\n" + + " \"leaf31\": \"abc\"\n" + + " },\n" + + " \"cont14\": {\n" + + " \"leaf28\": \"abc\"\n" + + " },\n" + + " \"cont13\": {\n" + + " \"list9\": [\n" + + " {\n" + + " \"leaf27\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf27\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"ll9\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"leaf28\": \"abc\"\n" + + " },\n" + + " \"ll10\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ]\n" + + " }\n" + + "}"; + + static final String DECODE_FROM_JSON_RPC = "{\n" + + " \"test-yang:output\": {\n" + + " \"cont16\": {\n" + + " \"leaf32\": \"abc\"\n" + + " },\n" + + " \"list11\": [\n" + + " {\n" + + " \"leaf33\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf33\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"leaf34\": \"abc\",\n" + + " \"ll11\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"cont17\": {\n" + + " \"leaf35\": \"abc\"\n" + + " },\n" + + " \"cont13\": {\n" + + " \"cont12\": {\n" + + " \"leaf26\": \"abc\"\n" + + " },\n" + + " \"list9\": [\n" + + " {\n" + + " \"leaf27\": \"abc\"\n" + + " },\n" + + " {\n" + + " \"leaf27\": \"abc\"\n" + + " }\n" + + " ],\n" + + " \"ll9\": [\n" + + " \"abc\",\n" + + " \"abc\"\n" + + " ],\n" + + " \"leaf28\": \"abc\"\n" + + " }\n" + + " }\n" + + "}"; + + static final String ENCODE_TO_XML_RPC = "\n" + + "\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " abc\n" + + "\n"; + + static final String DECODE_FROM_XML_RPC = "\n" + + "\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " abc\n" + + " abc\n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " \n" + + " abc\n" + + " \n" + + " abc\n" + + " abc\n" + + " abc\n" + + " \n" + + ""; +} diff --git a/restconf-client/provider/src/test/resources/yang/identity-test.yang b/restconf-client/provider/src/test/resources/yang/identity-test.yang index 81d3f0a0..12ef717f 100644 --- a/restconf-client/provider/src/test/resources/yang/identity-test.yang +++ b/restconf-client/provider/src/test/resources/yang/identity-test.yang @@ -58,16 +58,16 @@ module identity-test { type available; } leaf leaf1 { - type leafref { - path "../../iden"; - } + type leafref { + path "../../iden"; + } } leaf leaf2 { - type identityref { + type identityref { base type:int-type; base sec:iden1; - } + } } } } diff --git a/restconf-client/provider/src/test/resources/yang/identity-types-second.yang b/restconf-client/provider/src/test/resources/yang/identity-types-second.yang index ad752de3..98d6a6e6 100644 --- a/restconf-client/provider/src/test/resources/yang/identity-types-second.yang +++ b/restconf-client/provider/src/test/resources/yang/identity-types-second.yang @@ -1,4 +1,4 @@ -module identity-types-second{ +module identity-types-second { yang-version 1; namespace "identity:list:second:ns:test:json:ser"; prefix "sec"; diff --git a/restconf-client/provider/src/test/resources/yang/test-augment.yang b/restconf-client/provider/src/test/resources/yang/test-augment.yang index bac19171..795000d3 100644 --- a/restconf-client/provider/src/test/resources/yang/test-augment.yang +++ b/restconf-client/provider/src/test/resources/yang/test-augment.yang @@ -14,19 +14,24 @@ module test-augment { augment "/t:cont1/t:cont2/t:cont4" { container cont5 { leaf leaf13 { - type string; + type empty; } } list list7 { - leaf leaf14 { - type string; - } + leaf leaf14 { + type instance-identifier; + } } leaf leaf15 { type string; } leaf-list ll6 { - type string; + type union { + type int32; + type enumeration { + enum "unbounded"; + } + } } uses "t:g1"; } @@ -34,16 +39,22 @@ module test-augment { uses "t:g1"; augment "/t:ch1/t:c1/t:cont8/t:cont6" { choice ch2 { - case c3 { - leaf leaf21 { - type string; - } - } - case c4 { - leaf leaf22 { - type string; - } - } + case c3 { + leaf leaf21 { + type string; + } + } + case c4 { + leaf leaf22 { + type enumeration { + enum zero; + enum one; + enum seven { + value 7; + } + } + } + } } } @@ -72,14 +83,24 @@ module test-augment { } augment "/t:create-sfc/t:input" { - leaf leaf36 { - type string; - } + leaf leaf36 { + type bits { + bit angle { + position 0; + } + bit degree { + position 1; + } + bit movement { + position 2; + } + } + } } augment "/t:create-sfc/t:output" { leaf leaf37 { - type string; + type boolean; } } } \ No newline at end of file diff --git a/restconf-client/provider/src/test/resources/yang/test-yang.yang b/restconf-client/provider/src/test/resources/yang/test-yang.yang index e99d87bf..b2bf0600 100644 --- a/restconf-client/provider/src/test/resources/yang/test-yang.yang +++ b/restconf-client/provider/src/test/resources/yang/test-yang.yang @@ -17,7 +17,7 @@ module test-yang { list list1 { key "leaf1 leaf2"; leaf leaf1 { - type string; + type empty; } leaf leaf2 { type string; @@ -87,66 +87,66 @@ module test-yang { } choice ch1 { - case c1 { - container cont8 { - container cont6 { - leaf leaf16 { - type string; - } - } - list list8 { - leaf leaf18 { - type string; - } - } - leaf leaf19 { - type string; - } - leaf-list ll7 { - type string; - } - } - } - case c2 { - container cont9 { - leaf leaf20 { - type string; - } - leaf-list ll8 { - type string; - } - container cont11 { - choice ch3 { - case c1 { - leaf leaf25 { + case c1 { + container cont8 { + container cont6 { + leaf leaf16 { type string; - } - uses g1; - } - } - } - } - } + } + } + list list8 { + leaf leaf18 { + type string; + } + } + leaf leaf19 { + type string; + } + leaf-list ll7 { + type string; + } + } + } + case c2 { + container cont9 { + leaf leaf20 { + type string; + } + leaf-list ll8 { + type string; + } + container cont11 { + choice ch3 { + case c1 { + leaf leaf25 { + type string; + } + uses g1; + } + } + } + } + } } grouping g1 { - container cont13 { - container cont12 { - leaf leaf26 { - type string; - } - } - list list9 { - leaf leaf27 { - type string; - } - } - leaf leaf28 { - type string; - } - leaf-list ll9 { - type string; - } + container cont13 { + container cont12 { + leaf leaf26 { + type string; + } + } + list list9 { + leaf leaf27 { + type string; + } + } + leaf leaf28 { + type string; + } + leaf-list ll9 { + type string; + } } } -- 2.16.6