Wipe operational state 55/12955/4
authorRobert Varga <rovarga@cisco.com>
Wed, 19 Nov 2014 17:12:07 +0000 (18:12 +0100)
committerRobert Varga <rovarga@cisco.com>
Fri, 21 Nov 2014 21:39:02 +0000 (21:39 +0000)
Clustered data store may end up persisting our data, which means that if
an instance comes up after a crash, we may have stale data. Rather than
failing to come up, lets just wipe whatever was there.

Change-Id: I3b43d9bf692f083142e44fe8b588d1a92f81e7a2
Signed-off-by: Robert Varga <rovarga@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeerTest.java
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/AbstractTopologyBuilder.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java

index 43087a58d6e7e94bcd0f56ebdd5b8ead029b3cb8..94b7cca2298fe650ed8998423522ae29106c57c9 100644 (file)
@@ -24,7 +24,6 @@ import java.util.concurrent.LinkedBlockingQueue;
 import javax.annotation.concurrent.ThreadSafe;
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -61,7 +60,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRibBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
@@ -142,19 +140,11 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
 
         LOG.debug("Instantiating RIB table {} at {}", ribId, getInstanceIdentifier());
 
-        final ReadWriteTransaction trans = this.chain.newReadWriteTransaction();
-        Optional<Rib> o;
-        try {
-            o = trans.read(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier()).get();
-        } catch (InterruptedException | ExecutionException e) {
-            throw new IllegalStateException("Failed to read topology", e);
-        }
-        Preconditions.checkState(!o.isPresent(), "Data provider conflict detected on object {}", getInstanceIdentifier());
+        final WriteTransaction trans = this.chain.newWriteOnlyTransaction();
 
         // put empty BgpRib if not exists
