BUG-3348 : fixed application peer 38/21238/17
authorLadislav Borak <lborak@cisco.com>
Fri, 29 May 2015 07:25:11 +0000 (09:25 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 8 Jun 2015 22:57:59 +0000 (22:57 +0000)
By moving ipv4routes to inet, the namespaces in BestPathState
are no longer valid. Fixed them by matching extension QName
to BestPathState.

Change-Id: I9f09e92645fafc0d722109f10e06eb5bbaf17e37
Signed-off-by: Ladislav Borak <lborak@cisco.com>
Signed-off-by: Dana Kutenicsova <dkutenic@cisco.com>
Signed-off-by: Robert Varga <rovarga@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BestPathState.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/BestPathSelectorTest.java

index fc3d2d7509c8505d8b7cc2cd9aefa2dbf49df587..fdefeeb4d3a71dbec42d859f2ced138a72c8a790 100644 (file)
@@ -11,9 +11,13 @@ import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.ImmutableList;
 import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
 import javax.annotation.concurrent.NotThreadSafe;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.AsPath;
@@ -25,6 +29,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.type
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.AListCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.ASetCase;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
@@ -33,24 +38,81 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @NotThreadSafe
 final class BestPathState {
-    private static final Collection<PathArgument> AS_PATH = ImmutableList.<PathArgument>of(new NodeIdentifier(AsPath.QNAME), new NodeIdentifier(Segments.QNAME));
-    private static final Collection<PathArgument> LOCAL_PREF = ImmutableList.<PathArgument>of(new NodeIdentifier(LocalPref.QNAME), new NodeIdentifier(QName.create(LocalPref.QNAME, "pref")));
-    private static final Collection<PathArgument> MED = ImmutableList.<PathArgument>of(new NodeIdentifier(MultiExitDisc.QNAME), new NodeIdentifier(QName.create(MultiExitDisc.QNAME, "med")));
-    private static final Collection<PathArgument> ORIGIN = ImmutableList.<PathArgument>of(new NodeIdentifier(Origin.QNAME), new NodeIdentifier(QName.create(Origin.QNAME, "value")));
+    private static final class AttributesCollection {
+        private final Collection<PathArgument> asPath;
+        private final Collection<PathArgument> locPref;
+        private final Collection<PathArgument> med;
+        private final Collection<PathArgument> orig;
+
+        AttributesCollection(final QName namespace) {
+            NodeIdentifier container = new NodeIdentifier(QName.cachedReference(QName.create(namespace, AsPath.QNAME.getLocalName())));
+            NodeIdentifier leaf = new NodeIdentifier(QName.cachedReference(QName.create(namespace, "segments")));
+            this.asPath = ImmutableList.<PathArgument>of(container, leaf);
+
+            container = new NodeIdentifier(QName.cachedReference(QName.create(namespace, LocalPref.QNAME.getLocalName())));
+            leaf = new NodeIdentifier(QName.cachedReference(QName.create(namespace, "pref")));
+            this.locPref = ImmutableList.<PathArgument>of(container, leaf);
+
+            container = new NodeIdentifier(QName.cachedReference(QName.create(namespace, MultiExitDisc.QNAME.getLocalName())));
+            leaf = new NodeIdentifier(QName.cachedReference(QName.create(namespace, "med")));
+            this.med = ImmutableList.<PathArgument>of(container, leaf);
+
+            container = new NodeIdentifier(QName.cachedReference(QName.create(namespace, Origin.QNAME.getLocalName())));
+            leaf = new NodeIdentifier(QName.cachedReference(QName.create(namespace, "value")));
+            this.orig = ImmutableList.<PathArgument>of(container, leaf);
+        }
+
+        Collection<PathArgument> getAsPath() {
+            return this.asPath;
+        }
+
+        Collection<PathArgument> getLocPref() {
+            return this.locPref;
+        }
+
+        Collection<PathArgument> getMed() {
+            return this.med;
+        }
+
+        Collection<PathArgument> getOrig() {
+            return this.orig;
+        }
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(BestPathState.class);
+    private static final Cache<QNameModule, AttributesCollection> PATH_CACHE = CacheBuilder.newBuilder().weakKeys().weakValues().build();
+
+    private static Long peerAs = 0L;
+    private static int asPathLength = 0;
 
     private final ContainerNode attributes;
+    private final AttributesCollection collection;
     private Long localPref;
     private Long multiExitDisc;
     private BgpOrigin origin;
-    private static final Long peerAs = 0L;
-    private static final int asPathLength = 0;
     private boolean resolved;
 
     BestPathState(final ContainerNode attributes) {
+        final AttributesCollection col;
+        try {
+            col = PATH_CACHE.get(attributes.getNodeType().getModule(), new Callable<AttributesCollection>() {
+                @Override
+                public AttributesCollection call() {
+                    return new AttributesCollection(attributes.getNodeType());
+                }
+            });
+        } catch (final ExecutionException e) {
+            LOG.error("Error creating namespace-specific attributes collection.", e);
+            throw new IllegalStateException("Error creating namespace-specific attributes collection.", e);
+        }
+
         this.attributes = Preconditions.checkNotNull(attributes);
+        this.collection = col;
     }
 
     private static BgpOrigin fromString(final String originStr) {
@@ -71,28 +133,28 @@ final class BestPathState {
             return;
         }
 
-        final Optional<NormalizedNode<?, ?>> maybeLocalPref = NormalizedNodes.findNode(this.attributes, LOCAL_PREF);
+        final Optional<NormalizedNode<?, ?>> maybeLocalPref = NormalizedNodes.findNode(this.attributes, this.collection.getLocPref());
         if (maybeLocalPref.isPresent()) {
             this.localPref = (Long) ((LeafNode<?>)maybeLocalPref.get()).getValue();
         } else {
             this.localPref = null;
         }
 
-        final Optional<NormalizedNode<?, ?>> maybeMultiExitDisc = NormalizedNodes.findNode(this.attributes, MED);
+        final Optional<NormalizedNode<?, ?>> maybeMultiExitDisc = NormalizedNodes.findNode(this.attributes, this.collection.getMed());
         if (maybeMultiExitDisc.isPresent()) {
             this.multiExitDisc = (Long) ((LeafNode<?>)maybeMultiExitDisc.get()).getValue();
         } else {
             this.multiExitDisc = null;
         }
 
-        final Optional<NormalizedNode<?, ?>> maybeOrigin = NormalizedNodes.findNode(this.attributes, ORIGIN);
+        final Optional<NormalizedNode<?, ?>> maybeOrigin = NormalizedNodes.findNode(this.attributes, this.collection.getOrig());
         if (maybeOrigin.isPresent()) {
             this.origin = fromString((String) ((LeafNode<?>)maybeOrigin.get()).getValue());
         } else {
             this.origin = null;
         }
 
-        final Optional<NormalizedNode<?, ?>> maybeSegments = NormalizedNodes.findNode(this.attributes, AS_PATH);
+        final Optional<NormalizedNode<?, ?>> maybeSegments = NormalizedNodes.findNode(this.attributes, this.collection.getAsPath());
         if (maybeSegments.isPresent()) {
             final UnkeyedListNode segments = (UnkeyedListNode) maybeSegments.get();
 
@@ -127,7 +189,7 @@ final class BestPathState {
 
     Long getPeerAs() {
         resolveValues();
-        return this.peerAs;
+        return peerAs;
     }
 
     int getAsPathLength() {
index a21ceec88fb989652e8089fd0d7264a4ccc4a214..44a3994b234ac5270d1e989f139c34b41200f622 100644 (file)
@@ -12,10 +12,6 @@ import static org.junit.Assert.assertNotEquals;
 
 import com.google.common.primitives.UnsignedInteger;
 import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.AsPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.LocalPref;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.MultiExitDisc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.Origin;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -31,7 +27,11 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUn
 
 public class BestPathSelectorTest {
 
-    private final QName DATA_QNAME = QName.create("data");
+    private final QName extensionQName = QName.create("urn:opendaylight:params:xml:ns:yang:bgp-inet", "2015-03-05", "attributes");
+    private final QName localPrefQName = QName.create(this.extensionQName, "local-pref");
+    private final QName multiExitDiscQName = QName.create(this.extensionQName, "multi-exit-disc");
+    private final QName originQName = QName.create(this.extensionQName, "origin");
+    private final QName asPathQName = QName.create(this.extensionQName, "as-path");
     private final UnsignedInteger ROUTER_ID = RouterIds.routerIdForAddress("127.0.0.1");
     private final UnsignedInteger ROUTER_ID2 = RouterIds.routerIdForPeerId(new PeerId("bgp://127.0.0.1"));
     private final UnsignedInteger ROUTER_ID3 = RouterIds.routerIdForPeerId(new PeerId("bgp://127.0.0.2"));
@@ -82,34 +82,34 @@ public class BestPathSelectorTest {
     }
 
     private ContainerNode createStateFromPrefMedOrigin() {
-        this.dataContBuilder = createContBuilder(this.DATA_QNAME);
+        this.dataContBuilder = createContBuilder(this.extensionQName);
         // local pref
-        this.dataContBuilder.addChild(createContBuilder(LocalPref.QNAME).addChild(createValueBuilder(123L, LocalPref.QNAME, "pref").build()).build());
+        this.dataContBuilder.addChild(createContBuilder(this.localPrefQName).addChild(createValueBuilder(123L, this.localPrefQName, "pref").build()).build());
         // multi exit disc
-        this.dataContBuilder.addChild(createContBuilder(MultiExitDisc.QNAME).addChild(createValueBuilder(1234L, MultiExitDisc.QNAME, "med").build()).build());
+        this.dataContBuilder.addChild(createContBuilder(this.multiExitDiscQName).addChild(createValueBuilder(1234L, this.multiExitDiscQName, "med").build()).build());
         // origin
-        this.dataContBuilder.addChild(createContBuilder(Origin.QNAME).addChild(createValueBuilder("igp", Origin.QNAME, "value").build()).build());
+        this.dataContBuilder.addChild(createContBuilder(this.originQName).addChild(createValueBuilder("igp", this.originQName, "value").build()).build());
         return this.dataContBuilder.build();
     }
 
     private ContainerNode createStateFromPrefMedOriginASPath() {
-        this.dataContBuilder = createContBuilder(this.DATA_QNAME);
+        this.dataContBuilder = createContBuilder(this.extensionQName);
         // local pref
-        this.dataContBuilder.addChild(createContBuilder(LocalPref.QNAME).addChild(createValueBuilder(321L, LocalPref.QNAME, "pref").build()).build());
+        this.dataContBuilder.addChild(createContBuilder(this.localPrefQName).addChild(createValueBuilder(321L, this.localPrefQName, "pref").build()).build());
         // multi exit disc
-        this.dataContBuilder.addChild(createContBuilder(MultiExitDisc.QNAME).addChild(createValueBuilder(4321L, MultiExitDisc.QNAME, "med").build()).build());
+        this.dataContBuilder.addChild(createContBuilder(this.multiExitDiscQName).addChild(createValueBuilder(4321L, this.multiExitDiscQName, "med").build()).build());
         // origin
-        this.dataContBuilder.addChild(createContBuilder(Origin.QNAME).addChild(createValueBuilder("egp", Origin.QNAME, "value").build()).build());
+        this.dataContBuilder.addChild(createContBuilder(this.originQName).addChild(createValueBuilder("egp", this.originQName, "value").build()).build());
         // as path
         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> asPathContBuilder = ImmutableContainerNodeSchemaAwareBuilder.create();
-        asPathContBuilder.withNodeIdentifier(new NodeIdentifier(AsPath.QNAME));
+        asPathContBuilder.withNodeIdentifier(new NodeIdentifier(this.asPathQName));
 
         final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> segments = ImmutableUnkeyedListNodeBuilder.create();
-        segments.withNodeIdentifier(new NodeIdentifier(AsPath.QNAME));
+        segments.withNodeIdentifier(new NodeIdentifier(this.asPathQName));
         final DataContainerNodeAttrBuilder<NodeIdentifier, UnkeyedListEntryNode> segmentBuilder = ImmutableUnkeyedListEntryNodeBuilder.create();
-        segmentBuilder.withNodeIdentifier(new NodeIdentifier(AsPath.QNAME));
+        segmentBuilder.withNodeIdentifier(new NodeIdentifier(this.asPathQName));
         final ImmutableLeafNodeBuilder<Long> segmentLeaf = new ImmutableLeafNodeBuilder<>();
-        segmentLeaf.withNodeIdentifier(new NodeIdentifier(QName.create(AsPath.QNAME, "segments"))).withValue(123454L);
+        segmentLeaf.withNodeIdentifier(new NodeIdentifier(QName.create(this.asPathQName, "segments"))).withValue(123454L);
         segmentBuilder.addChild(segmentLeaf.build());
         segments.addChild(segmentBuilder.build());