From: Vladimir Lavor Date: Thu, 26 Jan 2017 13:13:59 +0000 (+0100) Subject: better odl <-> device communication via netconf - gbp side X-Git-Tag: release/carbon~37^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F67%2F51067%2F5;p=groupbasedpolicy.git better odl <-> device communication via netconf - gbp side * transaction is restarted after every exception (caused by collision, netconf failure, HC failure etc.) * data to remove are verified whether they are present to prevent netconf transaction exceptions Change-Id: I7243b174cb1545f78d2df897e8755fc173e3757a Signed-off-by: Vladimir Lavor --- diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java index bba5f19e4..ac6cc065a 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java @@ -191,7 +191,7 @@ public class InterfaceManager implements AutoCloseable { private ListenableFuture deleteIfaceOnVpp(ConfigCommand deleteIfaceWithoutBdCommand, DataBroker vppDataBroker, VppEndpoint vppEndpoint, InstanceIdentifier vppNodeIid) { - final boolean transactionState = GbpNetconfTransaction.delete(vppDataBroker, deleteIfaceWithoutBdCommand, + final boolean transactionState = GbpNetconfTransaction.deleteIfExists(vppDataBroker, deleteIfaceWithoutBdCommand, GbpNetconfTransaction.RETRY_COUNT); if (transactionState) { LOG.debug("Delete interface on VPP command was successful: VPP: {} Command: {}", vppNodeIid, @@ -408,7 +408,7 @@ public class InterfaceManager implements AutoCloseable { LOG.warn("Interface already not in bridge domain {} ", ifaceKey); return Futures.immediateFuture(null); } - final boolean transactionState = GbpNetconfTransaction.delete(mountPoint, + final boolean transactionState = GbpNetconfTransaction.deleteIfExists(mountPoint, VppIidFactory.getL2ForInterfaceIid(ifaceKey), GbpNetconfTransaction.RETRY_COUNT); if (transactionState) { LOG.debug("Removing bridge domain from interface {}", VppIidFactory.getInterfaceIID(ifaceKey)); @@ -484,7 +484,7 @@ public class InterfaceManager implements AutoCloseable { InstanceIdentifier l2Iid = interfaceIid.builder().augmentation(VppInterfaceAugmentation.class).child(L2.class).build(); LOG.debug("Deleting bridge domain from interface {}", interfacePath); - final boolean transactionState = GbpNetconfTransaction.delete(mountpoint, l2Iid, + final boolean transactionState = GbpNetconfTransaction.deleteIfExists(mountpoint, l2Iid, GbpNetconfTransaction.RETRY_COUNT); if (transactionState) { return vppEndpointLocationProvider.replaceLocationForEndpoint(new ExternalLocationCaseBuilder() diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransaction.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransaction.java index f0e820daa..ac4d715f6 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransaction.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransaction.java @@ -18,6 +18,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ConfigCommand; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; @@ -25,7 +26,7 @@ import org.slf4j.LoggerFactory; public class GbpNetconfTransaction { - public static final byte RETRY_COUNT = 5; + public static final byte RETRY_COUNT = 3; private static final Logger LOG = LoggerFactory.getLogger(GbpNetconfTransaction.class); /** @@ -36,7 +37,7 @@ public class GbpNetconfTransaction { * @param retryCounter number of attempts * @return true if transaction is successful, false otherwise */ - public synchronized static boolean write(final DataBroker mountpoint, final ConfigCommand command, + public static synchronized boolean write(final DataBroker mountpoint, final ConfigCommand command, byte retryCounter) { LOG.trace("Netconf WRITE transaction started. RetryCounter: {}", retryCounter); Preconditions.checkNotNull(mountpoint); @@ -45,20 +46,17 @@ public class GbpNetconfTransaction { command.execute(rwTx); final CheckedFuture futureTask = rwTx.submit(); futureTask.get(); - LOG.trace("Netconf WRITE transaction done. Retry counter: {}", retryCounter); + LOG.trace("Netconf WRITE transaction done for command {}", command); return true; - } catch (IllegalStateException e) { + } catch (Exception e) { // Retry if (retryCounter > 0) { - LOG.warn("Assuming that netconf write-transaction failed, restarting ...", e.getMessage()); + LOG.warn("Netconf WRITE transaction failed to {}. Restarting transaction ... ", e.getMessage()); return write(mountpoint, command, --retryCounter); } else { - LOG.warn("Netconf write-transaction failed. Maximal number of attempts reached", e.getMessage()); + LOG.warn("Netconf WRITE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e); return false; } - } catch (Exception e) { - LOG.warn("Exception while writing data ...", e.getMessage()); - return false; } } @@ -72,7 +70,7 @@ public class GbpNetconfTransaction { * @param generic data type. Has to be child of {@link DataObject} * @return true if transaction is successful, false otherwise */ - public synchronized static boolean write(final DataBroker mountpoint, + public static synchronized boolean write(final DataBroker mountpoint, final InstanceIdentifier iid, final T data, byte retryCounter) { @@ -83,20 +81,17 @@ public class GbpNetconfTransaction { rwTx.put(LogicalDatastoreType.CONFIGURATION, iid, data, true); final CheckedFuture futureTask = rwTx.submit(); futureTask.get(); - LOG.trace("Netconf WRITE transaction done. Retry counter: {}", retryCounter); + LOG.trace("Netconf WRITE transaction done for {}", iid); return true; - } catch (IllegalStateException e) { + } catch (Exception e) { // Retry if (retryCounter > 0) { - LOG.warn("Assuming that netconf write-transaction failed, restarting ...", e.getMessage()); + LOG.warn("Netconf WRITE transaction failed to {}. Restarting transaction ... ", e.getMessage()); return write(mountpoint, iid, data, --retryCounter); } else { - LOG.warn("Netconf write-transaction failed. Maximal number of attempts reached", e.getMessage()); + LOG.warn("Netconf WRITE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e); return false; } - } catch (Exception e) { - LOG.warn("Exception while writing data ...", e.getMessage()); - return false; } } @@ -110,7 +105,7 @@ public class GbpNetconfTransaction { * @param generic data type. Has to be child of {@link DataObject} * @return optional data object if successful, {@link Optional#absent()} if failed */ - public synchronized static Optional read(final DataBroker mountpoint, + public static synchronized Optional read(final DataBroker mountpoint, final LogicalDatastoreType datastoreType, final InstanceIdentifier iid, byte retryCounter) { @@ -122,61 +117,38 @@ public class GbpNetconfTransaction { final CheckedFuture, ReadFailedException> futureData = rTx.read(datastoreType, iid); data = futureData.get(); - LOG.trace("Netconf READ transaction done. Data present: {}, Retry counter: {}", - data.isPresent(), retryCounter); + LOG.trace("Netconf READ transaction done. Data present: {}", data.isPresent()); return data; - } catch (IllegalStateException e) { + } catch (Exception e) { // Retry if (retryCounter > 0) { - LOG.warn("Assuming that netconf read-transaction failed, restarting ...", e.getMessage()); + LOG.warn("Netconf READ transaction failed to {}. Restarting transaction ... ", e.getMessage()); rTx.close(); return read(mountpoint, datastoreType, iid, --retryCounter); } else { - LOG.warn("Netconf read-transaction failed. Maximal number of attempts reached", e.getMessage()); + LOG.warn("Netconf READ transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e); return Optional.absent(); } - } catch (Exception e) { - LOG.warn("Exception while reading data ...", e.getMessage()); - return Optional.absent(); } } /** - * Remove data from remote device using {@link ConfigCommand}. Transaction is restarted if failed. + * Remove data from remote device using {@link ConfigCommand} * * @param mountpoint to access remote device * @param command config command with data, datastore type and iid * @param retryCounter number of attempts * @return true if transaction is successful, false otherwise */ - public synchronized static boolean delete(final DataBroker mountpoint, final ConfigCommand command, + public static synchronized boolean deleteIfExists(final DataBroker mountpoint, final ConfigCommand command, byte retryCounter) { - LOG.trace("Netconf DELETE transaction started. RetryCounter: {}", retryCounter); Preconditions.checkNotNull(mountpoint); - final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction(); - try { - command.execute(rwTx); - final CheckedFuture futureTask = rwTx.submit(); - futureTask.get(); - LOG.trace("Netconf DELETE transaction done. Retry counter: {}", retryCounter); - return true; - } catch (IllegalStateException e) { - // Retry - if (retryCounter > 0) { - LOG.warn("Assuming that netconf delete-transaction failed, restarting ...", e.getMessage()); - return delete(mountpoint, command, --retryCounter); - } else { - LOG.warn("Netconf delete-transaction failed. Maximal number of attempts reached", e.getMessage()); - return false; - } - } catch (Exception e) { - LOG.warn("Exception while removing data ...", e.getMessage()); - return false; - } + InstanceIdentifier iid = VppIidFactory.getInterfaceIID(command.getInterfaceBuilder().getKey()); + return deleteIfExists(mountpoint, iid, retryCounter); } /** - * Remove data from remote device. Transaction is restarted if failed. + * Remove data from remote device. Data presence is verified before removal. Transaction is restarted if failed. * * @param mountpoint to access remote device * @param iid data identifier @@ -184,31 +156,34 @@ public class GbpNetconfTransaction { * @param generic data type. Has to be child of {@link DataObject} * @return true if transaction is successful, false otherwise */ - public synchronized static boolean delete(final DataBroker mountpoint, + public static synchronized boolean deleteIfExists(final DataBroker mountpoint, final InstanceIdentifier iid, byte retryCounter) { - LOG.trace("Netconf DELETE transaction started. RetryCounter: {}", retryCounter); + LOG.trace("Netconf DELETE transaction started. Data will be read at first. RetryCounter: {}", retryCounter); Preconditions.checkNotNull(mountpoint); + final Optional optionalObject = read(mountpoint, LogicalDatastoreType.CONFIGURATION, iid, RETRY_COUNT); + if (!optionalObject.isPresent()) { + LOG.warn("Netconf DELETE transaction aborted. Data to remove are not present or cannot be read. Iid: {}", + iid); + // Return true, this state is not considered as an error + return true; + } final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction(); try { rwTx.delete(LogicalDatastoreType.CONFIGURATION, iid); final CheckedFuture futureTask = rwTx.submit(); futureTask.get(); - LOG.trace("Netconf DELETE transaction done. Retry counter: {}", retryCounter); + LOG.trace("Netconf DELETE transaction done for {}", iid); return true; - } catch (IllegalStateException e) { + } catch (Exception e) { // Retry if (retryCounter > 0) { - LOG.warn("Assuming that netconf delete-transaction failed, restarting ...", e.getMessage()); - return delete(mountpoint, iid, --retryCounter); + LOG.warn("Netconf DELETE transaction failed to {}. Restarting transaction ... ", e.getMessage()); + return deleteIfExists(mountpoint, iid, --retryCounter); } else { - LOG.warn("Netconf delete-transaction failed. Maximal number of attempts reached", e.getMessage()); + LOG.warn("Netconf DELETE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e); return false; } - } catch (Exception e) { - LOG.warn("Exception while removing data ...", e.getMessage()); - return false; } } - -} +} \ No newline at end of file diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransactionTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransactionTest.java index 29e33ca43..7fa27d596 100644 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransactionTest.java +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransactionTest.java @@ -19,6 +19,7 @@ import static org.mockito.Mockito.when; import com.google.common.base.Optional; import com.google.common.util.concurrent.CheckedFuture; +import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; @@ -27,6 +28,10 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ConfigCommand; +import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.LoopbackCommand; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; @@ -35,6 +40,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class GbpNetconfTransactionTest { + private final String INTERFACE_KEY = "interface-key"; + private final String NODE_ID = "node-id"; private final DataBroker dataBroker = mock(DataBroker.class); private final ReadWriteTransaction rwTx = mock(ReadWriteTransaction.class); private final ReadOnlyTransaction rTx = mock(ReadOnlyTransaction.class); @@ -45,22 +52,19 @@ public class GbpNetconfTransactionTest { private final CheckedFuture future = mock(CheckedFuture.class); @SuppressWarnings("unchecked") private final CheckedFuture, ReadFailedException> futureNode = mock(CheckedFuture.class); - private final ConfigCommand command = mock(ConfigCommand.class); + @SuppressWarnings("unchecked") + private final CheckedFuture, ReadFailedException> futureInterface = mock(CheckedFuture.class); + private final ConfigCommand command = mock(LoopbackCommand.class); + private final InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setKey(new InterfaceKey(INTERFACE_KEY)); - @Test - public void writeConfigCommandExceptionTest() { + @Before + public void init() { + when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx); when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); - doThrow(new RuntimeException()).when(command).execute(rwTx); - - final boolean result = GbpNetconfTransaction.write(dataBroker, command, (byte)5); - verify(dataBroker, times(1)).newReadWriteTransaction(); - assertFalse(result); - } @Test public void writeConfigCommandReattemptTest() { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); doThrow(new IllegalStateException()).when(command).execute(rwTx); final boolean result = GbpNetconfTransaction.write(dataBroker, command, (byte)5); @@ -70,7 +74,6 @@ public class GbpNetconfTransactionTest { @Test public void writeConfigCommandTest() throws Exception { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); when(rwTx.submit()).thenReturn(future); doNothing().when(command).execute(rwTx); when(future.get()).thenReturn(null); @@ -80,19 +83,8 @@ public class GbpNetconfTransactionTest { assertTrue(result); } - @Test - public void writeDataExceptionTest() { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); - doThrow(new RuntimeException()).when(rwTx).put(LogicalDatastoreType.CONFIGURATION, nodeIid, node, true); - - final boolean result = GbpNetconfTransaction.write(dataBroker, nodeIid, node, (byte)5); - verify(dataBroker, times(1)).newReadWriteTransaction(); - assertFalse(result); - } - @Test public void writeDataReattemptTest() { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); doThrow(new IllegalStateException()).when(rwTx).put(LogicalDatastoreType.CONFIGURATION, nodeIid, node, true); final boolean result = GbpNetconfTransaction.write(dataBroker, nodeIid, node, (byte)5); @@ -102,7 +94,6 @@ public class GbpNetconfTransactionTest { @Test public void writeDataTest() throws Exception { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); when(rwTx.submit()).thenReturn(future); doNothing().when(rwTx).put(LogicalDatastoreType.CONFIGURATION, nodeIid, node, true); when(future.get()).thenReturn(null); @@ -112,20 +103,8 @@ public class GbpNetconfTransactionTest { assertTrue(result); } - @Test - public void readDataExceptionTest() { - when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx); - doThrow(new RuntimeException()).when(rTx).read(LogicalDatastoreType.CONFIGURATION, nodeIid); - - final Optional result = GbpNetconfTransaction.read(dataBroker, LogicalDatastoreType.CONFIGURATION, - nodeIid, (byte)5); - verify(dataBroker, times(1)).newReadOnlyTransaction(); - assertFalse(result.isPresent()); - } - @Test public void readDataReattemptTest() { - when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx); doThrow(new IllegalStateException()).when(rTx).read(LogicalDatastoreType.CONFIGURATION, nodeIid); final Optional result = GbpNetconfTransaction.read(dataBroker, LogicalDatastoreType.CONFIGURATION, @@ -136,10 +115,9 @@ public class GbpNetconfTransactionTest { @Test public void readDataTest() throws Exception { - when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx); when(rTx.read(LogicalDatastoreType.CONFIGURATION, nodeIid)).thenReturn(futureNode); when(futureNode.get()).thenReturn(Optional.of(new NodeBuilder() - .setKey(new NodeKey(new NodeId("node"))).build())); + .setKey(new NodeKey(new NodeId(NODE_ID))).build())); final Optional result = GbpNetconfTransaction.read(dataBroker, LogicalDatastoreType.CONFIGURATION, nodeIid, (byte)5); @@ -148,65 +126,81 @@ public class GbpNetconfTransactionTest { } @Test - public void deleteConfigCommandExceptionTest() { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); - doThrow(new RuntimeException()).when(command).execute(rwTx); + public void deleteConfigCommandMissingDataTest() throws Exception { + final InstanceIdentifier iid = VppIidFactory.getInterfaceIID(interfaceBuilder.getKey()); + when(command.getInterfaceBuilder()).thenReturn(interfaceBuilder); + when(rTx.read(LogicalDatastoreType.CONFIGURATION, iid)).thenReturn(futureInterface); + when(futureInterface.get()).thenReturn(Optional.absent()); + doThrow(new IllegalStateException()).when(command).execute(rwTx); - final boolean result = GbpNetconfTransaction.delete(dataBroker, command, (byte)5); - verify(dataBroker, times(1)).newReadWriteTransaction(); - assertFalse(result); + final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, command, (byte)5); + verify(dataBroker, times(1)).newReadOnlyTransaction(); + assertTrue(result); } @Test - public void deleteConfigCommandReattemptTest() { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); + public void deleteConfigCommandReattemptTest() throws Exception { + final InstanceIdentifier iid = VppIidFactory.getInterfaceIID(interfaceBuilder.getKey()); + when(command.getInterfaceBuilder()).thenReturn(interfaceBuilder); + when(rTx.read(LogicalDatastoreType.CONFIGURATION, iid)).thenReturn(futureInterface); + when(futureInterface.get()).thenReturn(Optional.of(new InterfaceBuilder() + .setKey(new InterfaceKey(INTERFACE_KEY)).build())); doThrow(new IllegalStateException()).when(command).execute(rwTx); - final boolean result = GbpNetconfTransaction.delete(dataBroker, command, (byte)5); + final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, command, (byte)5); verify(dataBroker, times(6)).newReadWriteTransaction(); assertFalse(result); } @Test public void deleteConfigCommandTest() throws Exception { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); + final InstanceIdentifier iid = VppIidFactory.getInterfaceIID(interfaceBuilder.getKey()); + when(command.getInterfaceBuilder()).thenReturn(interfaceBuilder); + when(rTx.read(LogicalDatastoreType.CONFIGURATION, iid)).thenReturn(futureInterface); + when(futureInterface.get()).thenReturn(Optional.of(new InterfaceBuilder() + .setKey(new InterfaceKey(INTERFACE_KEY)).build())); when(rwTx.submit()).thenReturn(future); doNothing().when(command).execute(rwTx); when(future.get()).thenReturn(null); - final boolean result = GbpNetconfTransaction.delete(dataBroker, command, (byte)5); + final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, command, (byte)5); verify(dataBroker, times(1)).newReadWriteTransaction(); assertTrue(result); } @Test - public void deleteDataExceptionTest() { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); - doThrow(new RuntimeException()).when(rwTx).delete(LogicalDatastoreType.CONFIGURATION, nodeIid); + public void deleteDataMissingDataTest() throws Exception { + when(rTx.read(LogicalDatastoreType.CONFIGURATION, nodeIid)).thenReturn(futureNode); + when(futureNode.get()).thenReturn(Optional.absent()); + doThrow(new IllegalStateException()).when(command).execute(rwTx); - final boolean result = GbpNetconfTransaction.delete(dataBroker, nodeIid, (byte)5); - verify(dataBroker, times(1)).newReadWriteTransaction(); - assertFalse(result); + final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, nodeIid, (byte)5); + verify(dataBroker, times(1)).newReadOnlyTransaction(); + assertTrue(result); } @Test - public void deleteDataReattemptTest() { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); + public void deleteDataReattemptTest() throws Exception { + when(rTx.read(LogicalDatastoreType.CONFIGURATION, nodeIid)).thenReturn(futureNode); + when(futureNode.get()).thenReturn(Optional.of(new NodeBuilder() + .setKey(new NodeKey(new NodeId(NODE_ID))).build())); doThrow(new IllegalStateException()).when(rwTx).delete(LogicalDatastoreType.CONFIGURATION, nodeIid); - final boolean result = GbpNetconfTransaction.delete(dataBroker, nodeIid, (byte)5); + final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, nodeIid, (byte)5); verify(dataBroker, times(6)).newReadWriteTransaction(); assertFalse(result); } @Test public void deleteDataTest() throws Exception { - when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx); + when(rTx.read(LogicalDatastoreType.CONFIGURATION, nodeIid)).thenReturn(futureNode); + when(futureNode.get()).thenReturn(Optional.of(new NodeBuilder() + .setKey(new NodeKey(new NodeId(NODE_ID))).build())); when(rwTx.submit()).thenReturn(future); doNothing().when(rwTx).delete(LogicalDatastoreType.CONFIGURATION, nodeIid); when(future.get()).thenReturn(null); - final boolean result = GbpNetconfTransaction.delete(dataBroker, nodeIid, (byte)5); + final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, nodeIid, (byte)5); verify(dataBroker, times(1)).newReadWriteTransaction(); assertTrue(result); }