-        trans.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(BgpRib.class).build(), new BgpRibBuilder().build());
         trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(), new RibBuilder().setKey(new RibKey(ribId)).setId(ribId).setLocRib(
-            new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build());
+            new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
 
         for (final BgpTableType t : localTables) {
             final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
index 28a735d7d68ce3c981a2dc7452404bf911ed3c21..713278074481fd0b222d4000dc5516294b3d019f 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.protocol.bgp.rib.impl;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.any;
-
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.CheckedFuture;
@@ -28,6 +27,7 @@ import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -39,7 +39,6 @@ import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -89,7 +88,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.multiprotocol._case.MultiprotocolCapabilityBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRibId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRibBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
@@ -124,9 +122,6 @@ public class ApplicationPeerTest {
     @Mock
     DataBroker dps;
 
-    @Mock
-    ReadWriteTransaction trans;
-
     @Mock
     WriteTransaction transWrite;
 
@@ -163,6 +158,9 @@ public class ApplicationPeerTest {
         4, 0x0a, 0x0b, 0x0c, 0x0d, 1, 3, 0, 4, (byte) 0xc5, 0x14, (byte) 0xa0, (byte) 0x2a, 1, 4, 0, 4, (byte) 0xc5,
         0x14, (byte) 0xa0, 0x28, 1, 7, 0, 2, 0, 3};
 
+    private RIBActivator a1;
+    private org.opendaylight.protocol.bgp.linkstate.RIBActivator a2;
+
     @SuppressWarnings("unchecked")
     @Before
     public void setUp() throws InterruptedException, ExecutionException, ReadFailedException {
@@ -172,17 +170,13 @@ public class ApplicationPeerTest {
         localTables.add(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
         localTables.add(new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class));
         final RIBExtensionProviderContext context = new SimpleRIBExtensionProviderContext();
-        final RIBActivator a1 = new RIBActivator();
+        a1 = new RIBActivator();
         a1.startRIBExtensionProvider(context);
-        final org.opendaylight.protocol.bgp.linkstate.RIBActivator a2 = new org.opendaylight.protocol.bgp.linkstate.RIBActivator();
+        a2 = new org.opendaylight.protocol.bgp.linkstate.RIBActivator();
         a2.startRIBExtensionProvider(context);
-        Mockito.doReturn(this.trans).when(this.dps).newReadWriteTransaction();
         Mockito.doReturn(this.chain).when(this.dps).createTransactionChain(Mockito.any(RIBImpl.class));
-        Mockito.doReturn(this.trans).when(this.chain).newReadWriteTransaction();
-        Mockito.doReturn(this.future).when(this.trans).read(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(InstanceIdentifier.class));
         Mockito.doReturn(this.o).when(this.future).get();
-        Mockito.doNothing().when(this.trans).merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(BgpRib.class).build(), new BgpRibBuilder().build());
-        Mockito.doNothing().when(this.trans).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(InstanceIdentifier.class), Mockito.any(Rib.class));
+        Mockito.doNothing().when(this.transWrite).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(InstanceIdentifier.class), Mockito.any(Rib.class));
         Mockito.doAnswer(new Answer<Object>() {
 
             @Override
@@ -194,7 +188,6 @@ public class ApplicationPeerTest {
         }).when(this.transWrite).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(InstanceIdentifier.class), Mockito.any(Route.class), Mockito.eq(true));
         Mockito.doNothing().when(this.transWrite).merge(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(InstanceIdentifier.class), Mockito.any(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes.class));
         Mockito.doReturn(false).when(this.o).isPresent();
-        Mockito.doReturn(this.future).when(this.trans).submit();
         Mockito.doReturn(this.future).when(this.transWrite).submit();
         Mockito.doNothing().when(this.future).addListener(Mockito.any(Runnable.class), Mockito.any(Executor.class));
         Mockito.doReturn(this.transWrite).when(this.chain).newWriteOnlyTransaction();
@@ -219,6 +212,12 @@ public class ApplicationPeerTest {
         Mockito.doReturn(readFuture).when(readTx).read(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(InstanceIdentifier.class));
     }
 
+    @After
+    public void tearDown() {
+        a1.close();
+        a2.close();
+    }
+
     @Test
     public void testOnDataChanged() {
         final Map<InstanceIdentifier<?>, DataObject> created = new HashMap<>();
@@ -254,13 +253,13 @@ public class ApplicationPeerTest {
         Mockito.doReturn(updated).when(this.change).getUpdatedData();
         Mockito.doReturn(Collections.EMPTY_SET).when(this.change).getRemovedPaths();
         this.peer.onDataChanged(this.change);
-        assertEquals(2, this.routes.size());
+        assertEquals(3, this.routes.size());
 
         Mockito.doReturn(Collections.EMPTY_MAP).when(this.change).getCreatedData();
         Mockito.doReturn(Collections.EMPTY_MAP).when(this.change).getUpdatedData();
         Mockito.doReturn(removed).when(this.change).getRemovedPaths();
         this.peer.onDataChanged(this.change);
-        assertEquals(1, this.routes.size());
+        assertEquals(2, this.routes.size());
     }
 
     @Test
@@ -293,12 +292,12 @@ public class ApplicationPeerTest {
         ub.setNlri(new NlriBuilder().setNlri(prefs).build());
         ub.setPathAttributes(new PathAttributesBuilder().build());
         this.classic.onMessage(this.session, ub.build());
-        assertEquals(2, this.routes.size());
+        assertEquals(3, this.routes.size());
 
         //create new peer so that it gets advertized routes from RIB
         try (final BGPPeer testingPeer = new BGPPeer("testingPeer", this.r)) {
             testingPeer.onSessionUp(this.session);
-            assertEquals(2, this.routes.size());
+            assertEquals(3, this.routes.size());
             assertEquals(1, testingPeer.getBgpPeerState().getSessionEstablishedCount().intValue());
             assertEquals(1, testingPeer.getBgpPeerState().getRouteTable().size());
             assertNotNull(testingPeer.getBgpSessionState());
@@ -307,7 +306,7 @@ public class ApplicationPeerTest {
         ub.setNlri(null);
         ub.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setWithdrawnRoutes(prefs).build());
         this.classic.onMessage(this.session, ub.build());
-        assertEquals(2, this.routes.size());
+        assertEquals(3, this.routes.size());
         this.classic.onMessage(this.session, new KeepaliveBuilder().build());
         this.classic.releaseConnection();
     }
index 674cec775312813dd630fabe78df91b40f84da64..4f453d9c51a7d238ef94d876580c84d9cede4627 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.bgpcep.bgp.topology.provider;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
@@ -15,7 +14,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
 import javax.annotation.concurrent.GuardedBy;
 import org.opendaylight.bgpcep.topology.TopologyReference;
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
@@ -70,14 +68,7 @@ public abstract class AbstractTopologyBuilder<T extends Route> implements AutoCl
 
         LOG.debug("Initiating topology builder from {} at {}", locRibReference, this.topology);
 
-        final ReadWriteTransaction t = this.chain.newReadWriteTransaction();
-        final Optional<Topology> o;
-        try {
-            o = t.read(LogicalDatastoreType.OPERATIONAL, this.topology).get();
-        } catch (InterruptedException | ExecutionException e) {
-            throw new IllegalStateException("Failed to read topology " + this.topology, e);
-        }
-        Preconditions.checkState(!o.isPresent(), "Data provider conflict detected on object {}", this.topology);
+        final WriteTransaction t = this.chain.newWriteOnlyTransaction();
 
         t.put(LogicalDatastoreType.OPERATIONAL, this.topology,
                 new TopologyBuilder().setKey(tk).setServerProvided(Boolean.TRUE).setTopologyTypes(types)
index 535ba28d066166c0357d737623e32beb732754c7..eb25a305e4aed216aa9292a2b8049e8449dc248a 100644 (file)
@@ -19,7 +19,6 @@ import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopolo
 import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistration;
 import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistrator;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
@@ -35,8 +34,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.TopologyTypes1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspArgs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.topology.pcep.type.TopologyPcepBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
 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;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
@@ -67,21 +64,13 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
         this.topology = Preconditions.checkNotNull(topology);
         this.listenerFactory = Preconditions.checkNotNull(listenerFactory);
 
-
-        // Make sure the topology does not exist
-        final ReadWriteTransaction tx = broker.newReadWriteTransaction();
-        final Optional<?> c = tx.read(LogicalDatastoreType.OPERATIONAL, topology).checkedGet();
-        Preconditions.checkArgument(!c.isPresent(), "Topology %s already exists", topology);
-
-        // create empty network-topology if not exists
-        tx.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(NetworkTopology.class).build(), new NetworkTopologyBuilder().build());
         // Now create the base topology
         final TopologyKey k = InstanceIdentifier.keyOf(topology);
+        final WriteTransaction tx = broker.newWriteOnlyTransaction();
         tx.put(LogicalDatastoreType.OPERATIONAL, topology, new TopologyBuilder().setKey(k).setTopologyId(k.getTopologyId()).setTopologyTypes(
                 new TopologyTypesBuilder().addAugmentation(TopologyTypes1.class,
                         new TopologyTypes1Builder().setTopologyPcep(new TopologyPcepBuilder().build()).build()).build()).setNode(
-                                new ArrayList<Node>()).build());
-
+                                new ArrayList<Node>()).build(), true);
         tx.submit().checkedGet();
     }