Cleanup eclipse warnings
[bgpcep.git] / bgp / parser-spi / src / main / java / org / opendaylight / protocol / bgp / parser / spi / pojo / SimpleNlriRegistry.java
index 77375be044cff03a1d428cec1975af7723ddc828..e566a89bab26fe25de248119db03c8f7e7b72ad9 100644 (file)
@@ -11,32 +11,44 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Iterables;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import org.opendaylight.bgp.concepts.NextHopUtil;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
 import org.opendaylight.protocol.bgp.parser.spi.AddressFamilyRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.NextHopParserSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.NlriRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
 import org.opendaylight.protocol.bgp.parser.spi.SubsequentAddressFamilyRegistry;
 import org.opendaylight.protocol.concepts.AbstractRegistration;
 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.multiprotocol.rev130919.update.path.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 final class SimpleNlriRegistry implements NlriRegistry {
 
     private static final int RESERVED = 1;
+    private static final int NEXT_HOP_LENGHT = 1;
+    private static final String PARSER_NOT_FOUND = "Nlri parser not found for table type {}";
+    private static final Logger LOG = LoggerFactory.getLogger(SimpleNlriRegistry.class);
 
     private final ConcurrentMap<BgpTableType, NlriParser> handlers = new ConcurrentHashMap<>();
     private final ConcurrentMap<Class<? extends DataObject>, NlriSerializer> serializers = new ConcurrentHashMap<>();
+    private final ConcurrentMap<BgpTableType, NextHopParserSerializer> nextHopParsers = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Entry<Class<? extends CNextHop>, BgpTableType>, NextHopParserSerializer> nextHopSerializers = new ConcurrentHashMap<>();
     private final SubsequentAddressFamilyRegistry safiReg;
     private final AddressFamilyRegistry afiReg;
 
@@ -46,17 +58,19 @@ final class SimpleNlriRegistry implements NlriRegistry {
     }
 
     private static BgpTableType createKey(final Class<? extends AddressFamily> afi,
-            final Class<? extends SubsequentAddressFamily> safi) {
+        final Class<? extends SubsequentAddressFamily> safi) {
         Preconditions.checkNotNull(afi);
         Preconditions.checkNotNull(safi);
         return new BgpTableTypeImpl(afi, safi);
     }
 
-    synchronized AutoCloseable registerNlriSerializer(final Class<? extends DataObject> nlriClass, final NlriSerializer serializer){
+    synchronized AutoCloseable registerNlriSerializer(final Class<? extends DataObject> nlriClass, final
+        NlriSerializer serializer){
         final NlriSerializer prev = this.serializers.get(nlriClass);
         Preconditions.checkState(prev == null, "Serializer already bound to class " + prev);
 
         this.serializers.put(nlriClass, serializer);
+
         final Object lock = this;
         return new AbstractRegistration() {
             @Override
@@ -69,18 +83,40 @@ final class SimpleNlriRegistry implements NlriRegistry {
     }
 
     synchronized AutoCloseable registerNlriParser(final Class<? extends AddressFamily> afi,
-            final Class<? extends SubsequentAddressFamily> safi, final NlriParser parser) {
+        final Class<? extends SubsequentAddressFamily> safi, final NlriParser parser,
+        final NextHopParserSerializer nextHopSerializer, final Class<? extends CNextHop> cNextHopClass,
+        final Class<? extends CNextHop>... cNextHopClassList) {
         final BgpTableType key = createKey(afi, safi);
         final NlriParser prev = this.handlers.get(key);
         Preconditions.checkState(prev == null, "AFI/SAFI is already bound to parser " + prev);
 
         this.handlers.put(key, parser);
+        this.nextHopParsers.put(key,nextHopSerializer);
+
+        if (cNextHopClass != null) {
+            final Entry<Class<? extends CNextHop>, BgpTableType> nhKey = new SimpleEntry<>(cNextHopClass, key);
+            this.nextHopSerializers.put(nhKey, nextHopSerializer);
+            for (final Class<? extends CNextHop> cNextHop : cNextHopClassList) {
+                final Entry<Class<? extends CNextHop>, BgpTableType> nhKeys = new SimpleEntry<>(cNextHop, key);
+                this.nextHopSerializers.put(nhKeys, nextHopSerializer);
+            }
+        }
+
         final Object lock = this;
         return new AbstractRegistration() {
             @Override
             protected void removeRegistration() {
                 synchronized (lock) {
                     SimpleNlriRegistry.this.handlers.remove(key);
+                    SimpleNlriRegistry.this.nextHopParsers.remove(key);
+                    if (cNextHopClass != null) {
+                        final Entry<Class<? extends CNextHop>, BgpTableType> nhKey = new SimpleEntry<>(cNextHopClass, key);
+                        SimpleNlriRegistry.this.nextHopSerializers.remove(nhKey);
+                        for (final Class<? extends CNextHop> cNextHop : cNextHopClassList) {
+                            final Entry<Class<? extends CNextHop>, BgpTableType> nhKeys = new SimpleEntry<>(cNextHop, key);
+                            SimpleNlriRegistry.this.nextHopSerializers.remove(nhKeys);
+                        }
+                    }
                 }
             }
         };
@@ -105,27 +141,43 @@ final class SimpleNlriRegistry implements NlriRegistry {
     }
 
     @Override
-    public MpUnreachNlri parseMpUnreach(final ByteBuf buffer) throws BGPParsingException {
+    public MpUnreachNlri parseMpUnreach(final ByteBuf buffer, final PeerSpecificParserConstraint constraint)
+            throws BGPParsingException {
         final MpUnreachNlriBuilder builder = new MpUnreachNlriBuilder();
         builder.setAfi(getAfi(buffer));
         builder.setSafi(getSafi(buffer));
 
-        final NlriParser parser = this.handlers.get(createKey(builder.getAfi(), builder.getSafi()));
         final ByteBuf nlri = buffer.slice();
-        parser.parseNlri(nlri, builder);
+        final BgpTableType key = createKey(builder.getAfi(), builder.getSafi());
+        final NlriParser parser = this.handlers.get(key);
+        if (parser == null) {
+            LOG.warn(PARSER_NOT_FOUND, key);
+        } else {
+            parser.parseNlri(nlri, builder, constraint);
+        }
         return builder.build();
     }
 
     @Override
     public void serializeMpReach(final MpReachNlri mpReachNlri, final ByteBuf byteAggregator) {
-        byteAggregator.writeShort(this.afiReg.numberForClass(mpReachNlri.getAfi()));
-        byteAggregator.writeByte(this.safiReg.numberForClass(mpReachNlri.getSafi()));
-
-        final ByteBuf nextHopBuffer = Unpooled.buffer();
-        NextHopUtil.serializeNextHop(mpReachNlri.getCNextHop(), nextHopBuffer);
-
-        byteAggregator.writeByte(nextHopBuffer.writerIndex());
-        byteAggregator.writeBytes(nextHopBuffer);
+        final Class<? extends AddressFamily> afi = mpReachNlri.getAfi();
+        final Class<? extends SubsequentAddressFamily> safi = mpReachNlri.getSafi();
+        byteAggregator.writeShort(this.afiReg.numberForClass(afi));
+        byteAggregator.writeByte(this.safiReg.numberForClass(safi));
+
+        final CNextHop cNextHop = mpReachNlri.getCNextHop();
+        if (cNextHop != null) {
+            final Entry<Class<? extends CNextHop>, BgpTableType> key = new SimpleEntry(
+                    cNextHop.getImplementedInterface(), new BgpTableTypeImpl(afi, safi));
+            final NextHopParserSerializer nextHopSerializer = this.nextHopSerializers.get(key);
+            final ByteBuf nextHopBuffer = Unpooled.buffer();
+            nextHopSerializer.serializeNextHop(cNextHop, nextHopBuffer);
+            byteAggregator.writeByte(nextHopBuffer.writerIndex());
+            byteAggregator.writeBytes(nextHopBuffer);
+
+        } else {
+            byteAggregator.writeZero(NEXT_HOP_LENGHT);
+        }
         byteAggregator.writeZero(RESERVED);
     }
 
@@ -141,19 +193,35 @@ final class SimpleNlriRegistry implements NlriRegistry {
     }
 
     @Override
-    public MpReachNlri parseMpReach(final ByteBuf buffer) throws BGPParsingException {
+    public MpReachNlri parseMpReach(final ByteBuf buffer, final PeerSpecificParserConstraint constraint)
+            throws BGPParsingException {
         final MpReachNlriBuilder builder = new MpReachNlriBuilder();
-        builder.setAfi(getAfi(buffer));
-        builder.setSafi(getSafi(buffer));
+        final Class<? extends AddressFamily> afi = getAfi(buffer);
+        final Class<? extends SubsequentAddressFamily> safi = getSafi(buffer);
+        builder.setAfi(afi);
+        builder.setSafi(safi);
 
-        final NlriParser parser = this.handlers.get(createKey(builder.getAfi(), builder.getSafi()));
+        final BgpTableType key = createKey(builder.getAfi(), builder.getSafi());
 
         final int nextHopLength = buffer.readUnsignedByte();
-        builder.setCNextHop(NextHopUtil.parseNextHop(buffer.readSlice(nextHopLength)));
+        if (nextHopLength != 0) {
+            final NextHopParserSerializer nextHopParser = this.nextHopParsers.get(key);
+            if (nextHopParser != null) {
+                builder.setCNextHop(nextHopParser.parseNextHop(buffer.readSlice(nextHopLength)));
+            } else {
+                builder.setCNextHop(NextHopUtil.parseNextHop(buffer.readSlice(nextHopLength)));
+                LOG.warn("NexHop Parser/Serializer for AFI/SAFI ({},{}) not bound",afi,safi);
+            }
+        }
         buffer.skipBytes(RESERVED);
 
         final ByteBuf nlri = buffer.slice();
-        parser.parseNlri(nlri, builder);
+        final NlriParser parser = this.handlers.get(key);
+        if (parser == null) {
+            LOG.warn(PARSER_NOT_FOUND, key);
+        } else {
+            parser.parseNlri(nlri, builder, constraint);
+        }
         return builder.build();
     }
 }