From 4a5a98e174eed2b184548a4a3e4fdb75ac421913 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Sun, 24 Oct 2021 13:11:51 +0200 Subject: [PATCH] Move RestconfMappingNodeUtil.mapCapabilites() The only user here is SchemaContextHandler, who should understand which capabilities we support. Move the method along with its test. JIRA: NETCONF-773 Change-Id: Iac110846052e7b06411bf34bfc568f46741fb89d Signed-off-by: Robert Varga --- .../handlers/SchemaContextHandler.java | 46 +++++++++++++++--- .../mapping/RestconfMappingNodeUtil.java | 33 ------------- .../handlers/SchemaContextHandlerTest.java | 48 ++++++++++++++++--- .../mapping/RestconfMappingNodeUtilTest.java | 34 ------------- 4 files changed, 81 insertions(+), 80 deletions(-) diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandler.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandler.java index a9b3b367d6..f0fa0ed06c 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandler.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandler.java @@ -8,6 +8,7 @@ package org.opendaylight.restconf.nb.rfc8040.handlers; import static java.util.Objects.requireNonNull; +import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.$YangModuleInfoImpl.qnameOf; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Throwables; @@ -20,15 +21,21 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.inject.Singleton; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.common.api.TransactionCommitFailedException; import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMSchemaService; import org.opendaylight.restconf.common.errors.RestconfDocumentedException; +import org.opendaylight.restconf.nb.rfc8040.AbstractReplayParameter; +import org.opendaylight.restconf.nb.rfc8040.DepthParameter; +import org.opendaylight.restconf.nb.rfc8040.FieldsParameter; +import org.opendaylight.restconf.nb.rfc8040.FilterParameter; import org.opendaylight.restconf.nb.rfc8040.Rfc8040.IetfYangLibrary; -import org.opendaylight.restconf.nb.rfc8040.utils.mapping.RestconfMappingNodeUtil; +import org.opendaylight.restconf.nb.rfc8040.WithDefaultsParameter; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.RestconfState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.Capabilities; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.ModulesState; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.Module.ConformanceType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.module.Deviation; @@ -69,6 +76,10 @@ import org.slf4j.LoggerFactory; @Singleton public class SchemaContextHandler implements EffectiveModelContextListener, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(SchemaContextHandler.class); + + @VisibleForTesting + static final @NonNull QName CAPABILITY_QNAME = qnameOf("capability"); + private static final NodeIdentifier MODULE_CONFORMANCE_NODEID = NodeIdentifier.create(QName.create(IetfYangLibrary.MODULE_QNAME, "conformance-type").intern()); private static final NodeIdentifier MODULE_FEATURE_NODEID = @@ -113,14 +124,13 @@ public class SchemaContextHandler implements EffectiveModelContextListener, Auto public void onModelContextUpdated(final EffectiveModelContext context) { schemaContext = requireNonNull(context); - if (context.findModule(IetfYangLibrary.MODULE_QNAME).isPresent()) { + if (context.findModuleStatement(IetfYangLibrary.MODULE_QNAME).isPresent()) { putData(mapModulesByIetfYangLibraryYang(context.getModules(), context, - String.valueOf(this.moduleSetId.incrementAndGet()))); + String.valueOf(moduleSetId.incrementAndGet()))); } - final Module monitoringModule = schemaContext.findModule(RestconfState.QNAME.getModule()).orElse(null); - if (monitoringModule != null) { - putData(RestconfMappingNodeUtil.mapCapabilites(monitoringModule)); + if (schemaContext.findModuleStatement(RestconfState.QNAME.getModule()).isPresent()) { + putData(mapCapabilites()); } } @@ -154,6 +164,29 @@ public class SchemaContextHandler implements EffectiveModelContextListener, Auto } } + /** + * Map capabilites by ietf-restconf-monitoring. + * + * @param monitoringModule ietf-restconf-monitoring module + * @return mapped capabilites + */ + @VisibleForTesting + static ContainerNode mapCapabilites() { + return Builders.containerBuilder() + .withNodeIdentifier(new NodeIdentifier(RestconfState.QNAME)) + .withChild(Builders.containerBuilder() + .withNodeIdentifier(new NodeIdentifier(Capabilities.QNAME)) + .withChild(Builders.orderedLeafSetBuilder() + .withNodeIdentifier(new NodeIdentifier(CAPABILITY_QNAME)) + .withChildValue(DepthParameter.capabilityUri().toString()) + .withChildValue(FieldsParameter.capabilityUri().toString()) + .withChildValue(FilterParameter.capabilityUri().toString()) + .withChildValue(AbstractReplayParameter.capabilityUri().toString()) + .withChildValue(WithDefaultsParameter.capabilityUri().toString()) + .build()) + .build()) + .build(); + } /** * Map data from modules to {@link NormalizedNode}. @@ -177,7 +210,6 @@ public class SchemaContextHandler implements EffectiveModelContextListener, Auto .withChild(mapBuilder.build()).build(); } - /** * Map data by the specific module or submodule. * diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/mapping/RestconfMappingNodeUtil.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/mapping/RestconfMappingNodeUtil.java index 6f6d522ae5..ec35f824e2 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/mapping/RestconfMappingNodeUtil.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/mapping/RestconfMappingNodeUtil.java @@ -18,29 +18,20 @@ import java.time.format.DateTimeFormatter; import java.util.Collection; import java.util.Optional; import org.opendaylight.restconf.common.errors.RestconfDocumentedException; -import org.opendaylight.restconf.nb.rfc8040.AbstractReplayParameter; -import org.opendaylight.restconf.nb.rfc8040.DepthParameter; -import org.opendaylight.restconf.nb.rfc8040.FieldsParameter; -import org.opendaylight.restconf.nb.rfc8040.FilterParameter; -import org.opendaylight.restconf.nb.rfc8040.WithDefaultsParameter; import org.opendaylight.restconf.nb.rfc8040.utils.parser.IdentifierCodec; import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.RestconfState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.Capabilities; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.streams.Stream; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.streams.stream.Access; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; -import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaNode; @@ -48,7 +39,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; * Util class for mapping nodes. */ public final class RestconfMappingNodeUtil { - private static final QName CAPABILITY_QNAME = qnameOf("capability"); @VisibleForTesting static final QName DESCRIPTION_QNAME = qnameOf("description"); @VisibleForTesting @@ -66,29 +56,6 @@ public final class RestconfMappingNodeUtil { // Hidden on purpose } - /** - * Map capabilites by ietf-restconf-monitoring. - * - * @param monitoringModule ietf-restconf-monitoring module - * @return mapped capabilites - */ - public static ContainerNode mapCapabilites(final Module monitoringModule) { - return Builders.containerBuilder() - .withNodeIdentifier(new NodeIdentifier(RestconfState.QNAME)) - .withChild(Builders.containerBuilder() - .withNodeIdentifier(new NodeIdentifier(Capabilities.QNAME)) - .withChild(Builders.orderedLeafSetBuilder() - .withNodeIdentifier(new NodeIdentifier(CAPABILITY_QNAME)) - .withChildValue(DepthParameter.capabilityUri().toString()) - .withChildValue(FieldsParameter.capabilityUri().toString()) - .withChildValue(FilterParameter.capabilityUri().toString()) - .withChildValue(AbstractReplayParameter.capabilityUri().toString()) - .withChildValue(WithDefaultsParameter.capabilityUri().toString()) - .build()) - .build()) - .build(); - } - /** * Map data of yang notification to normalized node according to ietf-restconf-monitoring. * diff --git a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandlerTest.java b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandlerTest.java index dfa968029f..444c74bce9 100644 --- a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandlerTest.java +++ b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandlerTest.java @@ -7,6 +7,9 @@ */ package org.opendaylight.restconf.nb.rfc8040.handlers; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.mockito.Mockito.doReturn; @@ -14,6 +17,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import java.io.FileNotFoundException; +import java.util.stream.Collectors; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -26,7 +30,11 @@ import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMSchemaService; import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.Capabilities; import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; @@ -65,9 +73,9 @@ public class SchemaContextHandlerTest { doReturn(wTx).when(dataBroker).newWriteOnlyTransaction(); doReturn(CommitInfo.emptyFluentFuture()).when(wTx).commit(); - this.schemaContextHandler = new SchemaContextHandler(dataBroker, mockDOMSchemaService); + schemaContextHandler = new SchemaContextHandler(dataBroker, mockDOMSchemaService); - this.schemaContextHandler.onModelContextUpdated(SchemaContextHandlerTest.SCHEMA_CONTEXT); + schemaContextHandler.onModelContextUpdated(SCHEMA_CONTEXT); } /** @@ -98,7 +106,7 @@ public class SchemaContextHandlerTest { @Test public void getSchemaContextTest() { assertEquals("SchemaContextHandler should has reference to actual SchemaContext", - SCHEMA_CONTEXT, this.schemaContextHandler.get()); + SCHEMA_CONTEXT, schemaContextHandler.get()); } /** @@ -113,11 +121,39 @@ public class SchemaContextHandlerTest { // create new SchemaContext and update SchemaContextHandler final EffectiveModelContext newSchemaContext = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles(PATH_FOR_NEW_SCHEMA_CONTEXT)); - this.schemaContextHandler.onModelContextUpdated(newSchemaContext); + schemaContextHandler.onModelContextUpdated(newSchemaContext); assertNotEquals("SchemaContextHandler should not has reference to old SchemaContext", - SCHEMA_CONTEXT, this.schemaContextHandler.get()); + SCHEMA_CONTEXT, schemaContextHandler.get()); assertEquals("SchemaContextHandler should has reference to new SchemaContext", - newSchemaContext, this.schemaContextHandler.get()); + newSchemaContext, schemaContextHandler.get()); } + + @Test + public void restconfStateCapabilitesTest() { + final ContainerNode normNode = SchemaContextHandler.mapCapabilites(); + + @SuppressWarnings("unchecked") + final LeafSetNode capability = (LeafSetNode) normNode.body().stream() + // Find 'capabilities' container + .filter(child -> Capabilities.QNAME.equals(child.getIdentifier().getNodeType())) + .findFirst() + .map(ContainerNode.class::cast) + .orElseThrow() + // Find 'capability' leaf-list + .body().stream() + .filter(child -> SchemaContextHandler.CAPABILITY_QNAME.equals(child.getIdentifier().getNodeType())) + .findFirst() + .orElseThrow(); + + assertThat( + capability.body().stream().map(entry -> ((LeafSetEntryNode) entry).body()).collect(Collectors.toList()), + containsInAnyOrder( + equalTo("urn:ietf:params:restconf:capability:depth:1.0"), + equalTo("urn:ietf:params:restconf:capability:fields:1.0"), + equalTo("urn:ietf:params:restconf:capability:filter:1.0"), + equalTo("urn:ietf:params:restconf:capability:replay:1.0"), + equalTo("urn:ietf:params:restconf:capability:with-defaults:1.0"))); + } + } diff --git a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/mapping/RestconfMappingNodeUtilTest.java b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/mapping/RestconfMappingNodeUtilTest.java index 71fdfeaa41..ccee1c3376 100644 --- a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/mapping/RestconfMappingNodeUtilTest.java +++ b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/utils/mapping/RestconfMappingNodeUtilTest.java @@ -7,9 +7,6 @@ */ package org.opendaylight.restconf.nb.rfc8040.utils.mapping; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -19,10 +16,8 @@ import java.time.Instant; import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.junit.BeforeClass; import org.junit.Test; @@ -30,8 +25,6 @@ import org.opendaylight.restconf.nb.rfc8040.Rfc8040.IetfYangLibrary; import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils; import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler; import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.RestconfState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126.restconf.state.Capabilities; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.module.Deviation; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Revision; @@ -39,8 +32,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; -import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; -import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; @@ -87,31 +78,6 @@ public class RestconfMappingNodeUtilTest { verifyDeviations(mods); } - @Test - public void restconfStateCapabilitesTest() { - final Module monitoringModule = schemaContextMonitoring.findModule(RestconfState.QNAME.getModule()).get(); - final ContainerNode normNode = RestconfMappingNodeUtil.mapCapabilites(monitoringModule); - assertNotNull(normNode); - final List listOfValues = new ArrayList<>(); - - for (final DataContainerChild child : normNode.body()) { - if (child.getIdentifier().getNodeType().equals(Capabilities.QNAME)) { - for (final DataContainerChild dataContainerChild : ((ContainerNode) child).body()) { - for (final Object entry : ((LeafSetNode) dataContainerChild).body()) { - listOfValues.add(((LeafSetEntryNode) entry).body()); - } - } - } - } - - assertThat(listOfValues, containsInAnyOrder( - equalTo("urn:ietf:params:restconf:capability:depth:1.0"), - equalTo("urn:ietf:params:restconf:capability:fields:1.0"), - equalTo("urn:ietf:params:restconf:capability:filter:1.0"), - equalTo("urn:ietf:params:restconf:capability:replay:1.0"), - equalTo("urn:ietf:params:restconf:capability:with-defaults:1.0"))); - } - @Test public void toStreamEntryNodeTest() throws Exception { final YangInstanceIdentifier path = ParserIdentifier.toInstanceIdentifier( -- 2.36.6