From: Tony Tkacik Date: Thu, 21 May 2015 15:08:47 +0000 (+0200) Subject: Introduced Lazy DOM Rpc Result future. X-Git-Tag: release/beryllium~554 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=618ddca0315b8c749562928be14b3884c327a1e3 Introduced Lazy DOM Rpc Result future. Introduced LazyDOMRpcResultFuture which is used when Binding Aware app invokes Binding Aware Rpc implementation. - This future encapsulates original future which is deencapsulated without any processing once returned back to Binding RPC implementation. Change-Id: I4b65bdc884925a128db0ec6697ba84f37527593f Signed-off-by: Tony Tkacik (cherry picked from commit 4a8854a49907eb11952af93f188fa5050729d85b) --- diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcImplementationAdapter.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcImplementationAdapter.java index c4a99efdbe..fac13fb281 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcImplementationAdapter.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcImplementationAdapter.java @@ -7,25 +7,20 @@ */ package org.opendaylight.controller.md.sal.binding.impl; -import com.google.common.base.Function; import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.JdkFutureAdapters; import com.google.common.util.concurrent.ListenableFuture; -import java.util.Collection; import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier; import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation; import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; -import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.binding.util.BindingReflections; import org.opendaylight.yangtools.yang.binding.util.RpcServiceInvoker; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -33,15 +28,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; public class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation { - private static final Function EXCEPTION_MAPPER = new Function() { - - @Override - public DOMRpcException apply(final Exception input) { - // FIXME: Return correct exception - return null; - } - - }; private final BindingNormalizedNodeCodecRegistry codec; private final RpcServiceInvoker invoker; private final RpcService delegate; @@ -81,32 +67,7 @@ public class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation private CheckedFuture transformResult(final SchemaPath schemaPath, final ListenableFuture> bindingResult) { - final ListenableFuture transformed = Futures.transform(bindingResult, new Function,DOMRpcResult>() { - - @Override - public DOMRpcResult apply(final RpcResult input) { - return new DOMRpcResult() { - - @Override - public NormalizedNode getResult() { - - if(input instanceof DataContainer) { - return codec.toNormalizedNodeRpcData((DataContainer) input); - } - return null; - } - - @Override - public Collection getErrors() { - return input.getErrors(); - } - }; - } - - }); - return Futures.makeChecked(transformed, EXCEPTION_MAPPER); + return LazyDOMRpcResultFuture.create(codec,bindingResult); } - - } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcProviderServiceAdapter.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcProviderServiceAdapter.java index 05f11943cd..ca87330308 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcProviderServiceAdapter.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcProviderServiceAdapter.java @@ -41,7 +41,7 @@ public class BindingDOMRpcProviderServiceAdapter { } private ObjectRegistration register(final Class type, final T implementation, final Set domRpcs) { - final BindingRpcImplementationAdapter adapter = new BindingRpcImplementationAdapter(codec.getCodecRegistry(), type, implementation); + final BindingDOMRpcImplementationAdapter adapter = new BindingDOMRpcImplementationAdapter(codec.getCodecRegistry(), type, implementation); final DOMRpcImplementationRegistration domReg = domRpcRegistry.registerRpcImplementation(adapter, domRpcs); diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingRpcImplementationAdapter.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingRpcImplementationAdapter.java deleted file mode 100644 index 25a6ebde97..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingRpcImplementationAdapter.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * 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.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.JdkFutureAdapters; -import com.google.common.util.concurrent.ListenableFuture; -import javax.annotation.Nullable; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; -import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.binding.util.BindingReflections; -import org.opendaylight.yangtools.yang.binding.util.RpcServiceInvoker; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; - -public class BindingRpcImplementationAdapter implements DOMRpcImplementation { - - private static final Function EXCEPTION_MAPPER = new Function() { - - @Override - public DOMRpcException apply(final Exception input) { - // FIXME: Return correct exception - return null; - } - - }; - private final BindingNormalizedNodeCodecRegistry codec; - private final RpcServiceInvoker invoker; - private final RpcService delegate; - private final QNameModule module; - - private final Function,DOMRpcResult> lazySerializedMapper = new Function,DOMRpcResult>() { - - @Override - public DOMRpcResult apply(final RpcResult input) { - return LazySerializedDOMRpcResult.create(input, codec); - } - }; - - public BindingRpcImplementationAdapter(final BindingNormalizedNodeCodecRegistry codec, final Class type ,final T delegate) { - this.codec = codec; - this.delegate = delegate; - invoker = RpcServiceInvoker.from(type); - module = BindingReflections.getQNameModule(type); - } - - public QNameModule getQNameModule() { - return module; - } - - @Override - public CheckedFuture invokeRpc(final DOMRpcIdentifier rpc, @Nullable final NormalizedNode input) { - final SchemaPath schemaPath = rpc.getType(); - final DataObject bindingInput = input != null ? deserilialize(rpc.getType(),input) : null; - final ListenableFuture> bindingResult = invoke(schemaPath, bindingInput); - return transformResult(schemaPath,bindingResult); - } - - private DataObject deserilialize(final SchemaPath rpcPath, final NormalizedNode input) { - if(input instanceof LazySerializedContainerNode) { - return ((LazySerializedContainerNode) input).bindingData(); - } - final SchemaPath inputSchemaPath = rpcPath.createChild(QName.create(module,"input")); - return codec.fromNormalizedNodeRpcData(inputSchemaPath, (ContainerNode) input); - } - - - private ListenableFuture> invoke(final SchemaPath schemaPath, final DataObject input) { - return JdkFutureAdapters.listenInPoolThread(invoker.invokeRpc(delegate, schemaPath.getLastComponent(), input)); - } - - private CheckedFuture transformResult(final SchemaPath schemaPath, - final ListenableFuture> bindingResult) { - final ListenableFuture transformed = Futures.transform(bindingResult, lazySerializedMapper); - return Futures.makeChecked(transformed, EXCEPTION_MAPPER); - } - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/LazyDOMRpcResultFuture.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/LazyDOMRpcResultFuture.java new file mode 100644 index 0000000000..fc493659b0 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/LazyDOMRpcResultFuture.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the 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.Preconditions; +import com.google.common.base.Throwables; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +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.spi.DefaultDOMRpcResult; +import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; +import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +final class LazyDOMRpcResultFuture implements CheckedFuture { + + private final ListenableFuture> bindingFuture; + private final BindingNormalizedNodeCodecRegistry codec; + private volatile DOMRpcResult result; + + private LazyDOMRpcResultFuture(final ListenableFuture> delegate, + final BindingNormalizedNodeCodecRegistry codec) { + this.bindingFuture = Preconditions.checkNotNull(delegate, "delegate"); + this.codec = Preconditions.checkNotNull(codec, "codec"); + } + + static CheckedFuture create(final BindingNormalizedNodeCodecRegistry codec, + final ListenableFuture> bindingResult) { + return new LazyDOMRpcResultFuture(bindingResult, codec); + } + + ListenableFuture> getBindingFuture() { + return bindingFuture; + } + + @Override + public boolean cancel(final boolean mayInterruptIfRunning) { + return bindingFuture.cancel(mayInterruptIfRunning); + } + + @Override + public void addListener(final Runnable listener, final Executor executor) { + bindingFuture.addListener(listener, executor); + } + + @Override + public DOMRpcResult get() throws InterruptedException, ExecutionException { + if (result != null) { + return result; + } + return transformIfNecessary(bindingFuture.get()); + } + + @Override + public DOMRpcResult get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, + TimeoutException { + if (result != null) { + return result; + } + return transformIfNecessary(bindingFuture.get(timeout, unit)); + } + + @Override + public DOMRpcResult checkedGet() throws DOMRpcException { + try { + return get(); + } catch (InterruptedException | ExecutionException e) { + // FIXME: Add exception mapping + throw Throwables.propagate(e); + } + } + + @Override + public DOMRpcResult checkedGet(final long timeout, final TimeUnit unit) throws TimeoutException, DOMRpcException { + try { + return get(timeout, unit); + } catch (InterruptedException | ExecutionException e) { + // FIXME: Add exception mapping + throw Throwables.propagate(e); + } + } + + @Override + public boolean isCancelled() { + return bindingFuture.isCancelled(); + } + + @Override + public boolean isDone() { + return bindingFuture.isDone(); + } + + private synchronized DOMRpcResult transformIfNecessary(final RpcResult input) { + if (result == null) { + result = transform(input); + } + return result; + } + + private DOMRpcResult transform(final RpcResult input) { + if (input.isSuccessful()) { + final Object inputData = input.getResult(); + if (inputData instanceof DataContainer) { + return new DefaultDOMRpcResult(codec.toNormalizedNodeRpcData((DataContainer) inputData)); + } else { + return new DefaultDOMRpcResult((NormalizedNode) null); + } + } + return new DefaultDOMRpcResult(input.getErrors()); + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/LazySerializedDOMRpcResult.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/LazySerializedDOMRpcResult.java deleted file mode 100644 index ab368d70a0..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/LazySerializedDOMRpcResult.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * 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 java.util.Collection; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; -import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; -import org.opendaylight.yangtools.yang.binding.DataContainer; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; - -abstract class LazySerializedDOMRpcResult implements DOMRpcResult { - - private final RpcResult bindingResult; - - LazySerializedDOMRpcResult(final RpcResult bindingResult) { - this.bindingResult = bindingResult; - } - - static final LazySerializedDOMRpcResult create(final RpcResult bindingResult, final BindingNormalizedNodeCodecRegistry codec) { - final Object resultData = bindingResult.getResult(); - - if(resultData instanceof DataObject) { - return new DataResult(bindingResult,codec); - - - } - return new EmptyDataResult(bindingResult); - } - - RpcResult bidningRpcResult() { - return bindingResult; - } - - @Override - public Collection getErrors() { - return bindingResult.getErrors(); - } - - - private static final class DataResult extends LazySerializedDOMRpcResult { - - private final BindingNormalizedNodeCodecRegistry codec; - private NormalizedNode domData; - - public DataResult(final RpcResult bindingResult, final BindingNormalizedNodeCodecRegistry codec) { - super(bindingResult); - this.codec = codec; - } - - @Override - public NormalizedNode getResult() { - if(domData == null) { - domData = codec.toNormalizedNodeRpcData((DataContainer) bidningRpcResult().getResult()); - } - return domData; - } - } - - - private static final class EmptyDataResult extends LazySerializedDOMRpcResult { - - public EmptyDataResult(final RpcResult bindingResult) { - super(bindingResult); - } - - @Override - public NormalizedNode getResult() { - // FIXME: Should we return something else? - return null; - } - - } - - - -} 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 7f2a074af2..e4319a8e4f 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 @@ -62,6 +62,10 @@ class RpcServiceAdapter implements InvocationHandler { private final ListenableFuture> invoke0(final SchemaPath schemaPath, final NormalizedNode input) { final CheckedFuture result = delegate.invokeRpc(schemaPath, input); + if(result instanceof LazyDOMRpcResultFuture) { + return ((LazyDOMRpcResultFuture) result).getBindingFuture(); + } + return transformFuture(schemaPath, result, codec.getCodecFactory()); } @@ -127,9 +131,6 @@ class RpcServiceAdapter implements InvocationHandler { return Futures.transform(domFuture, new Function>() { @Override public RpcResult apply(final DOMRpcResult input) { - if (input instanceof LazySerializedDOMRpcResult) { - return ((LazySerializedDOMRpcResult) input).bidningRpcResult(); - } final NormalizedNode domData = input.getResult(); final DataObject bindingResult; if (domData != null) {