Fixup Augmentable and Identifiable methods changing
[bgpcep.git] / bgp / parser-spi / src / main / java / org / opendaylight / protocol / bgp / parser / spi / pojo / SimpleAttributeRegistry.java
index 485c955e0eb2c6573901a82420fe704ed5ae3444..50c6f4cc0e0774c2c0fbe75a97befdd6abc0b566 100644 (file)
@@ -7,42 +7,48 @@
  */
 package org.opendaylight.protocol.bgp.parser.spi.pojo;
 
-import com.google.common.base.Preconditions;
-import com.google.common.primitives.UnsignedBytes;
+import static java.util.Objects.requireNonNull;
 
+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;
 import java.util.concurrent.atomic.AtomicReference;
-
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
 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.update.PathAttributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.attributes.UnrecognizedAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.attributes.UnrecognizedAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.attributes.UnrecognizedAttributesKey;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 final class SimpleAttributeRegistry implements AttributeRegistry {
+
     private static final class RawAttribute {
         private final AttributeParser parser;
         private final ByteBuf buffer;
 
         public RawAttribute(final AttributeParser parser, final ByteBuf buffer) {
-            this.parser = Preconditions.checkNotNull(parser);
-            this.buffer = Preconditions.checkNotNull(buffer);
+            this.parser = requireNonNull(parser);
+            this.buffer = requireNonNull(buffer);
         }
     }
 
@@ -54,7 +60,9 @@ final class SimpleAttributeRegistry implements AttributeRegistry {
     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>>(serializers.values());
+        new AtomicReference<>(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);
@@ -64,78 +72,75 @@ final class SimpleAttributeRegistry implements AttributeRegistry {
     synchronized AutoCloseable registerAttributeSerializer(final Class<? extends DataObject> paramClass, final AttributeSerializer serializer) {
         final AbstractRegistration reg = this.handlers.registerSerializer(paramClass, serializer);
 
-        serializers.put(reg, serializer);
+        this.serializers.put(reg, serializer);
         return new AbstractRegistration() {
             @Override
             protected void removeRegistration() {
                 synchronized (SimpleAttributeRegistry.this) {
-                    serializers.remove(reg);
-                    roSerializers.set(serializers.values());
+                    SimpleAttributeRegistry.this.serializers.remove(reg);
+                    SimpleAttributeRegistry.this.roSerializers.set(SimpleAttributeRegistry.this.serializers.values());
                 }
-
                 reg.close();
             }
         };
     }
 
-    private int addAttribute(final ByteBuf buffer, final Map<Integer, RawAttribute> attributes) throws BGPDocumentedException {
-        final boolean[] flags = ByteArray.parseBits(buffer.readByte());
-        final Integer type = UnsignedBytes.toInt(buffer.readByte());
-        final int hdrlen;
-        final int len;
-        if (flags[EXTENDED_LENGTH_BIT]) {
-            len = UnsignedBytes.toInt(buffer.readByte()) * 256 + UnsignedBytes.toInt(buffer.readByte());
-            hdrlen = 4;
-        } else {
-            len = UnsignedBytes.toInt(buffer.readByte());
-            hdrlen = 3;
-        }
+    private void addAttribute(final ByteBuf buffer, final Map<Integer, RawAttribute> attributes)
+            throws BGPDocumentedException {
+        final BitArray flags = BitArray.valueOf(buffer.readByte());
+        final int type = buffer.readUnsignedByte();
+        final int len = flags.get(EXTENDED_LENGTH_BIT) ? buffer.readUnsignedShort() : buffer.readUnsignedByte();
         if (!attributes.containsKey(type)) {
             final AttributeParser parser = this.handlers.getParser(type);
             if (parser == null) {
-                if (!flags[OPTIONAL_BIT]) {
-                    throw new BGPDocumentedException("Well known attribute not recognized.", BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED);
-                }
-                if (flags[TRANSITIVE_BIT]) {
-                    // FIXME: transitive attributes need to be preserved
-                    LOG.warn("Losing unrecognized transitive attribute {}", type);
-                } else {
-                    LOG.debug("Ignoring unrecognized attribute type {}", type);
-                }
+                processUnrecognized(flags, type, buffer, len);
             } else {
-                attributes.put(type, new RawAttribute(parser, buffer.slice(buffer.readerIndex(), len)));
-                buffer.skipBytes(len);
+                attributes.put(type, new RawAttribute(parser, buffer.readSlice(len)));
             }
         } else {
             LOG.debug("Ignoring duplicate attribute type {}", type);
         }
-        return hdrlen + len;
+    }
+
+    private void processUnrecognized(final BitArray flags, final int type, final ByteBuf buffer, final int len) throws BGPDocumentedException {
+        if (!flags.get(OPTIONAL_BIT)) {
+            throw new BGPDocumentedException("Well known attribute not recognized.", BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED);
+        }
+        final UnrecognizedAttributes unrecognizedAttribute = new UnrecognizedAttributesBuilder()
+            .withKey(new UnrecognizedAttributesKey((short) type))
+            .setPartial(flags.get(PARTIAL_BIT))
+            .setTransitive(flags.get(TRANSITIVE_BIT))
+            .setType((short) type)
+            .setValue(ByteArray.readBytes(buffer, len)).build();
+        this.unrecognizedAttributes.add(unrecognizedAttribute);
+        LOG.debug("Unrecognized attribute were parsed: {}", unrecognizedAttribute);
     }
 
     @Override
-    public PathAttributes parseAttributes(final ByteBuf buffer) throws BGPDocumentedException, BGPParsingException {
-        final TreeMap<Integer, RawAttribute> attributes = new TreeMap<>();
-        while (buffer.readableBytes() != 0) {
+    public Attributes parseAttributes(final ByteBuf buffer, final PeerSpecificParserConstraint constraint)
+            throws BGPDocumentedException, BGPParsingException {
+        final Map<Integer, RawAttribute> attributes = new TreeMap<>();
+        while (buffer.isReadable()) {
             addAttribute(buffer, attributes);
         }
         /*
          * TreeMap guarantees that we will be invoking the parser in the order
          * of increasing attribute type.
          */
-        final PathAttributesBuilder builder = new PathAttributesBuilder();
+        final AttributesBuilder builder = new AttributesBuilder();
         for (final Entry<Integer, RawAttribute> e : attributes.entrySet()) {
             LOG.debug("Parsing attribute type {}", e.getKey());
 
             final RawAttribute a = e.getValue();
-            a.parser.parseAttribute(a.buffer, builder);
+            a.parser.parseAttribute(a.buffer, builder, constraint);
         }
-
+        builder.setUnrecognizedAttributes(this.unrecognizedAttributes);
         return builder.build();
     }
 
     @Override
     public void serializeAttribute(final DataObject attribute,final ByteBuf byteAggregator) {
-        for (AttributeSerializer serializer : this.roSerializers.get()) {
+        for (final AttributeSerializer serializer : this.roSerializers.get()) {
             serializer.serializeAttribute(attribute, byteAggregator);
         }
     }