/**
* An abstract base class for remote RPC/action implementations.
*/
-abstract class AbstractRemoteImplementation<T extends AbstractExecute> {
+abstract class AbstractRemoteImplementation<T extends AbstractExecute<?>> {
// 0 for local, 1 for binding, 2 for remote
static final long COST = 2;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
/**
* A {@link DOMRpcImplementation} which routes invocation requests to a remote invoker actor.
}
@Override
- public ListenableFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final ContainerNode input) {
+ public ListenableFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc,
+ final NormalizedNode<?, ?> input) {
return new RemoteDOMRpcFuture(rpc.getType(), ask(ExecuteRpc.from(rpc, input)));
}
import com.google.common.base.MoreObjects.ToStringHelper;
import java.io.Serializable;
import org.eclipse.jdt.annotation.NonNull;
-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;
/**
* An abstract base class for invocation requests. Specialized via {@link ExecuteAction} and {@link ExecuteRpc}.
*/
-public abstract class AbstractExecute implements Serializable {
+public abstract class AbstractExecute<T extends NormalizedNode<?, ?>> implements Serializable {
private static final long serialVersionUID = 1L;
private final transient @NonNull SchemaPath type;
- private final transient @NonNull ContainerNode input;
+ private final transient T input;
- AbstractExecute(final @NonNull SchemaPath type, final ContainerNode input) {
+ AbstractExecute(final @NonNull SchemaPath type, final T input) {
this.type = requireNonNull(type);
- this.input = requireNonNull(input);
+ this.input = input;
}
public final @NonNull SchemaPath getType() {
return type;
}
- public final @NonNull ContainerNode getInput() {
+ public final T getInput() {
return input;
}
import java.io.Serializable;
import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
/**
* An abstract base class for invocation responses. Specialized via {@link ActionResponse} and {@link RpcResponse}.
*/
-public abstract class AbstractResponse implements Serializable {
+public abstract class AbstractResponse<T extends NormalizedNode<?, ?>> implements Serializable {
private static final long serialVersionUID = 1L;
- private final transient @Nullable ContainerNode output;
+ private final transient @Nullable T output;
- public AbstractResponse(final @Nullable ContainerNode output) {
+ public AbstractResponse(final @Nullable T output) {
this.output = output;
}
- public final @Nullable ContainerNode getOutput() {
+ public final @Nullable T getOutput() {
return output;
}
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@SuppressFBWarnings({"SE_TRANSIENT_FIELD_NOT_RESTORED", "DMI_NONSERIALIZABLE_OBJECT_WRITTEN"})
-public class ActionResponse extends AbstractResponse {
+public class ActionResponse extends AbstractResponse<ContainerNode> {
private static final long serialVersionUID = 1L;
private final transient @NonNull ImmutableList<@NonNull RpcError> errors;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.yangtools.yang.common.YangConstants;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataInput;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataOutput;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeStreamVersion;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-public final class ExecuteAction extends AbstractExecute {
+public final class ExecuteAction extends AbstractExecute<@NonNull ContainerNode> {
private static final long serialVersionUID = 1128904894827335676L;
private final @NonNull DOMDataTreeIdentifier path;
final SchemaPath name = stream.readSchemaPath();
final LogicalDatastoreType type = LogicalDatastoreType.readFrom(in);
final YangInstanceIdentifier path = stream.readYangInstanceIdentifier();
- ContainerNode input = (ContainerNode) stream.readOptionalNormalizedNode().orElse(null);
- if (input == null) {
- input = ImmutableNodes.containerNode(
- YangConstants.operationInputQName(name.getLastComponent().getModule()));
- }
+ final ContainerNode input = (ContainerNode) stream.readOptionalNormalizedNode().orElse(null);
executeAction = new ExecuteAction(name, new DOMDataTreeIdentifier(type, path), input);
}
import java.io.ObjectInput;
import java.io.ObjectOutput;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
-import org.opendaylight.yangtools.yang.common.YangConstants;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataInput;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataOutput;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeStreamVersion;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-public final class ExecuteRpc extends AbstractExecute {
+public final class ExecuteRpc extends AbstractExecute<@Nullable NormalizedNode<?, ?>> {
private static final long serialVersionUID = 1128904894827335676L;
- private ExecuteRpc(final @NonNull SchemaPath type, final @NonNull ContainerNode input) {
+ private ExecuteRpc(final @NonNull SchemaPath type, final @Nullable NormalizedNode<?, ?> input) {
super(type, input);
}
- public static @NonNull ExecuteRpc from(final @NonNull DOMRpcIdentifier rpc, final @NonNull ContainerNode input) {
+ public static @NonNull ExecuteRpc from(final @NonNull DOMRpcIdentifier rpc,
+ final @Nullable NormalizedNode<?, ?> input) {
return new ExecuteRpc(rpc.getType(), input);
}
public void readExternal(final ObjectInput in) throws IOException {
final NormalizedNodeDataInput stream = NormalizedNodeDataInput.newDataInput(in);
final SchemaPath type = SchemaPath.ROOT.createChild(stream.readQName());
- ContainerNode input = (ContainerNode) stream.readOptionalNormalizedNode().orElse(null);
- if (input == null) {
- input = ImmutableNodes.containerNode(
- YangConstants.operationInputQName(type.getLastComponent().getModule()));
- }
+ final NormalizedNode<?, ?> input = stream.readOptionalNormalizedNode().orElse(null);
executeRpc = new ExecuteRpc(type, input);
}
import java.io.ObjectOutput;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.datastore.node.utils.stream.SerializationUtils;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-public class RpcResponse extends AbstractResponse {
+public class RpcResponse extends AbstractResponse<NormalizedNode<?, ?>> {
private static final long serialVersionUID = -4211279498688989245L;
- public RpcResponse(final @Nullable ContainerNode output) {
+ public RpcResponse(final @Nullable NormalizedNode<?, ?> output) {
super(output);
}
@Override
public void readExternal(final ObjectInput in) throws IOException {
- rpcResponse = new RpcResponse((ContainerNode) SerializationUtils.readNormalizedNode(in).orElse(null));
+ rpcResponse = new RpcResponse(SerializationUtils.readNormalizedNode(in).orElse(null));
}
private Object readResolve() {
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import akka.actor.Status.Failure;
import java.time.Duration;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
public class OpsBrokerTest extends AbstractOpsTest {
+
@Test
public void testExecuteRpc() {
- final DOMRpcResult rpcResult = new DefaultDOMRpcResult(makeRPCOutput("bar"));
+ final ContainerNode invokeRpcResult = makeRPCOutput("bar");
+ final DOMRpcResult rpcResult = new DefaultDOMRpcResult(invokeRpcResult);
doReturn(FluentFutures.immediateFluentFuture(rpcResult)).when(domRpcService1)
.invokeRpc(eq(TEST_RPC_TYPE), any());
- final ExecuteRpc executeRpc = ExecuteRpc.from(TEST_RPC_ID, mock(ContainerNode.class));
+ final ExecuteRpc executeRpc = ExecuteRpc.from(TEST_RPC_ID, null);
rpcInvoker1.tell(executeRpc, rpcRegistry1Probe.getRef());
@Test
public void testExecuteRpcFailureWithException() {
- doReturn(FluentFutures.immediateFailedFluentFuture(new DOMRpcImplementationNotAvailableException("NOT FOUND")))
- .when(domRpcService1).invokeRpc(eq(TEST_RPC_TYPE), any());
+ when(domRpcService1.invokeRpc(eq(TEST_RPC_TYPE), any())).thenReturn(FluentFutures.immediateFailedFluentFuture(
+ new DOMRpcImplementationNotAvailableException("NOT FOUND")));
- final ExecuteRpc executeMsg = ExecuteRpc.from(TEST_RPC_ID, mock(ContainerNode.class));
+ final ExecuteRpc executeMsg = ExecuteRpc.from(TEST_RPC_ID, null);
rpcInvoker1.tell(executeMsg, rpcRegistry1Probe.getRef());
* 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.remote.rpc;
import static org.junit.Assert.assertEquals;
import org.opendaylight.mdsal.dom.spi.SimpleDOMActionResult;
import org.opendaylight.yangtools.util.concurrent.FluentFutures;
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;
/**
final ContainerNode rpcOutput = makeRPCOutput("bar");
final DOMRpcResult rpcResult = new DefaultDOMRpcResult(rpcOutput);
- final ContainerNode invokeRpcInput = makeRPCInput("foo");
- final ArgumentCaptor<ContainerNode> inputCaptor = ArgumentCaptor.forClass(ContainerNode.class);
+ final NormalizedNode<?, ?> invokeRpcInput = makeRPCInput("foo");
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ final ArgumentCaptor<NormalizedNode<?, ?>> inputCaptor =
+ ArgumentCaptor.forClass(NormalizedNode.class);
doReturn(FluentFutures.immediateFluentFuture(rpcResult)).when(domRpcService2)
.invokeRpc(eq(TEST_RPC_TYPE), inputCaptor.capture());
public void testInvokeAction() throws Exception {
final ContainerNode actionOutput = makeRPCOutput("bar");
final DOMActionResult actionResult = new SimpleDOMActionResult(actionOutput, Collections.emptyList());
- final ContainerNode invokeActionInput = makeRPCInput("foo");
- final ArgumentCaptor<ContainerNode> inputCaptor = ArgumentCaptor.forClass(ContainerNode.class);
+ final NormalizedNode<?, ?> invokeActionInput = makeRPCInput("foo");
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ final ArgumentCaptor<ContainerNode> inputCaptor =
+ ArgumentCaptor.forClass(ContainerNode.class);
doReturn(FluentFutures.immediateFluentFuture(actionResult)).when(domActionService2).invokeAction(
eq(TEST_RPC_TYPE), eq(TEST_DATA_TREE_ID), inputCaptor.capture());
final ListenableFuture<DOMActionResult> frontEndFuture = remoteActionImpl1.invokeAction(TEST_RPC_TYPE,
- TEST_DATA_TREE_ID, invokeActionInput);
+ TEST_DATA_TREE_ID, (ContainerNode) invokeActionInput);
assertTrue(frontEndFuture instanceof RemoteDOMActionFuture);
final DOMActionResult result = frontEndFuture.get(5, TimeUnit.SECONDS);
assertEquals(actionOutput, result.getOutput().get());
}
+ /**
+ * This test method invokes and executes the remote rpc.
+ */
+ @Test
+ public void testInvokeRpcWithNullInput() throws Exception {
+ final ContainerNode rpcOutput = makeRPCOutput("bar");
+ final DOMRpcResult rpcResult = new DefaultDOMRpcResult(rpcOutput);
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ final ArgumentCaptor<NormalizedNode<?, ?>> inputCaptor =
+ (ArgumentCaptor) ArgumentCaptor.forClass(NormalizedNode.class);
+
+ doReturn(FluentFutures.immediateFluentFuture(rpcResult)).when(domRpcService2)
+ .invokeRpc(eq(TEST_RPC_TYPE), inputCaptor.capture());
+
+ ListenableFuture<DOMRpcResult> frontEndFuture = remoteRpcImpl1.invokeRpc(TEST_RPC_ID, null);
+ assertTrue(frontEndFuture instanceof RemoteDOMRpcFuture);
+
+ final DOMRpcResult result = frontEndFuture.get(5, TimeUnit.SECONDS);
+ assertEquals(rpcOutput, result.getResult());
+ }
+
/**
* This test method invokes and executes the remote action.
*/
final ContainerNode actionOutput = makeRPCOutput("bar");
final DOMActionResult actionResult = new SimpleDOMActionResult(actionOutput);
- final ArgumentCaptor<ContainerNode> inputCaptor = ArgumentCaptor.forClass(ContainerNode.class);
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ final ArgumentCaptor<ContainerNode> inputCaptor =
+ ArgumentCaptor.forClass(ContainerNode.class);
doReturn(FluentFutures.immediateFluentFuture(actionResult)).when(domActionService2).invokeAction(
eq(TEST_RPC_TYPE), eq(TEST_DATA_TREE_ID), inputCaptor.capture());
final ContainerNode rpcOutput = null;
final DOMRpcResult rpcResult = new DefaultDOMRpcResult(rpcOutput);
- final ContainerNode invokeRpcInput = makeRPCInput("foo");
- final ArgumentCaptor<ContainerNode> inputCaptor = ArgumentCaptor.forClass(ContainerNode.class);
+ final NormalizedNode<?, ?> invokeRpcInput = makeRPCInput("foo");
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ final ArgumentCaptor<NormalizedNode<?, ?>> inputCaptor =
+ (ArgumentCaptor) ArgumentCaptor.forClass(NormalizedNode.class);
doReturn(FluentFutures.immediateFluentFuture(rpcResult)).when(domRpcService2)
.invokeRpc(eq(TEST_RPC_TYPE), inputCaptor.capture());
@SuppressWarnings({"checkstyle:AvoidHidingCauseException", "checkstyle:IllegalThrows"})
@Test(expected = DOMRpcException.class)
public void testInvokeRpcWithRemoteFailedFuture() throws Throwable {
- final ContainerNode invokeRpcInput = makeRPCInput("foo");
- final ArgumentCaptor<ContainerNode> inputCaptor = ArgumentCaptor.forClass(ContainerNode.class);
+ final NormalizedNode<?, ?> invokeRpcInput = makeRPCInput("foo");
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ final ArgumentCaptor<NormalizedNode<?, ?>> inputCaptor =
+ (ArgumentCaptor) ArgumentCaptor.forClass(NormalizedNode.class);
when(domRpcService2.invokeRpc(eq(TEST_RPC_TYPE), inputCaptor.capture())).thenReturn(
FluentFutures.immediateFailedFluentFuture(new RemoteDOMRpcException("Test Exception", null)));
@Test(expected = DOMActionException.class)
public void testInvokeActionWithRemoteFailedFuture() throws Throwable {
final ContainerNode invokeActionInput = makeRPCInput("foo");
- final ArgumentCaptor<ContainerNode> inputCaptor = ArgumentCaptor.forClass(ContainerNode.class);
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ final ArgumentCaptor<ContainerNode> inputCaptor =
+ ArgumentCaptor.forClass(ContainerNode.class);
when(domActionService2.invokeAction(eq(TEST_RPC_TYPE), eq(TEST_DATA_TREE_ID),
inputCaptor.capture())).thenReturn(FluentFutures.immediateFailedFluentFuture(
@Ignore
@Test(expected = RemoteDOMRpcException.class)
public void testInvokeRpcWithAkkaTimeoutException() throws Exception {
- final ContainerNode invokeRpcInput = makeRPCInput("foo");
+ final NormalizedNode<?, ?> invokeRpcInput = makeRPCInput("foo");
final ListenableFuture<DOMRpcResult> frontEndFuture = remoteRpcImpl1.invokeRpc(TEST_RPC_ID, invokeRpcInput);
assertTrue(frontEndFuture instanceof RemoteDOMRpcFuture);
@Test(expected = DOMRpcException.class)
@SuppressWarnings({"checkstyle:AvoidHidingCauseException", "checkstyle:IllegalThrows"})
public void testInvokeRpcWithLookupException() throws Throwable {
- final ContainerNode invokeRpcInput = makeRPCInput("foo");
+ final NormalizedNode<?, ?> invokeRpcInput = makeRPCInput("foo");
doThrow(new RuntimeException("test")).when(domRpcService2).invokeRpc(any(SchemaPath.class),
- any(ContainerNode.class));
+ any(NormalizedNode.class));
final ListenableFuture<DOMRpcResult> frontEndFuture = remoteRpcImpl1.invokeRpc(TEST_RPC_ID, invokeRpcInput);
assertTrue(frontEndFuture instanceof RemoteDOMRpcFuture);
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.common.YangConstants;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
}
@Override
- public ListenableFuture<? extends DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc,
- final ContainerNode input) {
+ public ListenableFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final NormalizedNode<?, ?> input) {
LOG.debug("get-constant invoked, current value: {}", constant);
return Futures.immediateFuture(new DefaultDOMRpcResult(ImmutableContainerNodeBuilder.create()
import org.opendaylight.yangtools.yang.common.YangConstants;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
}
@Override
- public ListenableFuture<? extends DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final ContainerNode input) {
+ public ListenableFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final NormalizedNode<?, ?> input) {
LOG.debug("get-contexted-constant invoked, current value: {}", constant);
return Futures.immediateFuture(new DefaultDOMRpcResult(ImmutableContainerNodeBuilder.create()
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.common.YangConstants;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
}
@Override
- public ListenableFuture<? extends DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final ContainerNode input) {
+ public ListenableFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final NormalizedNode<?, ?> input) {
LOG.debug("get-singleton-constant invoked, current value: {}", constant);
return Futures.immediateFuture(new DefaultDOMRpcResult(ImmutableContainerNodeBuilder.create()