Restore binding RPC shortcut
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / md / sal / binding / impl / RpcServiceAdapter.java
index c0232298245fe95a73ddae1e257208d932731445..074341cc0c558b6224c528678dd73eac9698583b 100644 (file)
@@ -5,10 +5,8 @@
  * 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.controller.md.sal.binding.impl;
 
-import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.util.concurrent.CheckedFuture;
@@ -18,11 +16,14 @@ import com.google.common.util.concurrent.MoreExecutors;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import java.util.Collection;
 import java.util.Map.Entry;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.controller.md.sal.dom.broker.spi.rpc.RpcRoutingStrategy;
+import org.opendaylight.controller.sal.core.compat.LegacyDOMRpcResultFutureAdapter;
+import org.opendaylight.mdsal.binding.dom.adapter.BindingRpcFutureAware;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -30,6 +31,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -62,10 +65,16 @@ class RpcServiceAdapter implements InvocationHandler {
         proxy = (RpcService) Proxy.newProxyInstance(type.getClassLoader(), new Class[] {type}, this);
     }
 
-    private ListenableFuture<RpcResult<?>> invoke0(final SchemaPath schemaPath, final NormalizedNode<?, ?> input) {
+    ListenableFuture<RpcResult<?>> invoke0(final SchemaPath schemaPath, final NormalizedNode<?, ?> input) {
         final CheckedFuture<DOMRpcResult, DOMRpcException> result = delegate.invokeRpc(schemaPath, input);
-        if (result instanceof LazyDOMRpcResultFuture) {
-            return ((LazyDOMRpcResultFuture) result).getBindingFuture();
+        if (result instanceof BindingRpcFutureAware) {
+            return ((BindingRpcFutureAware) result).getBindingFuture();
+        } else if (result instanceof LegacyDOMRpcResultFutureAdapter) {
+            CheckedFuture<org.opendaylight.mdsal.dom.api.DOMRpcResult, org.opendaylight.mdsal.dom.api.DOMRpcException>
+                    delegateFuture = ((LegacyDOMRpcResultFutureAdapter)result).delegate();
+            if (delegateFuture instanceof BindingRpcFutureAware) {
+                return ((BindingRpcFutureAware) delegateFuture).getBindingFuture();
+            }
         }
 
         return transformFuture(schemaPath, result, codec.getCodecFactory());
@@ -132,7 +141,7 @@ class RpcServiceAdapter implements InvocationHandler {
 
     private static ListenableFuture<RpcResult<?>> transformFuture(final SchemaPath rpc,
             final ListenableFuture<DOMRpcResult> domFuture, final BindingNormalizedNodeSerializer codec) {
-        return Futures.transform(domFuture, (Function<DOMRpcResult, RpcResult<?>>) input -> {
+        return Futures.transform(domFuture, input -> {
             final NormalizedNode<?, ?> domData = input.getResult();
             final DataObject bindingResult;
             if (domData != null) {
@@ -141,7 +150,13 @@ class RpcServiceAdapter implements InvocationHandler {
             } else {
                 bindingResult = null;
             }
-            return RpcResult.class.cast(RpcResultBuilder.success(bindingResult).build());
+
+            // DOMRpcResult does not have a notion of success, hence we have to reverse-engineer it by looking
+            // at reported errors and checking whether they are just warnings.
+            final Collection<RpcError> errors = input.getErrors();
+            return RpcResult.class.cast(RpcResultBuilder.status(errors.stream()
+                .noneMatch(error -> error.getSeverity() == ErrorSeverity.ERROR))
+                .withResult(bindingResult).withRpcErrors(errors).build());
         }, MoreExecutors.directExecutor());
     }