Introduced Lazy DOM Rpc Result future. 10/21110/2
authorTony Tkacik <ttkacik@cisco.com>
Thu, 21 May 2015 15:08:47 +0000 (17:08 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 26 May 2015 13:44:00 +0000 (13:44 +0000)
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 <ttkacik@cisco.com>
(cherry picked from commit 4a8854a49907eb11952af93f188fa5050729d85b)

opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcImplementationAdapter.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcProviderServiceAdapter.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingRpcImplementationAdapter.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/LazyDOMRpcResultFuture.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/LazySerializedDOMRpcResult.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java

index c4a99efdbe1822542f43644a012a6ff8a9c0be83..fac13fb2818a8a8f007ce1686dd223da555b841d 100644 (file)
@@ -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<? super Exception, DOMRpcException> EXCEPTION_MAPPER = new Function<Exception, DOMRpcException>() {
-
-        @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<DOMRpcResult, DOMRpcException> transformResult(final SchemaPath schemaPath,
             final ListenableFuture<RpcResult<?>> bindingResult) {
-        final ListenableFuture<DOMRpcResult> transformed = Futures.transform(bindingResult, new Function<RpcResult<?>,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<RpcError> getErrors() {
-                        return input.getErrors();
-                    }
-                };
-            }
-
-        });
-        return Futures.makeChecked(transformed, EXCEPTION_MAPPER);
+        return LazyDOMRpcResultFuture.create(codec,bindingResult);
     }
 
-
-
 }
index 05f11943cdb59391817eb1479823dfd01cb02984..ca8733030837aed2aad1f6a003b657b6bb05abf6 100644 (file)
@@ -41,7 +41,7 @@ public class BindingDOMRpcProviderServiceAdapter {
     }
 
     private <S extends RpcService, T extends S> ObjectRegistration<T> register(final Class<S> type, final T implementation, final Set<DOMRpcIdentifier> 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 (file)
index 25a6ebd..0000000
+++ /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<? super Exception, DOMRpcException> EXCEPTION_MAPPER = new Function<Exception, DOMRpcException>() {
-
-        @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<RpcResult<?>,DOMRpcResult> lazySerializedMapper = new Function<RpcResult<?>,DOMRpcResult>() {
-
-        @Override
-        public DOMRpcResult apply(final RpcResult<?> input) {
-            return LazySerializedDOMRpcResult.create(input, codec);
-        }
-    };
-
-    public <T extends RpcService> BindingRpcImplementationAdapter(final BindingNormalizedNodeCodecRegistry codec, final Class<T> 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<DOMRpcResult, DOMRpcException> 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<RpcResult<?>> 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<RpcResult<?>> invoke(final SchemaPath schemaPath, final DataObject input) {
-        return JdkFutureAdapters.listenInPoolThread(invoker.invokeRpc(delegate, schemaPath.getLastComponent(), input));
-    }
-
-    private CheckedFuture<DOMRpcResult, DOMRpcException> transformResult(final SchemaPath schemaPath,
-            final ListenableFuture<RpcResult<?>> bindingResult) {
-        final ListenableFuture<DOMRpcResult> 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 (file)
index 0000000..fc49365
--- /dev/null
@@ -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<DOMRpcResult, DOMRpcException> {
+
+    private final ListenableFuture<RpcResult<?>> bindingFuture;
+    private final BindingNormalizedNodeCodecRegistry codec;
+    private volatile DOMRpcResult result;
+
+    private LazyDOMRpcResultFuture(final ListenableFuture<RpcResult<?>> delegate,
+            final BindingNormalizedNodeCodecRegistry codec) {
+        this.bindingFuture = Preconditions.checkNotNull(delegate, "delegate");
+        this.codec = Preconditions.checkNotNull(codec, "codec");
+    }
+
+    static CheckedFuture<DOMRpcResult, DOMRpcException> create(final BindingNormalizedNodeCodecRegistry codec,
+            final ListenableFuture<RpcResult<?>> bindingResult) {
+        return new LazyDOMRpcResultFuture(bindingResult, codec);
+    }
+
+    ListenableFuture<RpcResult<?>> 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 (file)
index ab368d7..0000000
+++ /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<RpcError> 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;
-        }
-
-    }
-
-
-
-}
index 7f2a074af23db07a928a773a6f8e7ec1af2bb8fb..e4319a8e4f21f4e6db05ad8ecaf6d32de1810953 100644 (file)
@@ -62,6 +62,10 @@ class RpcServiceAdapter implements InvocationHandler {
 
     private final 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();
+        }
+
         return transformFuture(schemaPath, result, codec.getCodecFactory());
     }
 
@@ -127,9 +131,6 @@ class RpcServiceAdapter implements InvocationHandler {
         return Futures.transform(domFuture, new Function<DOMRpcResult, RpcResult<?>>() {
             @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) {