diff options
6 files changed, 235 insertions, 2 deletions
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 146e581f..20b06d0b 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 @@ -34,6 +34,7 @@ import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPrope 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.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.MULTI_INSTANCE_LEAF_NODE; import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE; @@ -121,13 +122,16 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer<Sche break; case SINGLE_INSTANCE_LEAF_NODE: node = node.addChild(localName, ns, SINGLE_INSTANCE_LEAF_NODE, - value, null, schema); + value, getValueNamespace(value, schemaCtx()), + schema); node = node.endNode(); curSchema = ((SchemaNode) node.appInfo()); break; case MULTI_INSTANCE_LEAF_NODE: node = node.addChild(getIndex(name), localName, ns, - MULTI_INSTANCE_LEAF_NODE, value, null, schema); + MULTI_INSTANCE_LEAF_NODE, value, + getValueNamespace(value, schemaCtx()), + schema); node = node.endNode(); curSchema = ((SchemaNode) node.appInfo()); break; diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java index fb57d63b..5b4755e8 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java @@ -20,13 +20,16 @@ package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.opendaylight.yangtools.yang.common.QName; 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.AugmentationSchemaNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; @@ -36,6 +39,8 @@ import java.util.Deque; import java.util.Iterator; import java.util.Optional; +import static com.google.common.base.Preconditions.checkArgument; + /** * Represents utilities for properties node tree. */ @@ -294,4 +299,55 @@ public final class MdsalPropertiesNodeUtils { public static String getRevision(Optional<Revision> r) { return (r.isPresent()) ? r.get().toString() : null; } + + /** + * Returns value namespace for leaf value. + * + * @param value value of the leaf + * @param ctx schema context + * @return value namespace + * @throws SvcLogicException if identity/module could not be found + */ + static Namespace getValueNamespace(String value, + SchemaContext ctx) + throws SvcLogicException { + String prefix = getPrefixFromValue(value); + if (prefix == null) { + return null; + } + + IdentitySchemaNode id = IdentityCodecUtil.parseIdentity(value, + ctx, + prefixToModule -> { + final Iterator<Module> modules = ctx.findModules(prefix).iterator(); + checkArgument(modules.hasNext(), "Could not find " + + "module %s", prefix); + return modules.next().getQNameModule(); + }); + + if (id == null) { + throw new SvcLogicException("Could not find identity"); + } + + return getModuleNamespace(id.getQName(), ctx); + } + + private static String getPrefixFromValue(String value) { + int lastIndexOfColon = value.lastIndexOf(":"); + if (lastIndexOfColon != -1) { + return value.substring(0, lastIndexOfColon); + } + return null; + } + + private static Namespace getModuleNamespace(QName qName, SchemaContext ctx) + throws SvcLogicException { + Optional<Module> module = ctx.findModule(qName.getModule()); + if (!module.isPresent()) { + throw new SvcLogicException("Could not find module node"); + } + Module m = module.get(); + return new Namespace(m.getName(), m.getQNameModule().getNamespace(), + getRevision(m.getRevision())); + } } diff --git a/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesSerializerTest.java b/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesSerializerTest.java index fddfe2d4..dc0da6f7 100644 --- a/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesSerializerTest.java +++ b/restconf-client/provider/src/test/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/PropertiesSerializerTest.java @@ -1071,6 +1071,60 @@ public final class PropertiesSerializerTest { assertThat(node.uri(), is("test-yang:cont18.leaf40")); } + @Test + public void testIdentityRef() throws SvcLogicException { + String uri = "identity-test:test"; + Map<String, String> params = new HashMap<>(); + params.put("identity-test:test.con1.interface", "identity-types:physical"); + params.put("identity-test:test.con1.interfaces.int-list[0].iden", "identity-test:Giga"); + params.put("identity-test:test.con1.interfaces.int-list[0].available.ll[0]", "identity-types:Loopback"); + params.put("identity-test:test.con1.interfaces.int-list[0].available.leaf1", "identity-types-second:Ethernet"); + params.put("identity-test:test.con1.interfaces.int-list[0].available.leaf2", "identity-types-second:iden2"); + InstanceIdentifierContext<?> iCtx = ParserIdentifier + .toInstanceIdentifier(uri, context, null); + + PropertiesNodeSerializer ser = new MdsalPropertiesNodeSerializer( + iCtx.getSchemaNode(), context, uri); + PropertiesNode node = ser.encode(params); + Map<String, PropertiesNode> childNodes = ((RootNode) node).children(); + assertThat(childNodes.containsKey("con1"), is(true)); + node = childNodes.get("con1"); + assertThat(node.uri(), is("identity-test:test.con1")); + LeafNode l = ((LeafNode) ((SingleInstanceNode) node).children().get("interface")); + assertThat(l.uri(), is("identity-test:test.con1.interface")); + assertThat(l.valueNs().moduleName(), is("identity-types")); + assertThat(l.valueNs().moduleNs().toString(), is("identity:list:ns:test:json:ser")); + + // identity type inside union + node = ((SingleInstanceNode) ((SingleInstanceNode) node).children().get("interfaces")); + node = ((ListHolderNode) ((SingleInstanceNode) node).children().get("int-list")); + node = ((MultiInstanceNode) ((ListHolderNode) node).children().get("0")); + l = ((LeafNode) ((MultiInstanceNode) node).children().get("iden")); + assertThat(l.uri(), is("identity-test:test.con1.interfaces.int-list[0].iden")); + assertThat(l.valueNs().moduleName(), is("identity-test")); + assertThat(l.valueNs().moduleNs().toString(), is("identity:ns:test:json:ser")); + + // leaf-list test + node = (SingleInstanceNode) ((MultiInstanceNode) node).children().get("available"); + LeafListHolderNode holder = (LeafListHolderNode) ((SingleInstanceNode) node).children().get("ll"); + l = ((LeafNode) holder.children().get("0")); + assertThat(l.uri(), is("identity-test:test.con1.interfaces.int-list[0].available.ll[0]")); + assertThat(l.valueNs().moduleName(), is("identity-types")); + assertThat(l.valueNs().moduleNs().toString(), is("identity:list:ns:test:json:ser")); + + // leaf-ref test + l = ((LeafNode) ((SingleInstanceNode) node).children().get("leaf1")); + assertThat(l.uri(), is("identity-test:test.con1.interfaces.int-list[0].available.leaf1")); + assertThat(l.valueNs().moduleName(), is("identity-types-second")); + assertThat(l.valueNs().moduleNs().toString(), is("identity:list:second:ns:test:json:ser")); + + // list of base identity test + l = ((LeafNode) ((SingleInstanceNode) node).children().get("leaf2")); + assertThat(l.uri(), is("identity-test:test.con1.interfaces.int-list[0].available.leaf2")); + assertThat(l.valueNs().moduleName(), is("identity-types-second")); + assertThat(l.valueNs().moduleNs().toString(), is("identity:list:second:ns:test:json:ser")); + } + public static SchemaContext compileYangFile() throws FileNotFoundException { String path = PropertiesSerializerTest.class.getResource("/yang").getPath(); File dir = new File(path); diff --git a/restconf-client/provider/src/test/resources/yang/identity-test.yang b/restconf-client/provider/src/test/resources/yang/identity-test.yang new file mode 100644 index 00000000..81d3f0a0 --- /dev/null +++ b/restconf-client/provider/src/test/resources/yang/identity-test.yang @@ -0,0 +1,77 @@ +module identity-test { + yang-version 1.1; + namespace "identity:ns:test:json:ser"; + prefix "id"; + + import identity-types { + prefix "type"; + } + + import identity-types-second { + prefix "sec"; + } + + revision "2013-07-15"; + + identity optical { + base type:int-type; + } + + identity Giga { + base type:physical; + } + + typedef available { + type identityref { + base "type:physical"; + } + } + + typedef typed{ + type union { + type int32; + type int8; + type identityref { + base type:int-type; + } + } + } + + container test { + leaf l { + type string; + } + container con1 { + leaf interface { + type identityref { + base "type:int-type"; + } + } + container interfaces { + list int-list { + key "iden"; + leaf iden { + type "id:typed"; + } + container available { + leaf-list ll { + type available; + } + leaf leaf1 { + type leafref { + path "../../iden"; + } + } + + leaf leaf2 { + 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 new file mode 100644 index 00000000..ad752de3 --- /dev/null +++ b/restconf-client/provider/src/test/resources/yang/identity-types-second.yang @@ -0,0 +1,25 @@ +module identity-types-second{ + yang-version 1; + namespace "identity:list:second:ns:test:json:ser"; + prefix "sec"; + + import identity-types { + prefix "type"; + } + + revision "2013-07-15"; + + identity virtual { + base type:int-type; + } + + identity Ethernet { + base type:physical; + } + + identity iden1; + + identity iden2 { + base iden1; + } +} diff --git a/restconf-client/provider/src/test/resources/yang/identity-types.yang b/restconf-client/provider/src/test/resources/yang/identity-types.yang new file mode 100644 index 00000000..25c8fa54 --- /dev/null +++ b/restconf-client/provider/src/test/resources/yang/identity-types.yang @@ -0,0 +1,17 @@ +module identity-types { + yang-version 1; + namespace "identity:list:ns:test:json:ser"; + prefix "type"; + revision "2013-07-15"; + + identity int-type { + } + + identity physical { + base int-type; + } + + identity Loopback { + base physical; + } +} |