Merge "Remove unused isMaster variable in ClusteredNetconfDevice"
[netconf.git] / netconf / sal-netconf-connector / src / main / java / org / opendaylight / netconf / sal / connect / netconf / util / NetconfBaseOps.java
index 3362f0607fd1ef1df21ea61c74f1d0e9cda868ba..de61ee9073e467a57601d88001869a58adb3a4ad 100644 (file)
@@ -27,6 +27,7 @@ import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTr
 import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
 import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
 
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.FutureCallback;
@@ -34,11 +35,14 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+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.edit.config.input.EditContent;
 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.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
 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.NormalizedNode;
@@ -54,10 +58,16 @@ public final class NetconfBaseOps {
 
     private final DOMRpcService rpc;
     private final SchemaContext schemaContext;
+    private final RpcStructureTransformer transformer;
 
     public NetconfBaseOps(final DOMRpcService rpc, final SchemaContext schemaContext) {
         this.rpc = rpc;
         this.schemaContext = schemaContext;
+        if (rpc instanceof SchemalessNetconfDeviceRpc) {
+            this.transformer = new SchemalessRpcStructureTransformer();
+        } else {
+            this.transformer = new NetconfRpcStructureTransformer(schemaContext);
+        }
     }
 
     public ListenableFuture<DOMRpcResult> lock(final FutureCallback<DOMRpcResult> callback, final QName datastore) {
@@ -157,7 +167,7 @@ public final class NetconfBaseOps {
 
         final ListenableFuture<DOMRpcResult> future;
         if (isFilterPresent(filterPath)) {
-            final DataContainerChild<?, ?> node = toFilterStructure(filterPath.get(), schemaContext);
+            final DataContainerChild<?, ?> node = transformer.toFilterStructure(filterPath.get());
             future = rpc.invokeRpc(toPath(NETCONF_GET_CONFIG_QNAME),
                             NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, getSourceNode(datastore), node));
         } else {
@@ -169,6 +179,31 @@ public final class NetconfBaseOps {
         return future;
     }
 
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> getConfigRunningData(final FutureCallback<DOMRpcResult> callback,
+                                                                                 final Optional<YangInstanceIdentifier> filterPath) {
+        final ListenableFuture<DOMRpcResult> configRunning = getConfigRunning(callback, filterPath);
+        return extractData(filterPath, configRunning);
+    }
+
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> getData(final FutureCallback<DOMRpcResult> callback,
+                                                                    final Optional<YangInstanceIdentifier> filterPath) {
+        final ListenableFuture<DOMRpcResult> configRunning = get(callback, filterPath);
+        return extractData(filterPath, configRunning);
+    }
+
+    private ListenableFuture<Optional<NormalizedNode<?, ?>>> extractData(final Optional<YangInstanceIdentifier> path,
+                                                                         final ListenableFuture<DOMRpcResult> configRunning) {
+        return Futures.transform(configRunning, new Function<DOMRpcResult, Optional<NormalizedNode<?, ?>>>() {
+            @Override
+            public Optional<NormalizedNode<?, ?>> apply(final DOMRpcResult result) {
+                Preconditions.checkArgument(result.getErrors().isEmpty(), "Unable to read data: %s, errors: %s", path, result.getErrors());
+                final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataNode =
+                        ((ContainerNode) result.getResult()).getChild(NetconfMessageTransformUtil.toId(NetconfMessageTransformUtil.NETCONF_DATA_QNAME)).get();
+                return transformer.selectFromDataStructure(dataNode, path.get());
+            }
+        });
+    }
+
     public ListenableFuture<DOMRpcResult> getConfigRunning(final FutureCallback<DOMRpcResult> callback, final Optional<YangInstanceIdentifier> filterPath) {
         return getConfig(callback, NETCONF_RUNNING_QNAME, filterPath);
     }
@@ -222,7 +257,8 @@ public final class NetconfBaseOps {
     }
 
     public DataContainerChild<?, ?> createEditConfigStrcture(final Optional<NormalizedNode<?, ?>> lastChild, final Optional<ModifyAction> operation, final YangInstanceIdentifier dataPath) {
-        return NetconfMessageTransformUtil.createEditConfigStructure(schemaContext, dataPath, operation, lastChild);
+        final AnyXmlNode configContent = transformer.createEditConfigStructure(lastChild, dataPath, operation);
+        return Builders.choiceBuilder().withNodeIdentifier(toId(EditContent.QNAME)).withChild(configContent).build();
     }
 
     private ContainerNode getEditConfigContent(final QName datastore, final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation, final boolean rollback) {