*/
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;
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;
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);
}
-
-
}
}
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);
+++ /dev/null
-/*
- * 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);
- }
-
-}
--- /dev/null
+/*
+ * 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());
+ }
+
+}
+++ /dev/null
-/*
- * 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;
- }
-
- }
-
-
-
-}
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());
}
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) {