X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fbinding%2Fimpl%2FRpcServiceAdapter.java;h=af2ad1dc5baea14cbd7dc064ba6aa42fafbff067;hp=81aa46133a1b1b34eee37e518437c5fe93f24fdd;hb=3859df9beca8f13f1ff2b2744ed3470a1715bec3;hpb=a7c5e34ae9692603f50efd4cb426fb26d1a9fe3f diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java index 81aa46133a..af2ad1dc5b 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java @@ -5,30 +5,36 @@ * 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 static java.util.Objects.requireNonNull; + import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +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 java.util.concurrent.Future; 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.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; 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; @@ -40,6 +46,7 @@ import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaPath; +@Deprecated class RpcServiceAdapter implements InvocationHandler { private final ImmutableMap rpcNames; @@ -50,9 +57,9 @@ class RpcServiceAdapter implements InvocationHandler { RpcServiceAdapter(final Class type, final BindingToNormalizedNodeCodec codec, final DOMRpcService domService) { - this.type = Preconditions.checkNotNull(type); - this.codec = Preconditions.checkNotNull(codec); - this.delegate = Preconditions.checkNotNull(domService); + this.type = requireNonNull(type); + this.codec = requireNonNull(codec); + this.delegate = requireNonNull(domService); final ImmutableMap.Builder rpcBuilder = ImmutableMap.builder(); for (final Entry rpc : codec.getRpcMethodToSchema(type).entrySet()) { rpcBuilder.put(rpc.getKey(), createStrategy(rpc.getKey(), rpc.getValue())); @@ -61,10 +68,16 @@ class RpcServiceAdapter implements InvocationHandler { proxy = (RpcService) Proxy.newProxyInstance(type.getClassLoader(), new Class[] {type}, this); } - private ListenableFuture> invoke0(final SchemaPath schemaPath, final NormalizedNode input) { + ListenableFuture> invoke0(final SchemaPath schemaPath, final NormalizedNode input) { final CheckedFuture 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) { + Future delegateFuture = + ((LegacyDOMRpcResultFutureAdapter)result).delegate(); + if (delegateFuture instanceof BindingRpcFutureAware) { + return ((BindingRpcFutureAware) delegateFuture).getBindingFuture(); + } } return transformFuture(schemaPath, result, codec.getCodecFactory()); @@ -83,11 +96,11 @@ class RpcServiceAdapter implements InvocationHandler { } @Override - public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + public Object invoke(final Object proxyObj, final Method method, final Object[] args) { final RpcInvocationStrategy rpc = rpcNames.get(method); if (rpc != null) { - if (method.getParameterTypes().length == 0) { + if (method.getParameterCount() == 0) { return rpc.invokeEmpty(); } if (args.length != 1) { @@ -97,33 +110,33 @@ class RpcServiceAdapter implements InvocationHandler { } if (isObjectMethod(method)) { - return callObjectMethod(proxy, method, args); + return callObjectMethod(proxyObj, method, args); } throw new UnsupportedOperationException("Method " + method.toString() + "is unsupported."); } - private static boolean isObjectMethod(final Method m) { - switch (m.getName()) { + private static boolean isObjectMethod(final Method method) { + switch (method.getName()) { case "toString": - return (m.getReturnType().equals(String.class) && m.getParameterTypes().length == 0); + return method.getReturnType().equals(String.class) && method.getParameterCount() == 0; case "hashCode": - return (m.getReturnType().equals(int.class) && m.getParameterTypes().length == 0); + return method.getReturnType().equals(int.class) && method.getParameterCount() == 0; case "equals": - return (m.getReturnType().equals(boolean.class) && m.getParameterTypes().length == 1 && m - .getParameterTypes()[0] == Object.class); + return method.getReturnType().equals(boolean.class) && method.getParameterCount() == 1 && method + .getParameterTypes()[0] == Object.class; default: return false; } } - private Object callObjectMethod(final Object self, final Method m, final Object[] args) { - switch (m.getName()) { + private Object callObjectMethod(final Object self, final Method method, final Object[] args) { + switch (method.getName()) { case "toString": return type.getName() + "$Adapter{delegate=" + delegate.toString() + "}"; case "hashCode": return System.identityHashCode(self); case "equals": - return (self == args[0]); + return self == args[0]; default: return null; } @@ -131,20 +144,23 @@ class RpcServiceAdapter implements InvocationHandler { private static ListenableFuture> transformFuture(final SchemaPath rpc, final ListenableFuture domFuture, final BindingNormalizedNodeSerializer codec) { - return Futures.transform(domFuture, new Function>() { - @Override - public RpcResult apply(final DOMRpcResult input) { - final NormalizedNode domData = input.getResult(); - final DataObject bindingResult; - if (domData != null) { - final SchemaPath rpcOutput = rpc.createChild(QName.create(rpc.getLastComponent(), "output")); - bindingResult = codec.fromNormalizedNodeRpcData(rpcOutput, (ContainerNode) domData); - } else { - bindingResult = null; - } - return RpcResult.class.cast(RpcResultBuilder.success(bindingResult).build()); + return Futures.transform(domFuture, input -> { + final NormalizedNode domData = input.getResult(); + final DataObject bindingResult; + if (domData != null) { + final SchemaPath rpcOutput = rpc.createChild(QName.create(rpc.getLastComponent(), "output")); + bindingResult = codec.fromNormalizedNodeRpcData(rpcOutput, (ContainerNode) domData); + } else { + bindingResult = null; } - }); + + // 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 errors = input.getErrors(); + return RpcResult.class.cast(RpcResultBuilder.status(errors.stream() + .noneMatch(error -> error.getSeverity() == ErrorSeverity.ERROR)) + .withResult(bindingResult).withRpcErrors(errors).build()); + }, MoreExecutors.directExecutor()); } private abstract class RpcInvocationStrategy { @@ -168,7 +184,6 @@ class RpcServiceAdapter implements InvocationHandler { final SchemaPath getRpcName() { return rpcName; } - } private final class NonRoutedStrategy extends RpcInvocationStrategy { @@ -181,7 +196,6 @@ class RpcServiceAdapter implements InvocationHandler { NormalizedNode serialize(final DataObject input) { return LazySerializedContainerNode.create(getRpcName(), input, codec.getCodecRegistry()); } - } private final class RoutedStrategy extends RpcInvocationStrategy { @@ -207,6 +221,5 @@ class RpcServiceAdapter implements InvocationHandler { } return LazySerializedContainerNode.create(getRpcName(), input, codec.getCodecRegistry()); } - } }