Bug 2824 - Fill in unrecognized attributes 27/16827/7
authorLadislav Borak <lborak@cisco.com>
Thu, 19 Mar 2015 11:35:10 +0000 (12:35 +0100)
committerLadislav Borak <lborak@cisco.com>
Fri, 20 Mar 2015 12:05:07 +0000 (13:05 +0100)
- added support for parsing unrecognized path attributes
- added test for parsing unrecognized path attributes

Change-Id: Ibca8feb9c10a6f22ee6ebb4c6bf43e03af319849
Signed-off-by: Ladislav Borak <lborak@cisco.com>
bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/ParserTest.java
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/BGPParserTest.java
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleAttributeRegistry.java
bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/pojo/UnrecognizedAttributesTest.java [new file with mode: 0644]

index 89d9d452c9c4e2d8ec1238cd70d3e9c451ba7fc8..b8df5fb6430864fa3f79322c44deedb6b2a6aea9 100644 (file)
@@ -69,6 +69,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AsPathBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.LocalPrefBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.OriginBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.UnrecognizedAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.as.path.Segments;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
@@ -406,6 +407,7 @@ public class ParserTest {
         paBuilder.addAugmentation(
             org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.PathAttributes1.class,
             lsAttrBuilder.build());
+        paBuilder.setUnrecognizedAttributes(Collections.<UnrecognizedAttributes> emptyList());
 
         assertEquals(
             lsAttrBuilder.build().getLinkstatePathAttribute(),
@@ -576,6 +578,7 @@ public class ParserTest {
         assertEquals(paBuilder.getLocalPref(), attrs.getLocalPref());
 
         paBuilder.addAugmentation(PathAttributes1.class, lsBuilder.build());
+        paBuilder.setUnrecognizedAttributes(Collections.<UnrecognizedAttributes> emptyList());
 
         final MpReachNlri mp = attrs.getAugmentation(PathAttributes1.class).getMpReachNlri();
         assertEquals(mpBuilder.getAfi(), mp.getAfi());
index fbfef1f385e82709c28ab3ceb060bfe3518d373e..56738420491a9604cabe5b784b7d9dc588cfa990 100644 (file)
@@ -52,6 +52,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.MultiExitDiscBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.OriginBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.OriginatorIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.UnrecognizedAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.as.path.Segments;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.as.path.SegmentsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.Nlri;
@@ -237,6 +238,8 @@ public class BGPParserTest {
         paBuilder.setCommunities(comms);
         assertEquals(paBuilder.getCommunities(), attrs.getCommunities());
 
+        paBuilder.setUnrecognizedAttributes(Collections.<UnrecognizedAttributes> emptyList());
+
         builder.setPathAttributes(paBuilder.build());
 
         assertEquals(builder.build(), message);
@@ -361,7 +364,7 @@ public class BGPParserTest {
         paBuilder.addAugmentation(PathAttributes1.class, new PathAttributes1Builder().setMpReachNlri(mpBuilder.build()).build());
         assertEquals(paBuilder.getAugmentation(PathAttributes1.class).getMpReachNlri(),
             attrs.getAugmentation(PathAttributes1.class).getMpReachNlri());
-
+        paBuilder.setUnrecognizedAttributes(Collections.<UnrecognizedAttributes> emptyList());
         // check API message
 
         builder.setPathAttributes(paBuilder.build());
@@ -461,7 +464,7 @@ public class BGPParserTest {
 
         paBuilder.setAggregator(aggregator);
         assertEquals(paBuilder.getAggregator(), attrs.getAggregator());
-
+        paBuilder.setUnrecognizedAttributes(Collections.<UnrecognizedAttributes> emptyList());
         builder.setPathAttributes(paBuilder.build());
 
         assertEquals(builder.build(), message);
@@ -563,6 +566,7 @@ public class BGPParserTest {
         paBuilder.setExtendedCommunities(comms);
         assertEquals(paBuilder.getExtendedCommunities(), attrs.getExtendedCommunities());
 
+        paBuilder.setUnrecognizedAttributes(Collections.<UnrecognizedAttributes> emptyList());
         // check API message
         builder.setPathAttributes(paBuilder.build());
         assertEquals(builder.build(), message);
index 1e3f3923df82b5e2efa8f7b805c53ebefd116e15..232a1f739ade55e7ba265724e4035c2eb6195e67 100644 (file)
@@ -59,7 +59,7 @@ public class ParserTest {
         (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x1a, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x48, (byte) 0x02, (byte)0x01,
         (byte) 0x00, (byte) 0x04, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
         (byte) 0x43, (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x64,
-        (byte) 0x80, (byte) 0x63, (byte) 0x19, (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x4f, (byte) 0x66, (byte) 0x2d, (byte) 0x39, (byte) 0x6b, (byte) 0x2d, (byte) 0x30, (byte)0x33,
+        (byte) 0x00, (byte) 0x63, (byte) 0x19, (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x4f, (byte) 0x66, (byte) 0x2d, (byte) 0x39, (byte) 0x6b, (byte) 0x2d, (byte) 0x30, (byte)0x33,
         (byte) 0x04, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b
     };
 
index f6c4c669cacdce0b920ec33e877be61341ae271d..085e609bbe8646ee02243f67f41c6f1c8ace2888 100644 (file)
@@ -9,7 +9,9 @@ package org.opendaylight.protocol.bgp.parser.spi.pojo;
 
 import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.TreeMap;
@@ -23,7 +25,11 @@ import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.concepts.AbstractRegistration;
 import org.opendaylight.protocol.concepts.HandlerRegistry;
 import org.opendaylight.protocol.util.BitArray;
+import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.protocol.util.Values;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.UnrecognizedAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.UnrecognizedAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.UnrecognizedAttributesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
@@ -46,13 +52,14 @@ final class SimpleAttributeRegistry implements AttributeRegistry {
     private static final Logger LOG = LoggerFactory.getLogger(SimpleAttributeRegistry.class);
     private static final int OPTIONAL_BIT = 0;
     private static final int TRANSITIVE_BIT = 1;
-    @SuppressWarnings("unused")
     private static final int PARTIAL_BIT = 2;
     private static final int EXTENDED_LENGTH_BIT = 3;
     private final HandlerRegistry<DataContainer, AttributeParser, AttributeSerializer> handlers = new HandlerRegistry<>();
     private final Map<AbstractRegistration, AttributeSerializer> serializers = new LinkedHashMap<>();
     private final AtomicReference<Iterable<AttributeSerializer>> roSerializers =
         new AtomicReference<Iterable<AttributeSerializer>>(this.serializers.values());
+    private final List<UnrecognizedAttributes> unrecognizedAttributes = new ArrayList<>();
+
 
     AutoCloseable registerAttributeParser(final int attributeType, final AttributeParser parser) {
         Preconditions.checkArgument(attributeType >= 0 && attributeType <= Values.UNSIGNED_BYTE_MAX_VALUE);
@@ -85,12 +92,14 @@ final class SimpleAttributeRegistry implements AttributeRegistry {
                 if (!flags.get(OPTIONAL_BIT)) {
                     throw new BGPDocumentedException("Well known attribute not recognized.", BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED);
                 }
-                if (flags.get(TRANSITIVE_BIT)) {
-                    // FIXME: transitive attributes need to be preserved
-                    LOG.warn("Losing unrecognized transitive attribute {}. Some data might be missing from the output.", type);
-                } else {
-                    LOG.warn("Ignoring unrecognized attribute type {}. Some data might be missing from the output.", type);
-                }
+                final UnrecognizedAttributes unrecognizedAttribute = new UnrecognizedAttributesBuilder()
+                    .setKey(new UnrecognizedAttributesKey((short)type))
+                    .setPartial(flags.get(PARTIAL_BIT))
+                    .setTransitive(flags.get(TRANSITIVE_BIT))
+                    .setType((short)type)
+                    .setValue(ByteArray.readBytes(buffer, len)).build();
+                unrecognizedAttributes.add(unrecognizedAttribute);
+                LOG.debug("Unrecognized attribute were parsed: {}", unrecognizedAttribute);
             } else {
                 attributes.put(type, new RawAttribute(parser, buffer.readSlice(len)));
             }
@@ -116,6 +125,7 @@ final class SimpleAttributeRegistry implements AttributeRegistry {
             final RawAttribute a = e.getValue();
             a.parser.parseAttribute(a.buffer, builder);
         }
+        builder.setUnrecognizedAttributes(unrecognizedAttributes);
         return builder.build();
     }
 
diff --git a/bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/pojo/UnrecognizedAttributesTest.java b/bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/pojo/UnrecognizedAttributesTest.java
new file mode 100644 (file)
index 0000000..d013b31
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015 Cisco 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.protocol.bgp.parser.spi.pojo;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import io.netty.buffer.Unpooled;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.UnrecognizedAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.UnrecognizedAttributesKey;
+
+public class UnrecognizedAttributesTest {
+
+    private static final int UNRECOGNIZED_ATTRIBUTE_COUNT = 1;
+    private static final int FIRST_ATTRIBUTE = 0;
+    private static final short NON_EXISTENT_TYPE = 0;
+    private static final int NON_VALUE_BYTES = 3;
+
+    private static final SimpleAttributeRegistry simpleAttrReg = new SimpleAttributeRegistry();
+
+    @Rule
+    public ExpectedException expException = ExpectedException.none();
+
+    @Test
+    public void testUnrecognizedAttributesWithoutOptionalFlag() throws BGPDocumentedException, BGPParsingException {
+        expException.expect(BGPDocumentedException.class);
+        expException.expectMessage("Well known attribute not recognized.");
+        simpleAttrReg.parseAttributes(Unpooled.wrappedBuffer(new byte[] { 0x03, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05 }));
+    }
+
+    @Test
+    public void testUnrecognizedAttributes() throws BGPDocumentedException, BGPParsingException {
+        final byte[] attributeBytes = { (byte)0xe0, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05 };
+        final List<UnrecognizedAttributes> unrecogAttribs = simpleAttrReg.parseAttributes(Unpooled.wrappedBuffer(attributeBytes)).getUnrecognizedAttributes();
+        assertEquals(UNRECOGNIZED_ATTRIBUTE_COUNT, unrecogAttribs.size());
+        final UnrecognizedAttributes unrecogAttrib = unrecogAttribs.get(FIRST_ATTRIBUTE);
+        final UnrecognizedAttributesKey expectedAttribKey = new UnrecognizedAttributesKey(unrecogAttrib.getType().shortValue());
+
+        assertTrue(unrecogAttrib.isPartial());
+        assertTrue(unrecogAttrib.isTransitive());
+        assertArrayEquals(ByteArray.cutBytes(attributeBytes, NON_VALUE_BYTES), unrecogAttrib.getValue());
+        assertEquals(NON_EXISTENT_TYPE, unrecogAttrib.getType().shortValue());
+        assertEquals(expectedAttribKey, unrecogAttrib.getKey());
+    }
+}