From f9b44acb9f0d688448fe1a4c19d792bfc5b059ab Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 19 Dec 2019 19:04:36 +0100 Subject: [PATCH] Propagate MountPointContext to NetconfRpcStructureTransformer We need to be aware of schema mounts, so that we can properly handle them. This patch attempts to push down MountPointContext to all the interested places. Change-Id: Ic1c3a29bf69ee5838cd5f8434a0bcfdc767642b7 Signed-off-by: Robert Varga --- .../singleton/impl/MasterSalFacade.java | 15 +++++++-------- .../netconf/util/NetconfUtil.java | 19 +++++++++++++++---- .../netconf/sal/NetconfDeviceDataBroker.java | 8 ++++---- .../netconf/sal/NetconfDeviceSalFacade.java | 2 +- .../connect/netconf/util/NetconfBaseOps.java | 16 ++++++++++++---- .../util/NetconfRpcStructureTransformer.java | 19 +++++++++++-------- .../sal/NetconfDeviceDataBrokerTest.java | 3 ++- 7 files changed, 52 insertions(+), 30 deletions(-) diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java index bfda118dc2..0d376b74a2 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java @@ -33,7 +33,6 @@ import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalProvider import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.netconf.topology.singleton.messages.CreateInitialMasterActorData; import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; @@ -51,7 +50,7 @@ class MasterSalFacade implements AutoCloseable, RemoteDeviceHandler() { + sendInitialDataToActor().onComplete(new OnComplete<>() { @Override public void onComplete(final Throwable failure, final Object success) { if (failure == null) { @@ -132,7 +131,7 @@ class MasterSalFacade implements AutoCloseable, RemoteDeviceHandler sendInitialDataToActor() { final List sourceIdentifiers = - SchemaContextUtil.getConstituentModuleIdentifiers(currentSchemaContext).stream() + SchemaContextUtil.getConstituentModuleIdentifiers(currentMountContext.getSchemaContext()).stream() .map(mi -> RevisionSourceIdentifier.create(mi.getName(), mi.getRevision())) .collect(Collectors.toList()); diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java index 1b267003fb..0580159e15 100644 --- a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java +++ b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java @@ -22,8 +22,10 @@ import org.opendaylight.netconf.api.DocumentedException; import org.opendaylight.netconf.api.xml.XmlElement; import org.opendaylight.netconf.api.xml.XmlNetconfConstants; import org.opendaylight.netconf.api.xml.XmlUtil; +import org.opendaylight.yangtools.rcf8528.data.util.EmptyMountPointContext; import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadata; import org.opendaylight.yangtools.rfc7952.data.util.NormalizedMetadataWriter; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.Revision; @@ -160,16 +162,25 @@ public final class NetconfUtil { } } - // FIXME: document this interface contract. Does it support RFC8528/RFC8542? How? - public static NormalizedNodeResult transformDOMSourceToNormalizedNode(final SchemaContext schemaContext, + public static NormalizedNodeResult transformDOMSourceToNormalizedNode(final MountPointContext mountContext, final DOMSource value) throws XMLStreamException, URISyntaxException, IOException, SAXException { final NormalizedNodeResult resultHolder = new NormalizedNodeResult(); final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder); - final XmlCodecFactory codecs = XmlCodecFactory.create(schemaContext); - final ContainerSchemaNode dataRead = new NodeContainerProxy(NETCONF_DATA_QNAME, schemaContext.getChildNodes()); + final XmlCodecFactory codecs = XmlCodecFactory.create(mountContext); + + // FIXME: we probably need to propagate MountPointContext here and not just the child nodes + final ContainerSchemaNode dataRead = new NodeContainerProxy(NETCONF_DATA_QNAME, + mountContext.getSchemaContext().getChildNodes()); try (XmlParserStream xmlParserStream = XmlParserStream.create(writer, codecs, dataRead)) { xmlParserStream.traverse(value); } return resultHolder; } + + + // FIXME: document this interface contract. Does it support RFC8528/RFC8542? How? + public static NormalizedNodeResult transformDOMSourceToNormalizedNode(final SchemaContext schemaContext, + final DOMSource value) throws XMLStreamException, URISyntaxException, IOException, SAXException { + return transformDOMSourceToNormalizedNode(new EmptyMountPointContext(schemaContext), value); + } } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java index 57c27280bd..2a2e585a54 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java @@ -27,7 +27,7 @@ import org.opendaylight.netconf.sal.connect.netconf.sal.tx.WriteCandidateTx; import org.opendaylight.netconf.sal.connect.netconf.sal.tx.WriteRunningTx; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; public final class NetconfDeviceDataBroker implements PingPongMergingDOMDataBroker { @@ -39,10 +39,10 @@ public final class NetconfDeviceDataBroker implements PingPongMergingDOMDataBrok private boolean isLockAllowed = true; - public NetconfDeviceDataBroker(final RemoteDeviceId id, final SchemaContext schemaContext, + public NetconfDeviceDataBroker(final RemoteDeviceId id, final MountPointContext mountContext, final DOMRpcService rpc, final NetconfSessionPreferences netconfSessionPreferences) { this.id = id; - this.netconfOps = new NetconfBaseOps(rpc, schemaContext); + this.netconfOps = new NetconfBaseOps(rpc, mountContext); // get specific attributes from netconf preferences and get rid of it // no need to keep the entire preferences object, its quite big with all the capability QNames candidateSupported = netconfSessionPreferences.isCandidateSupported(); @@ -86,7 +86,7 @@ public final class NetconfDeviceDataBroker implements PingPongMergingDOMDataBrok return ImmutableClassToInstanceMap.of(); } - void setLockAllowed(boolean isLockAllowedOrig) { + void setLockAllowed(final boolean isLockAllowedOrig) { this.isLockAllowed = isLockAllowedOrig; } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java index c842e5f05e..91ef01eff4 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java @@ -76,7 +76,7 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice final DOMRpcService deviceRpc, final DOMActionService deviceAction) { final SchemaContext schemaContext = mountContext.getSchemaContext(); final NetconfDeviceDataBroker netconfDeviceDataBroker = - new NetconfDeviceDataBroker(id, schemaContext, deviceRpc, netconfSessionPreferences); + new NetconfDeviceDataBroker(id, mountContext, deviceRpc, netconfSessionPreferences); registerLockListener(netconfDeviceDataBroker); final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService(); diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOps.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOps.java index ac4033cbfc..7564e755e7 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOps.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOps.java @@ -47,6 +47,8 @@ import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade.Keepa import org.opendaylight.netconf.sal.connect.netconf.sal.SchemalessNetconfDeviceRpc; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.copy.config.input.target.ConfigTarget; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.get.config.input.source.ConfigSource; +import org.opendaylight.yangtools.rcf8528.data.util.EmptyMountPointContext; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; import org.opendaylight.yangtools.yang.common.Empty; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @@ -68,18 +70,23 @@ public final class NetconfBaseOps { private static final NodeIdentifier CONFIG_TARGET_NODEID = NodeIdentifier.create(ConfigTarget.QNAME); private final DOMRpcService rpc; - private final SchemaContext schemaContext; + private final MountPointContext mountContext; private final RpcStructureTransformer transformer; + @Deprecated public NetconfBaseOps(final DOMRpcService rpc, final SchemaContext schemaContext) { + this(rpc, new EmptyMountPointContext(schemaContext)); + } + + public NetconfBaseOps(final DOMRpcService rpc, final MountPointContext mountContext) { this.rpc = rpc; - this.schemaContext = schemaContext; + this.mountContext = mountContext; if (rpc instanceof KeepaliveDOMRpcService && ((KeepaliveDOMRpcService) rpc).getDeviceRpc() instanceof SchemalessNetconfDeviceRpc) { this.transformer = new SchemalessRpcStructureTransformer(); } else { - this.transformer = new NetconfRpcStructureTransformer(schemaContext); + this.transformer = new NetconfRpcStructureTransformer(mountContext); } } @@ -235,7 +242,8 @@ public final class NetconfBaseOps { requireNonNull(callback); final ListenableFuture future = rpc.invokeRpc(NETCONF_GET_PATH, isFilterPresent(filterPath) - ? NetconfMessageTransformUtil.wrap(NETCONF_GET_NODEID, toFilterStructure(filterPath.get(), schemaContext)) + ? NetconfMessageTransformUtil.wrap(NETCONF_GET_NODEID, + toFilterStructure(filterPath.get(), mountContext.getSchemaContext())) : NetconfMessageTransformUtil.GET_RPC_CONTENT); Futures.addCallback(future, callback, MoreExecutors.directExecutor()); return future; diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfRpcStructureTransformer.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfRpcStructureTransformer.java index 5e444cc361..1755659009 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfRpcStructureTransformer.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfRpcStructureTransformer.java @@ -13,13 +13,13 @@ import java.util.Optional; import javax.xml.stream.XMLStreamException; import org.opendaylight.netconf.api.ModifyAction; import org.opendaylight.netconf.util.NetconfUtil; +import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.DOMSourceAnyxmlNode; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes; import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; @@ -28,12 +28,12 @@ import org.xml.sax.SAXException; * Transforms rpc structures to normalized nodes and vice versa. */ class NetconfRpcStructureTransformer implements RpcStructureTransformer { - private static final Logger LOG = LoggerFactory.getLogger(NetconfRpcStructureTransformer.class); - private final SchemaContext schemaContext; - NetconfRpcStructureTransformer(final SchemaContext schemaContext) { - this.schemaContext = schemaContext; + private final MountPointContext mountContext; + + NetconfRpcStructureTransformer(final MountPointContext mountContext) { + this.mountContext = mountContext; } @Override @@ -43,7 +43,7 @@ class NetconfRpcStructureTransformer implements RpcStructureTransformer { if (data instanceof DOMSourceAnyxmlNode) { final NormalizedNodeResult node; try { - node = NetconfUtil.transformDOMSourceToNormalizedNode(schemaContext, + node = NetconfUtil.transformDOMSourceToNormalizedNode(mountContext, ((DOMSourceAnyxmlNode)data).getValue()); return NormalizedNodes.findNode(node.getResult(), path.getPathArguments()); } catch (final XMLStreamException | URISyntaxException | IOException | SAXException e) { @@ -59,11 +59,14 @@ class NetconfRpcStructureTransformer implements RpcStructureTransformer { public DOMSourceAnyxmlNode createEditConfigStructure(final Optional> data, final YangInstanceIdentifier dataPath, final Optional operation) { - return NetconfMessageTransformUtil.createEditConfigAnyxml(schemaContext, dataPath, operation, data); + // FIXME: propagate MountPointContext + return NetconfMessageTransformUtil.createEditConfigAnyxml(mountContext.getSchemaContext(), dataPath, operation, + data); } @Override public DataContainerChild toFilterStructure(final YangInstanceIdentifier path) { - return NetconfMessageTransformUtil.toFilterStructure(path, schemaContext); + // FIXME: propagate MountPointContext + return NetconfMessageTransformUtil.toFilterStructure(path, mountContext.getSchemaContext()); } } diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBrokerTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBrokerTest.java index 1b68063d23..1e176a83f2 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBrokerTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBrokerTest.java @@ -39,6 +39,7 @@ import org.opendaylight.netconf.sal.connect.netconf.sal.tx.WriteRunningTx; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.$YangModuleInfoImpl; +import org.opendaylight.yangtools.rcf8528.data.util.EmptyMountPointContext; import org.opendaylight.yangtools.util.concurrent.FluentFutures; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -119,7 +120,7 @@ public class NetconfDeviceDataBrokerTest { NetconfSessionPreferences prefs = NetconfSessionPreferences.fromStrings(Arrays.asList(caps)); final RemoteDeviceId id = new RemoteDeviceId("device-1", InetSocketAddress.createUnresolved("localhost", 17830)); - return new NetconfDeviceDataBroker(id, SCHEMA_CONTEXT, rpcService, prefs); + return new NetconfDeviceDataBroker(id, new EmptyMountPointContext(SCHEMA_CONTEXT), rpcService, prefs); } } -- 2.36.6