From 51772cbaa1ede16c121af64276dda6a2c96b1848 Mon Sep 17 00:00:00 2001 From: Ruslan Kashapov Date: Tue, 7 May 2024 14:09:19 +0300 Subject: [PATCH] Fix instance-identifier key being not recognized properly List key of type instance-identifier require own context based codec to properly parse the value. Previous usage TypeDefinitionAwareCodec (serves primitive types) resulted NPE due to absence of associated codec. JIRA: NETCONF-1214 Change-Id: Iaefe44b2be8346f55d4087b4512c010354fd2da6 Signed-off-by: Ruslan Kashapov --- .../operations/FilterContentValidator.java | 4 +- .../server/mdsal/operations/NC1214Test.java | 113 ++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 plugins/netconf-server-mdsal/src/test/java/org/opendaylight/netconf/server/mdsal/operations/NC1214Test.java diff --git a/plugins/netconf-server-mdsal/src/main/java/org/opendaylight/netconf/server/mdsal/operations/FilterContentValidator.java b/plugins/netconf-server-mdsal/src/main/java/org/opendaylight/netconf/server/mdsal/operations/FilterContentValidator.java index 0ed55171e2..a7ea7150bb 100644 --- a/plugins/netconf-server-mdsal/src/main/java/org/opendaylight/netconf/server/mdsal/operations/FilterContentValidator.java +++ b/plugins/netconf-server-mdsal/src/main/java/org/opendaylight/netconf/server/mdsal/operations/FilterContentValidator.java @@ -43,6 +43,7 @@ import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition; import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack; import org.slf4j.Logger; @@ -213,7 +214,8 @@ public class FilterContentValidator { keys.put(qualifiedName, keyValue); } else { final TypeDefinition> keyType = listKey.getType(); - if (keyType instanceof IdentityrefTypeDefinition || keyType instanceof LeafrefTypeDefinition) { + if (keyType instanceof IdentityrefTypeDefinition || keyType instanceof LeafrefTypeDefinition + || keyType instanceof InstanceIdentifierTypeDefinition) { final Document document = filterContent.getDomElement().getOwnerDocument(); final NamespaceContext nsContext = new UniversalNamespaceContextImpl(document, false); final EffectiveModelContext modelContext = schemaContext.getCurrentContext(); diff --git a/plugins/netconf-server-mdsal/src/test/java/org/opendaylight/netconf/server/mdsal/operations/NC1214Test.java b/plugins/netconf-server-mdsal/src/test/java/org/opendaylight/netconf/server/mdsal/operations/NC1214Test.java new file mode 100644 index 0000000000..92279ab77a --- /dev/null +++ b/plugins/netconf-server-mdsal/src/test/java/org/opendaylight/netconf/server/mdsal/operations/NC1214Test.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 PANTHEON.tech s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.server.mdsal.operations; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.doReturn; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opendaylight.netconf.api.xml.XmlElement; +import org.opendaylight.netconf.api.xml.XmlUtil; +import org.opendaylight.netconf.server.mdsal.CurrentSchemaContext; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.common.XMLNamespace; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; + +/** + * Addresses issue with list key of type instance-identifier being not recognized properly. + */ +@ExtendWith(MockitoExtension.class) +public class NC1214Test { + + private static final String MODULE1 = """ + module module1 { + yang-version 1; + namespace "urn:test:module1"; + prefix "module1"; + revision "2024-05-06"; + typedef ref-type { + type instance-identifier; + } + container root { + list items { + key name; + leaf name { + type string; + } + } + } + } + """; + private static final String MODULE2 = """ + module module2 { + yang-version 1; + namespace "urn:test:module2"; + prefix "module2"; + revision "2024-05-06"; + import module1 { + prefix "m1"; + revision-date "2024-05-06"; + } + container root { + list reference { + key ref; + leaf ref { + type m1:ref-type; + } + } + } + } + """; + private static final String XML = """ + + + /a:root/a:items[a:name='test'] + + + """; + + private static EffectiveModelContext CONTEXT = YangParserTestUtils.parseYang(MODULE1, MODULE2); + private static final QNameModule M1 = + QNameModule.of(XMLNamespace.of("urn:test:module1"), Revision.of("2024-05-06")); + private static final QNameModule M2 = + QNameModule.of(XMLNamespace.of("urn:test:module2"), Revision.of("2024-05-06")); + private static QName M1_ROOT = QName.create(M1, "root"); + private static QName M1_ITEMS = QName.create(M1, "items"); + private static QName M1_ITEM_KEY = QName.create(M1, "name"); + private static QName M2_ROOT = QName.create(M2, "root"); + private static QName M2_REF = QName.create(M2, "reference"); + private static QName M2_REF_KEY = QName.create(M2, "ref"); + + @Mock + CurrentSchemaContext currentContext; + + @Test + void instanceIdentifierReference() throws Exception { + doReturn(CONTEXT).when(currentContext).getCurrentContext(); + + final var xmlElement = XmlElement.fromDomDocument(XmlUtil.readXmlToDocument(XML)); + final var validator = new FilterContentValidator(currentContext); + final var expected = YangInstanceIdentifier.builder() + .node(M2_ROOT) + .node(M2_REF) + .nodeWithKey(M2_REF, M2_REF_KEY, YangInstanceIdentifier.builder() + .node(M1_ROOT) + .node(M1_ITEMS) + .nodeWithKey(M1_ITEMS, M1_ITEM_KEY, "test").build() + ).build(); + + assertEquals(expected, validator.validate(xmlElement)); + } +} -- 2.36.6