From d449631e9b99aace639985286b73357577481cab Mon Sep 17 00:00:00 2001 From: Devin Avery Date: Mon, 12 May 2014 11:52:51 -0400 Subject: [PATCH] Bug 953 - Change the BindingIndependentConnector to handle RpcInvocationStrategies consistently. Patch Set 1/2/3 *Combined the RpcInvocationStrategies into a single intelligence class that handles the varying strategies since the majority of the intelligence was overlapped. *Moved some logic out of the BindingIndependentConnector to simplify it. *Added an RpcInvocationStrategyTest to validate logic in RpcInvocationStrategy. Patch Set 4 * Removed tabs and trailing whitespace Patch Set 6 * Addressed NPE that would happen when no input was provided to a method requiring input. Change-Id: I8d6916819105c5530c9b501e1ae973cdcb769ea7 Signed-off-by: Devin Avery --- .../dom/BindingIndependentConnector.java | 216 +------------- .../connect/dom/RpcInvocationStrategy.java | 164 +++++++++++ .../dom/RpcInvocationStrategyTest.java | 267 ++++++++++++++++++ ...java => MultipleAugmentationPutsTest.java} | 4 +- 4 files changed, 434 insertions(+), 217 deletions(-) create mode 100644 opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java create mode 100644 opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java rename opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/{MultipleAugmentationPuts.java => MultipleAugmentationPutsTest.java} (98%) diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java index 2b40437d64..5bbebe6f1b 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java @@ -77,8 +77,6 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.Node; -import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; import org.slf4j.Logger; @@ -87,7 +85,6 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import com.google.common.util.concurrent.Futures; @@ -736,224 +733,13 @@ public class BindingIndependentConnector implements // } } checkState(targetMethod != null, "Rpc method not found"); - Optional> outputClass = BindingReflections.resolveRpcOutputClass(targetMethod); - Optional> inputClass = BindingReflections - .resolveRpcInputClass(targetMethod); - - RpcInvocationStrategy strategy = null; - if (outputClass.isPresent()) { - if (inputClass.isPresent()) { - strategy = new DefaultInvocationStrategy(rpc, targetMethod, outputClass.get(), inputClass - .get()); - } else { - strategy = new NoInputInvocationStrategy(rpc, targetMethod, outputClass.get()); - } - } else if (inputClass.isPresent()) { - strategy = new NoOutputInvocationStrategy(rpc, targetMethod, inputClass.get()); - } else { - strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod); - } - return strategy; + return new RpcInvocationStrategy(rpc,targetMethod, mappingService, biRpcRegistry); } }); } } - private abstract class RpcInvocationStrategy { - - protected final Method targetMethod; - protected final QName rpc; - - public RpcInvocationStrategy(final QName rpc, final Method targetMethod) { - this.targetMethod = targetMethod; - this.rpc = rpc; - } - - public abstract Future> forwardToDomBroker(DataObject input); - - public abstract RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) - throws Exception; - - public RpcResult invokeOn(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - return uncheckedInvoke(rpcService, domInput); - } - } - - private class DefaultInvocationStrategy extends RpcInvocationStrategy { - - @SuppressWarnings("rawtypes") - private final WeakReference inputClass; - - @SuppressWarnings("rawtypes") - private final WeakReference outputClass; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public DefaultInvocationStrategy(final QName rpc, final Method targetMethod, final Class outputClass, - final Class inputClass) { - super(rpc, targetMethod); - this.outputClass = new WeakReference(outputClass); - this.inputClass = new WeakReference(inputClass); - } - - @SuppressWarnings("unchecked") - @Override - public RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); - Future> futureResult = (Future>) targetMethod.invoke(rpcService, bindingInput); - if (futureResult == null) { - return Rpcs.getRpcResult(false); - } - RpcResult bindingResult = futureResult.get(); - final Object resultObj = bindingResult.getResult(); - if (resultObj instanceof DataObject) { - final CompositeNode output = mappingService.toDataDom((DataObject) resultObj); - return Rpcs.getRpcResult(true, output, Collections. emptySet()); - } - return Rpcs.getRpcResult(true); - } - - @Override - public ListenableFuture> forwardToDomBroker(final DataObject input) { - if (biRpcRegistry == null) { - return Futures.> immediateFuture(Rpcs.getRpcResult(false)); - } - - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); - - return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), - new Function, RpcResult>() { - @Override - public RpcResult apply(final RpcResult input) { - Object baResultValue = null; - if (input.getResult() != null) { - baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), - input.getResult()); - } - return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors()); - } - }); - } - } - - private class NoInputInvocationStrategy extends RpcInvocationStrategy { - - @SuppressWarnings("rawtypes") - private final WeakReference outputClass; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public NoInputInvocationStrategy(final QName rpc, final Method targetMethod, final Class outputClass) { - super(rpc, targetMethod); - this.outputClass = new WeakReference(outputClass); - } - - @SuppressWarnings("unchecked") - @Override - public RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - Future> futureResult = (Future>) targetMethod.invoke(rpcService); - if (futureResult == null) { - return Rpcs.getRpcResult(false); - } - RpcResult bindingResult = futureResult.get(); - final Object resultObj = bindingResult.getResult(); - if (resultObj instanceof DataObject) { - final CompositeNode output = mappingService.toDataDom((DataObject) resultObj); - return Rpcs.getRpcResult(true, output, Collections. emptySet()); - } - return Rpcs.getRpcResult(true); - } - - @Override - public Future> forwardToDomBroker(final DataObject input) { - if (biRpcRegistry != null) { - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); - return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), - new Function, RpcResult>() { - @Override - public RpcResult apply(final RpcResult input) { - Object baResultValue = null; - if (input.getResult() != null) { - baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), - input.getResult()); - } - return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors()); - } - }); - } else { - return Futures.> immediateFuture(Rpcs.getRpcResult(false)); - } - } - } - - private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy { - - public NoInputNoOutputInvocationStrategy(final QName rpc, final Method targetMethod) { - super(rpc, targetMethod); - } - - @Override - public RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - @SuppressWarnings("unchecked") - Future> result = (Future>) targetMethod.invoke(rpcService); - RpcResult bindingResult = result.get(); - return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors()); - } - - @Override - public Future> forwardToDomBroker(final DataObject input) { - return Futures.immediateFuture(null); - } - } - - private class NoOutputInvocationStrategy extends RpcInvocationStrategy { - - @SuppressWarnings("rawtypes") - private final WeakReference inputClass; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public NoOutputInvocationStrategy(final QName rpc, final Method targetMethod, - final Class inputClass) { - super(rpc, targetMethod); - this.inputClass = new WeakReference(inputClass); - } - - @Override - public RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); - Future> result = (Future>) targetMethod.invoke(rpcService, bindingInput); - if (result == null) { - return Rpcs.getRpcResult(false); - } - RpcResult bindingResult = result.get(); - return Rpcs.getRpcResult(true); - } - - @Override - public ListenableFuture> forwardToDomBroker(final DataObject input) { - if (biRpcRegistry == null) { - return Futures.> immediateFuture(Rpcs.getRpcResult(false)); - } - - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); - - return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), - new Function, RpcResult>() { - @Override - public RpcResult apply(final RpcResult input) { - return Rpcs. getRpcResult(input.isSuccessful(), null, input.getErrors()); - } - }); - } - } - public boolean isRpcForwarding() { return rpcForwarding; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java new file mode 100644 index 0000000000..d08b217e71 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java @@ -0,0 +1,164 @@ +/* + ** Copyright (c) 2014 Brocade Communications 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.sal.binding.impl.connect.dom; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.Future; + +import org.opendaylight.controller.sal.common.util.Rpcs; +import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; +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.common.QName; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; +import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +/* + * RPC's can have both input, output, one or the other, or neither. + * + * This class handles the permutations and provides two means of invocation: + * 1. forwardToDomBroker + * 2. + * + * Weak References to the input and output classes are used to allow these classes to + * be from another OSGi bundle/class loader which may come and go. + * + */ +public class RpcInvocationStrategy { + + private final BindingIndependentMappingService mappingService; + private final RpcProvisionRegistry biRpcRegistry; + protected final Method targetMethod; + protected final QName rpc; + + @SuppressWarnings("rawtypes") + private final WeakReference inputClass; + + @SuppressWarnings("rawtypes") + private final WeakReference outputClass; + + @SuppressWarnings({ "rawtypes" }) + public RpcInvocationStrategy(final QName rpc, + final Method targetMethod, + final BindingIndependentMappingService mappingService, + final RpcProvisionRegistry biRpcRegistry ) { + + this.targetMethod = targetMethod; + this.rpc = rpc; + + Optional> outputClassOption = BindingReflections.resolveRpcOutputClass(targetMethod); + Optional> inputClassOption = BindingReflections.resolveRpcInputClass(targetMethod); + + if ( outputClassOption != null && outputClassOption.isPresent() ) { + this.outputClass = new WeakReference(outputClassOption.get() ) ; + } else { + this.outputClass = null ; + } + if ( inputClassOption != null && inputClassOption.isPresent() ) { + this.inputClass = new WeakReference(inputClassOption.get() ) ; + } else { + this.inputClass = null ; + } + + this.mappingService = mappingService; + this.biRpcRegistry = biRpcRegistry; + } + + @SuppressWarnings({ "unchecked" }) + public ListenableFuture> forwardToDomBroker(final DataObject input) { + + if(biRpcRegistry == null) { + return Futures.> immediateFuture(Rpcs.getRpcResult(false)); + } + + CompositeNode inputXml = null; + if( input != null ) { + CompositeNode xml = mappingService.toDataDom(input); + inputXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); + } else { + inputXml = ImmutableCompositeNode.create( rpc, Collections.>emptyList() ); + } + + Function, RpcResult> transformationFunction = + new Function, RpcResult>() { + @Override + public RpcResult apply(RpcResult result) { + + Object output = null; + + if( getOutputClass() != null ) { + if (result.getResult() != null) { + output = mappingService.dataObjectFromDataDom(getOutputClass().get(), + result.getResult()); + } + } + + return Rpcs.getRpcResult(result.isSuccessful(), output, result.getErrors()); + } + }; + + return Futures.transform(biRpcRegistry.invokeRpc(rpc, inputXml), transformationFunction); + } + + @SuppressWarnings("unchecked") + private RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception { + + Future> futureResult = null; + + if( inputClass != null ){ + DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); + futureResult = (Future>) targetMethod.invoke(rpcService, bindingInput); + + } else { + futureResult = (Future>) targetMethod.invoke(rpcService); + } + + if (futureResult == null) { + return Rpcs.getRpcResult(false); + } + + RpcResult bindingResult = futureResult.get(); + + Collection errors = bindingResult.getErrors(); + if( errors == null ) { + errors = Collections.emptySet(); + } + + final Object resultObj = bindingResult.getResult(); + CompositeNode output = null; + if (resultObj instanceof DataObject) { + output = mappingService.toDataDom((DataObject)resultObj); + } + return Rpcs.getRpcResult( bindingResult.isSuccessful(), output, errors); + } + + public RpcResult invokeOn(final RpcService rpcService, final CompositeNode domInput) throws Exception { + return uncheckedInvoke(rpcService, domInput); + } + + @SuppressWarnings("rawtypes") + public WeakReference getOutputClass() { + return outputClass; + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java new file mode 100644 index 0000000000..c5aea8f2ab --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java @@ -0,0 +1,267 @@ +/* +* Copyright (c) 2014 Brocade Communications 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.sal.binding.impl.connect.dom; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.controller.sal.common.util.Rpcs; +import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +public class RpcInvocationStrategyTest { + + @Mock + private BindingIndependentMappingService mockMappingService; + @Mock + private RpcProvisionRegistry mockbiRpcRegistry; + + private RpcInvocationStrategy rpcInvocationStrategy; + private ListenableFuture> futureDataObj; + private ListenableFuture> futureCompNode; + private final RpcError rpcError = mock(RpcError.class); + private final Collection errors = new ArrayList(); + + private final CompositeNode inputInvokeOn = mock(CompositeNode.class); + private final CompositeNode outputInvokeOn = mock(CompositeNode.class); + + private final DataObject toDataDomInput = mock(DataObject.class); + private final CompositeNode toDataDomReturn = mock(CompositeNode.class); + private final CompositeNode invokeRpcResult = mock(CompositeNode.class); + + private final DataObject inputForward = mock(DataObject.class); + private final DataObject outputForward = mock(DataObject.class); + + private QName mockQName; + private URI urn; + + private final MockRpcService mockRpcService = new MockRpcService(); + + public class MockRpcService implements RpcService { + + public Future rpcnameWithInputNoOutput(DataObject input) { + return futureDataObj; + } + + public Future> rpcnameWithInputWithOutput(DataObject input) { + return futureDataObj; + } + + public Future> rpcnameNoInputWithOutput() { + return futureDataObj; + } + + public Future rpcnameNoInputNoOutput() { + return futureDataObj; + } + } + + public RpcInvocationStrategyTest() { + MockitoAnnotations.initMocks(this); + } + + @Before + public void testInit() throws Exception { + urn = new URI(new String("urn:a:valid:urn")); + } + + private void setupForForwardToDom(boolean hasOutput, boolean hasInput, int expectedErrorSize) { + + if (expectedErrorSize > 0) + errors.add(rpcError); + RpcResult result = Rpcs.getRpcResult(true, invokeRpcResult, errors); + futureCompNode = Futures.immediateFuture(result); + if( hasInput ) + { + when(mockMappingService.toDataDom(inputForward)).thenReturn(toDataDomReturn); + } + when(mockbiRpcRegistry.invokeRpc(eq(mockQName), any(CompositeNode.class))).thenReturn( + futureCompNode); + if (hasOutput) { + when( + mockMappingService.dataObjectFromDataDom(eq(rpcInvocationStrategy + .getOutputClass().get()), any(CompositeNode.class))).thenReturn( + outputForward); + } + + } + + private void validateForwardToDomBroker(ListenableFuture> forwardToDomBroker, + boolean expectedSuccess, DataObject expectedResult, int expectedErrorSize) + throws InterruptedException, ExecutionException { + assertNotNull(forwardToDomBroker); + assertEquals(expectedSuccess, forwardToDomBroker.get().isSuccessful()); + assertEquals(expectedResult, forwardToDomBroker.get().getResult()); + assertEquals(expectedErrorSize, forwardToDomBroker.get().getErrors().size()); + } + + private void setupTestMethod(String rpcName, String testMethodName, boolean hasInput) + throws NoSuchMethodException { + mockQName = new QName(urn, new Date(0L), new String("prefix"), new String(rpcName)); + java.lang.reflect.Method rpcMethod = hasInput ? MockRpcService.class.getMethod(rpcName, + DataObject.class) : MockRpcService.class.getMethod(rpcName); + rpcInvocationStrategy = new RpcInvocationStrategy(mockQName, rpcMethod, mockMappingService, + mockbiRpcRegistry); + } + + /* + * forwardToDomBroker tests + */ + @Test + public void testForwardToDomBroker_WithInputNoOutput() throws Exception { + setupTestMethod("rpcnameWithInputNoOutput", "testForwardToDomBroker_WithInputNoOutput", + true); + setupForForwardToDom(false, true, 0); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(inputForward); + + validateForwardToDomBroker(forwardToDomBroker, true, null, 0); + } + + @Test + public void testForwardToDomBroker_WithInputNoOutput_error() throws Exception { + setupTestMethod("rpcnameWithInputNoOutput", + "testForwardToDomBroker_WithInputNoOutput_error", true); + setupForForwardToDom(false, true, 1); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(inputForward); + + validateForwardToDomBroker(forwardToDomBroker, true, null, 1); + } + + @Test + public void testForwardToDomBroker_WithInputWithOutput() throws Exception { + setupTestMethod("rpcnameWithInputWithOutput", "testForwardToDomBroker_WithInputWithOutput", + true); + setupForForwardToDom(true, true, 0); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(inputForward); + validateForwardToDomBroker(forwardToDomBroker, true, outputForward, 0); + } + + @Test + public void testForwardToDomBroker_NoInputWithOutput() throws Exception { + setupTestMethod("rpcnameNoInputWithOutput", "testForwardToDomBroker_NoInputWithOutput", + false); + setupForForwardToDom(true, false, 0); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(null); + validateForwardToDomBroker(forwardToDomBroker, true, outputForward, 0); + } + + @Test + public void testForwardToDomBroker_NoInputNoOutput() throws Exception { + setupTestMethod("rpcnameNoInputNoOutput", "testForwardToDomBroker_NoInputNoOutput", false); + setupForForwardToDom(false, false, 0); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(null); + validateForwardToDomBroker(forwardToDomBroker, true, null, 0); + } + + /* + * invokeOn Tests + */ + private void setupRpcResultsWithOutput(int expectedErrorSize) { + if (expectedErrorSize > 0) + errors.add(rpcError); + RpcResult resultCompNode = Rpcs.getRpcResult(true, inputInvokeOn, errors); + futureCompNode = Futures.immediateFuture(resultCompNode); + RpcResult resultDataObj = Rpcs.getRpcResult(true, toDataDomInput, errors); + futureDataObj = Futures.immediateFuture(resultDataObj); + + when(mockMappingService.toDataDom(toDataDomInput)).thenReturn(outputInvokeOn); + } + + private void setupRpcResultsNoOutput(int expectedErrorSize) { + if (expectedErrorSize > 0) + errors.add(rpcError); + RpcResult resultCompNode = Rpcs.getRpcResult(true, inputInvokeOn, errors); + futureCompNode = Futures.immediateFuture(resultCompNode); + RpcResult resultDataObj = Rpcs.getRpcResult(true, null, errors); + futureDataObj = Futures.immediateFuture(resultDataObj); + } + + private void validateReturnedImmediateFuture( + ListenableFuture> immediateFuture, boolean expectedSuccess, + CompositeNode expectedReturn, int expectedErrorSize) throws InterruptedException, + ExecutionException { + assertNotNull(immediateFuture); + assertEquals(expectedSuccess, immediateFuture.get().isSuccessful()); + assertEquals(expectedReturn, immediateFuture.get().getResult()); + assertEquals(expectedErrorSize, immediateFuture.get().getErrors().size()); + } + + @Test + public void testInvokeOn_NoInputNoOutput() throws Exception { + setupTestMethod("rpcnameNoInputNoOutput", "testInvokeOn_NoInputNoOutput", false); + setupRpcResultsNoOutput(0); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, null, 0); + } + + @Test + public void testInvokeOn_NoInputNoOutput_errors() throws Exception { + setupTestMethod("rpcnameNoInputNoOutput", "testInvokeOn_NoInputNoOutput", false); + setupRpcResultsNoOutput(1); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, null, 1); + } + + @Test + public void testInvokeOn_WithInputNoOutput() throws Exception { + setupTestMethod("rpcnameWithInputNoOutput", "testInvokeOn_WithInputNoOutput", true); + setupRpcResultsNoOutput(0); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, null, 0); + } + + @Test + public void testInvokeOn_WithInputWithOutput() throws Exception { + setupTestMethod("rpcnameWithInputWithOutput", "testInvokeOn_WithInputWithOutput", true); + setupRpcResultsWithOutput(0); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, outputInvokeOn, 0); + } + + @Test + public void testInvokeOn_NoInputWithOutput() throws Exception { + setupTestMethod("rpcnameNoInputWithOutput", "testInvokeOn_NoInputWithOutput", false); + setupRpcResultsWithOutput(0); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, outputInvokeOn, 0); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPuts.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPutsTest.java similarity index 98% rename from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPuts.java rename to opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPutsTest.java index 6b2568aba7..02870c4ef7 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPuts.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPutsTest.java @@ -48,7 +48,7 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -public class MultipleAugmentationPuts extends AbstractDataServiceTest implements DataChangeListener { +public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implements DataChangeListener { private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id"); private static final String NODE_ID = "openflow:1"; @@ -76,7 +76,7 @@ public class MultipleAugmentationPuts extends AbstractDataServiceTest implements * * @throws Exception */ - @Test + @Test( timeout = 15000) public void testAugmentSerialization() throws Exception { baDataService.registerDataChangeListener(NODES_INSTANCE_ID_BA, this); -- 2.36.6