From 24a90173653e8ae72067f9486f47e5ef0329b8f4 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 7 Apr 2014 13:56:26 +0200 Subject: [PATCH] Move uptodate into its own container This patch side-steps the need to read the entire table in order to update a single leaf (uptodate) by moving it into its own container. Change-Id: Ib9f31cd4d10e2c2808b374a215ee6f4325e95ef3 Signed-off-by: Robert Varga Signed-off-by: Dana Kutenicsova --- .../bgp/linkstate/LinkstateAdjRIBsInTest.java | 33 ++++++++++----- bgp/rib-api/src/main/yang/bgp-rib.yang | 8 ++-- .../bgp/rib/spi/AbstractAdjRIBsIn.java | 20 +++++---- .../integration/bgp/ParserToSalTest.java | 42 ++++++++++++++++--- 4 files changed, 77 insertions(+), 26 deletions(-) diff --git a/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAdjRIBsInTest.java b/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAdjRIBsInTest.java index 945d0d7033..0f0afe4c96 100644 --- a/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAdjRIBsInTest.java +++ b/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAdjRIBsInTest.java @@ -58,8 +58,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib. 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.bgp.rib.Rib; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.AttributesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier; import org.opendaylight.yangtools.yang.binding.DataObject; @@ -76,6 +79,8 @@ public class LinkstateAdjRIBsInTest { @Mock private Peer peer; + + private LinkstateAdjRIBsIn lrib; private CLinkstateDestinationBuilder dBuilder; @@ -90,7 +95,7 @@ public class LinkstateAdjRIBsInTest { public void setUp() { MockitoAnnotations.initMocks(this); TablesKey key = new TablesKey(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class); - InstanceIdentifier iid = InstanceIdentifier.builder(BgpRib.class).child(Rib.class, new RibKey(new RibId("test-rib"))).toInstance(); + final InstanceIdentifier iid = InstanceIdentifier.builder(BgpRib.class).child(Rib.class, new RibKey(new RibId("test-rib"))).toInstance(); Mockito.doAnswer(new Answer() { @Override public String answer(final InvocationOnMock invocation) throws Throwable { @@ -105,7 +110,15 @@ public class LinkstateAdjRIBsInTest { @Override public Object answer(final InvocationOnMock invocation) throws Throwable { final Object[] args = invocation.getArguments(); - return LinkstateAdjRIBsInTest.this.data.get(args[0]); + Object result = LinkstateAdjRIBsInTest.this.data.get(args[0]); + if (result == null) { + InstanceIdentifier attrId = iid.child(LocRib.class).child(Tables.class).child(Attributes.class); + if (attrId.containsWildcarded((InstanceIdentifier) args[0])) { + result = new AttributesBuilder().setUptodate(Boolean.TRUE).build(); + } + } + + return result; } }).when(this.trans).readOperationalData(Matchers.any(InstanceIdentifier.class)); @@ -150,10 +163,10 @@ public class LinkstateAdjRIBsInTest { this.lrib.addRoutes(this.trans, this.peer, this.builder.build(), pa.build()); - Mockito.verify(this.trans, Mockito.times(2)).putOperationalData(Matchers.any(InstanceIdentifier.class), + Mockito.verify(this.trans, Mockito.times(3)).putOperationalData(Matchers.any(InstanceIdentifier.class), Matchers.any(DataObject.class)); - assertEquals(2,this.data.size()); + assertEquals(3,this.data.size()); } @Test @@ -168,9 +181,9 @@ public class LinkstateAdjRIBsInTest { this.lrib.addRoutes(this.trans, this.peer, this.builder.build(), pa.build()); - Mockito.verify(this.trans, Mockito.times(2)).putOperationalData(Matchers.any(InstanceIdentifier.class), + Mockito.verify(this.trans, Mockito.times(3)).putOperationalData(Matchers.any(InstanceIdentifier.class), Matchers.any(DataObject.class)); - assertEquals(2,this.data.size()); + assertEquals(3,this.data.size()); } @Test @@ -186,9 +199,9 @@ public class LinkstateAdjRIBsInTest { this.lrib.addRoutes(this.trans, this.peer, this.builder.build(), pa.build()); - Mockito.verify(this.trans, Mockito.times(2)).putOperationalData(Matchers.any(InstanceIdentifier.class), + Mockito.verify(this.trans, Mockito.times(3)).putOperationalData(Matchers.any(InstanceIdentifier.class), Matchers.any(DataObject.class)); - assertEquals(2,this.data.size()); + assertEquals(3,this.data.size()); MpUnreachNlriBuilder builder = new MpUnreachNlriBuilder(); builder.setAfi(LinkstateAddressFamily.class); @@ -198,7 +211,7 @@ public class LinkstateAdjRIBsInTest { new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder().setCLinkstateDestination(this.destinations).build()).build()).build()); this.lrib.removeRoutes(this.trans, this.peer, builder.build()); - Mockito.verify(this.trans, Mockito.times(1)).removeOperationalData(Matchers.any(InstanceIdentifier.class)); - assertEquals(1,this.data.size()); + Mockito.verify(this.trans, Mockito.times(2)).removeOperationalData(Matchers.any(InstanceIdentifier.class)); + assertEquals(2,this.data.size()); } } diff --git a/bgp/rib-api/src/main/yang/bgp-rib.yang b/bgp/rib-api/src/main/yang/bgp-rib.yang index 7df5312e92..1b99d1c123 100644 --- a/bgp/rib-api/src/main/yang/bgp-rib.yang +++ b/bgp/rib-api/src/main/yang/bgp-rib.yang @@ -42,9 +42,11 @@ module bgp-rib { uses bgp-mp:bgp-table-type; key "afi safi"; - leaf uptodate { - type boolean; - default false; + container attributes { + leaf uptodate { + type boolean; + default false; + } } choice routes { diff --git a/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractAdjRIBsIn.java b/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractAdjRIBsIn.java index 51f1ab400b..fb9c028271 100644 --- a/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractAdjRIBsIn.java +++ b/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractAdjRIBsIn.java @@ -28,6 +28,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib. import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.AttributesBuilder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; @@ -58,7 +60,7 @@ public abstract class AbstractAdjRIBsIn implements AdjR } protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) { - return toStringHelper.add("attributes", attributes); + return toStringHelper.add("attributes", this.attributes); } } @@ -155,15 +157,19 @@ public abstract class AbstractAdjRIBsIn implements AdjR new MpReachNlriBuilder().setAfi(key.getAfi()).setSafi(key.getSafi()).build()).build()).build()).build(); trans.putOperationalData(this.basePath, - new TablesBuilder().setAfi(key.getAfi()).setSafi(key.getSafi()).setUptodate(Boolean.FALSE).build()); + new TablesBuilder().setAfi(key.getAfi()).setSafi(key.getSafi()). + setAttributes(new AttributesBuilder().setUptodate(Boolean.TRUE).build()).build()); } private void setUptodate(final DataModificationTransaction trans, final Boolean uptodate) { - final Tables t = (Tables) trans.readOperationalData(this.basePath); - Preconditions.checkState(t != null); - if (!uptodate.equals(t.isUptodate())) { - LOG.debug("Table {} switching uptodate to {}", t, uptodate); - trans.putOperationalData(this.basePath, new TablesBuilder(t).setRoutes(t.getRoutes()).setUptodate(uptodate).build()); + final InstanceIdentifier aid = this.basePath.child(Attributes.class); + final Attributes a = (Attributes) trans.readOperationalData(aid); + Preconditions.checkState(a != null); + + if (!uptodate.equals(a.isUptodate())) { + LOG.debug("Table {} switching uptodate to {}", this.basePath, uptodate); + trans.removeOperationalData(aid); + trans.putOperationalData(aid, new AttributesBuilder().setUptodate(uptodate).build()); } } diff --git a/integration-tests/src/test/java/org/opendaylight/protocol/integration/bgp/ParserToSalTest.java b/integration-tests/src/test/java/org/opendaylight/protocol/integration/bgp/ParserToSalTest.java index 87e4c2cf1b..089babb791 100644 --- a/integration-tests/src/test/java/org/opendaylight/protocol/integration/bgp/ParserToSalTest.java +++ b/integration-tests/src/test/java/org/opendaylight/protocol/integration/bgp/ParserToSalTest.java @@ -52,7 +52,13 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkstateAddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkstateSubsequentAddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType; +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.RibId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.AttributesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily; import org.opendaylight.yangtools.concepts.ListenerRegistration; @@ -71,6 +77,8 @@ import com.google.common.eventbus.EventBus; public class ParserToSalTest { private static final Logger LOG = LoggerFactory.getLogger(ParserToSalTest.class); + private static final InstanceIdentifier attrId = + InstanceIdentifier.builder(BgpRib.class).child(Rib.class).child(LocRib.class).child(Tables.class).child(Attributes.class).build(); private final String hex_messages = "/bgp_hex.txt"; @@ -138,7 +146,7 @@ public class ParserToSalTest { Mockito.doAnswer(new Answer() { @Override - public String answer(final InvocationOnMock invocation) throws Throwable { + public String answer(final InvocationOnMock invocation) { final Object[] args = invocation.getArguments(); LOG.debug("Put key {} value {}", args[0]); LOG.debug("Put value {}", args[1]); @@ -150,10 +158,32 @@ public class ParserToSalTest { Mockito.doAnswer(new Answer() { @Override - public Object answer(final InvocationOnMock invocation) throws Throwable { + public Object answer(final InvocationOnMock invocation) { final Object[] args = invocation.getArguments(); - LOG.debug("Get key {}", args[0]); - return data.get(args[0]); + final InstanceIdentifier id = (InstanceIdentifier) args[0]; + + LOG.debug("Remove key {}", id); + data.remove(id); + return null; + } + }).when(this.mockedTransaction).removeOperationalData(Matchers.any(InstanceIdentifier.class)); + + Mockito.doAnswer(new Answer() { + @Override + public Object answer(final InvocationOnMock invocation) { + final Object[] args = invocation.getArguments(); + final InstanceIdentifier id = (InstanceIdentifier) args[0]; + + LOG.debug("Get key {}", id); + Object ret = data.get(id); + if (ret != null) { + return ret; + } + + if (attrId.containsWildcarded(id)) { + return new AttributesBuilder().setUptodate(true).build(); + } + return null; } }).when(this.mockedTransaction).readOperationalData(Matchers.any(InstanceIdentifier.class)); @@ -193,7 +223,7 @@ public class ParserToSalTest { (BgpTableType) new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class), new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class))); - Mockito.verify(this.mockedTransaction, Mockito.times(81)).putOperationalData(Matchers.any(InstanceIdentifier.class), + Mockito.verify(this.mockedTransaction, Mockito.times(83)).putOperationalData(Matchers.any(InstanceIdentifier.class), Matchers.any(DataObject.class)); } @@ -202,7 +232,7 @@ public class ParserToSalTest { runTestWithTables(ImmutableList.of( (BgpTableType) new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class))); - Mockito.verify(this.mockedTransaction, Mockito.times(27)).putOperationalData(Matchers.any(InstanceIdentifier.class), + Mockito.verify(this.mockedTransaction, Mockito.times(28)).putOperationalData(Matchers.any(InstanceIdentifier.class), Matchers.any(DataObject.class)); } -- 2.36.6