From f65dce1db116e65f354afee08fa728fbb8a29f02 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Wed, 11 Mar 2015 11:34:27 +0100 Subject: [PATCH] Use default SchemaCtx for base netconf ops(if not available) If remote device does not expose yang model for base netconf operations, use a default, pre built schema context for these operations e.g. Lock, unlock Change-Id: I33e89adaa9a151cc236586e75264a907bf45a5df Signed-off-by: Maros Marsalek --- .../sal/connect/netconf/NetconfDevice.java | 2 + .../mapping/NetconfMessageTransformer.java | 41 +++++++++++++++---- .../connect/netconf/util/NetconfBaseOps.java | 2 +- .../NetconfMessageTransformerTest.java | 33 ++++++++++++--- 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java index b57a8912cc..ac84acb2f1 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java @@ -176,6 +176,8 @@ public final class NetconfDevice implements RemoteDevice rpcResultListenableFuture = deviceRpc.invokeRpc(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_QNAME), NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_CONTENT); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java index 4fdf5e584c..9e32dd0663 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.sal.connect.netconf.schema.mapping; import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RPC_QNAME; +import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_URI; import com.google.common.base.Function; import com.google.common.base.Preconditions; @@ -84,7 +85,6 @@ public class NetconfMessageTransformer implements MessageTransformer MAPPED_BASE_RPCS = Maps.uniqueIndex(BASE_NETCONF_CTX.getOperations(), QNAME_FUNCTION); private final SchemaContext schemaContext; private final MessageCounter counter; @@ -154,8 +155,17 @@ public class NetconfMessageTransformer implements MessageTransformer currentMappedRpcs = mappedRpcs; + + // Determine whether a base netconf operation is being invoked and also check if the device exposed model for base netconf + // If no, use pre built base netconf operations model + final boolean needToUseBaseCtx = mappedRpcs.get(rpcQName) == null && isBaseRpc(rpcQName); + if(needToUseBaseCtx) { + currentMappedRpcs = MAPPED_BASE_RPCS; + } + + Preconditions.checkNotNull(currentMappedRpcs.get(rpcQName), "Unknown rpc %s, available rpcs: %s", rpcQName, currentMappedRpcs.keySet()); + if(currentMappedRpcs.get(rpcQName).getInput() == null) { final Document document = XmlUtil.newDocument(); final Element elementNS = document.createElementNS(rpcQName.getNamespace().toString(), rpcQName.getLocalName()); document.appendChild(elementNS); @@ -167,7 +177,9 @@ public class NetconfMessageTransformer implements MessageTransformer normalizedNode; - if (NetconfMessageTransformUtil.isDataRetrievalOperation(rpc.getLastComponent())) { + final QName rpcQName = rpc.getLastComponent(); + if (NetconfMessageTransformUtil.isDataRetrievalOperation(rpcQName)) { final Element xmlData = NetconfMessageTransformUtil.getDataSubtree(message.getDocument()); final ContainerSchemaNode schemaForDataRead = NetconfMessageTransformUtil.createSchemaForDataRead(schemaContext); final ContainerNode dataNode = parserFactory.getContainerNodeParser().parse(Collections.singleton(xmlData), schemaForDataRead); @@ -226,8 +243,18 @@ public class NetconfMessageTransformer implements MessageTransformer documentElement = Collections.singleton(message.getDocument().getDocumentElement()); - final RpcDefinition rpcDefinition = mappedRpcs.get(rpc.getLastComponent()); - Preconditions.checkArgument(rpcDefinition != null, "Unable to parse response of %s, the rpc is unknown", rpc.getLastComponent()); + + Map currentMappedRpcs = mappedRpcs; + + // Determine whether a base netconf operation is being invoked and also check if the device exposed model for base netconf + // If no, use pre built base netconf operations model + final boolean needToUseBaseCtx = mappedRpcs.get(rpcQName) == null && isBaseRpc(rpcQName); + if(needToUseBaseCtx) { + currentMappedRpcs = MAPPED_BASE_RPCS; + } + + final RpcDefinition rpcDefinition = currentMappedRpcs.get(rpcQName); + Preconditions.checkArgument(rpcDefinition != null, "Unable to parse response of %s, the rpc is unknown", rpcQName); // In case no input for rpc is defined, we can simply construct the payload here if (rpcDefinition.getOutput() == null) { diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java index 7b231f989e..6af08eab4b 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java @@ -257,7 +257,7 @@ public final class NetconfBaseOps { ).build(); } - public static NormalizedNode getLockContent(final QName datastore) { + public static ContainerNode getLockContent(final QName datastore) { return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_LOCK_QNAME)) .withChild(getTargetNode(datastore)).build(); } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java index 35a6df8304..643c67af28 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java @@ -21,6 +21,7 @@ import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessag import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME; import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME; import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME; +import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_LOCK_QNAME; import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME; import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.createEditConfigStructure; import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toFilterStructure; @@ -80,11 +81,30 @@ public class NetconfMessageTransformerTest { XMLUnit.setIgnoreAttributeOrder(true); XMLUnit.setIgnoreComments(true); - schema = getSchema(); + schema = getSchema(true); netconfMessageTransformer = getTransformer(schema); } + @Test + public void testLockRequestBaseSchemaNotPresent() throws Exception { + final SchemaContext partialSchema = getSchema(false); + final NetconfMessageTransformer transformer = getTransformer(partialSchema); + final NetconfMessage netconfMessage = transformer.toRpcRequest(toPath(NETCONF_LOCK_QNAME), + NetconfBaseOps.getLockContent(NETCONF_CANDIDATE_QNAME)); + + assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString(""; + + transformer.toRpcResult(new NetconfMessage(XmlUtil.readXmlToDocument(result)), toPath(NETCONF_LOCK_QNAME)); + } + @Test public void testDiscardChangesRequest() throws Exception { final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_DISCARD_CHANGES_QNAME), @@ -105,9 +125,10 @@ public class NetconfMessageTransformerTest { ""); } + @Test public void tesGetSchemaResponse() throws Exception { - final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema()); + final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema(true)); final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument( "\n" + @@ -143,7 +164,7 @@ public class NetconfMessageTransformerTest { "\n" + "")); - final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema()); + final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema(true)); final DOMRpcResult compositeNodeRpcResult = netconfMessageTransformer.toRpcResult(response, toPath(NETCONF_GET_CONFIG_QNAME)); assertTrue(compositeNodeRpcResult.getErrors().isEmpty()); assertNotNull(compositeNodeRpcResult.getResult()); @@ -276,9 +297,11 @@ public class NetconfMessageTransformerTest { assertNull(compositeNodeRpcResult.getResult()); } - public SchemaContext getSchema() { + public SchemaContext getSchema(boolean addBase) { final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create(); - moduleInfoBackedContext.addModuleInfos(Collections.singleton($YangModuleInfoImpl.getInstance())); + if(addBase) { + moduleInfoBackedContext.addModuleInfos(Collections.singleton($YangModuleInfoImpl.getInstance())); + } moduleInfoBackedContext.addModuleInfos(Collections.singleton(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.$YangModuleInfoImpl.getInstance())); return moduleInfoBackedContext.tryToCreateSchemaContext().get(); } -- 2.36.6