Bug 611 - BGP Update message serialization 04/7104/29
authorDana Kutenicsova <dkutenic@cisco.com>
Mon, 16 Jun 2014 22:05:31 +0000 (00:05 +0200)
committerDana Kutenicsova <dkutenic@cisco.com>
Tue, 17 Jun 2014 07:54:34 +0000 (09:54 +0200)
- serializers use ByteBuf instead of byte[]
- added update message path attributes serialization
- AttributeSerializer expects ByteBuf as method param
- MessageSerializer uses ByteBuf as method param

Change-Id: Ic7bb94e1ab20980a90967ef0a8b00ea17d04db69
Signed-off-by: Martin Bobak <mbobak@cisco.com>
Signed-off-by: Dana Kutenicsova <dkutenic@cisco.com>
34 files changed:
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/BGPActivator.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPKeepAliveMessageParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPNotificationMessageParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPOpenMessageParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPUpdateMessageParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4AggregatorAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4PathAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AggregatorAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathSegmentParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AtomicAggregateAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ClusterIdAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ExtendedCommunitiesAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LocalPreferenceAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MultiExitDiscriminatorAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/NextHopAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginatorIdAttributeParser.java
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ComplementaryTest.java
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/OpenTest.java
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java
bgp/parser-mock/src/main/java/org/opendaylight/protocol/bgp/parser/mock/BGPMessageParserMock.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistry.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeRegistry.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeSerializer.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageRegistry.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageSerializer.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleAttributeRegistry.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleMessageRegistry.java
bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistryTest.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPMessageToByteEncoder.java

index 9bbaedf33753426c930397d9d5c966ee986e2d15..90f68664efd440321ae57c65a9075a4645283c0b 100644 (file)
@@ -46,16 +46,27 @@ import org.opendaylight.protocol.bgp.parser.spi.SubsequentAddressFamilyRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Keepalive;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Notify;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParameters;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.c.parameters.As4BytesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Aggregator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AsPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AtomicAggregate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Communities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.ExtendedCommunities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.LocalPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.MultiExitDisc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Origin;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.c.parameters.GracefulRestartCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.c.parameters.MultiprotocolCase;
 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.Ipv6AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.NextHop;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
 
 public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
+
     @Override
     protected List<AutoCloseable> startImpl(final BGPExtensionProviderContext context) {
         final List<AutoCloseable> regs = new ArrayList<>();
@@ -68,26 +79,57 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
         regs.add(context.registerSubsequentAddressFamily(UnicastSubsequentAddressFamily.class, 1));
         regs.add(context.registerSubsequentAddressFamily(MplsLabeledVpnSubsequentAddressFamily.class, 128));
 
-        final NlriRegistry nlriReg = context.getNlriRegistry();
         regs.add(context.registerNlriParser(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, new Ipv4NlriParser()));
         regs.add(context.registerNlriParser(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, new Ipv6NlriParser()));
 
         final AttributeRegistry attrReg = context.getAttributeRegistry();
-        regs.add(context.registerAttributeParser(OriginAttributeParser.TYPE, new OriginAttributeParser()));
-        regs.add(context.registerAttributeParser(AsPathAttributeParser.TYPE, new AsPathAttributeParser(context.getReferenceCache())));
-        regs.add(context.registerAttributeParser(NextHopAttributeParser.TYPE, new NextHopAttributeParser()));
-        regs.add(context.registerAttributeParser(MultiExitDiscriminatorAttributeParser.TYPE, new MultiExitDiscriminatorAttributeParser()));
-        regs.add(context.registerAttributeParser(LocalPreferenceAttributeParser.TYPE, new LocalPreferenceAttributeParser()));
-        regs.add(context.registerAttributeParser(AtomicAggregateAttributeParser.TYPE, new AtomicAggregateAttributeParser()));
-        regs.add(context.registerAttributeParser(AggregatorAttributeParser.TYPE, new AggregatorAttributeParser(context.getReferenceCache())));
-        regs.add(context.registerAttributeParser(CommunitiesAttributeParser.TYPE,
-                new CommunitiesAttributeParser(context.getReferenceCache())));
-        regs.add(context.registerAttributeParser(OriginatorIdAttributeParser.TYPE, new OriginatorIdAttributeParser()));
-        regs.add(context.registerAttributeParser(ClusterIdAttributeParser.TYPE, new ClusterIdAttributeParser()));
+        final NlriRegistry nlriReg = context.getNlriRegistry();
+
+        final OriginAttributeParser originAttributeParser = new OriginAttributeParser();
+        regs.add(context.registerAttributeSerializer(Origin.class, originAttributeParser));
+        regs.add(context.registerAttributeParser(OriginAttributeParser.TYPE, originAttributeParser));
+
+        final AsPathAttributeParser asPathAttributeParser = new AsPathAttributeParser(context.getReferenceCache());
+        regs.add(context.registerAttributeSerializer(AsPath.class, asPathAttributeParser));
+        regs.add(context.registerAttributeParser(AsPathAttributeParser.TYPE, asPathAttributeParser));
+
+        final NextHopAttributeParser nextHopAttributeParser = new NextHopAttributeParser();
+        regs.add(context.registerAttributeSerializer(NextHop.class, nextHopAttributeParser));
+        regs.add(context.registerAttributeParser(NextHopAttributeParser.TYPE, nextHopAttributeParser));
+
+        final MultiExitDiscriminatorAttributeParser multiExitDiscriminatorAttributeParser = new MultiExitDiscriminatorAttributeParser();
+        regs.add(context.registerAttributeSerializer(MultiExitDisc.class, multiExitDiscriminatorAttributeParser));
+        regs.add(context.registerAttributeParser(MultiExitDiscriminatorAttributeParser.TYPE, multiExitDiscriminatorAttributeParser));
+
+        final LocalPreferenceAttributeParser localPreferenceAttributeParser = new LocalPreferenceAttributeParser();
+        regs.add(context.registerAttributeSerializer(LocalPref.class, localPreferenceAttributeParser));
+        regs.add(context.registerAttributeParser(LocalPreferenceAttributeParser.TYPE, localPreferenceAttributeParser));
+
+        final AtomicAggregateAttributeParser atomicAggregateAttributeParser = new AtomicAggregateAttributeParser();
+        regs.add(context.registerAttributeSerializer(AtomicAggregate.class, atomicAggregateAttributeParser));
+        regs.add(context.registerAttributeParser(AtomicAggregateAttributeParser.TYPE, atomicAggregateAttributeParser));
+
+        final AggregatorAttributeParser as4AggregatorAttributeParser = new AggregatorAttributeParser(context.getReferenceCache());
+        regs.add(context.registerAttributeSerializer(Aggregator.class, as4AggregatorAttributeParser));
+        regs.add(context.registerAttributeParser(AggregatorAttributeParser.TYPE, as4AggregatorAttributeParser));
+
+        final CommunitiesAttributeParser communitiesAttributeParser = new CommunitiesAttributeParser(context.getReferenceCache());
+        regs.add(context.registerAttributeSerializer(Communities.class, communitiesAttributeParser));
+        regs.add(context.registerAttributeParser(CommunitiesAttributeParser.TYPE, communitiesAttributeParser));
+
+        final OriginatorIdAttributeParser originatorIdAttributeParser = new OriginatorIdAttributeParser();
+        regs.add(context.registerAttributeParser(OriginatorIdAttributeParser.TYPE, originatorIdAttributeParser));
+
+        final ClusterIdAttributeParser clusterIdAttributeParser = new ClusterIdAttributeParser();
+        regs.add(context.registerAttributeParser(ClusterIdAttributeParser.TYPE, clusterIdAttributeParser));
+
         regs.add(context.registerAttributeParser(MPReachAttributeParser.TYPE, new MPReachAttributeParser(nlriReg)));
         regs.add(context.registerAttributeParser(MPUnreachAttributeParser.TYPE, new MPUnreachAttributeParser(nlriReg)));
-        regs.add(context.registerAttributeParser(ExtendedCommunitiesAttributeParser.TYPE,
-                new ExtendedCommunitiesAttributeParser(context.getReferenceCache())));
+
+        final ExtendedCommunitiesAttributeParser extendedCommunitiesAttributeParser = new ExtendedCommunitiesAttributeParser(context.getReferenceCache());
+        regs.add(context.registerAttributeSerializer(ExtendedCommunities.class, extendedCommunitiesAttributeParser));
+        regs.add(context.registerAttributeParser(ExtendedCommunitiesAttributeParser.TYPE, extendedCommunitiesAttributeParser));
+
         regs.add(context.registerAttributeParser(AS4AggregatorAttributeParser.TYPE, new AS4AggregatorAttributeParser()));
         regs.add(context.registerAttributeParser(AS4PathAttributeParser.TYPE, new AS4PathAttributeParser()));
 
@@ -115,7 +157,7 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
 
         final BGPUpdateMessageParser ump = new BGPUpdateMessageParser(attrReg);
         regs.add(context.registerMessageParser(BGPUpdateMessageParser.TYPE, ump));
-        // Serialization of Update message is not supported
+        regs.add(context.registerMessageSerializer(Update.class, ump));
 
         final BGPNotificationMessageParser nmp = new BGPNotificationMessageParser();
         regs.add(context.registerMessageParser(BGPNotificationMessageParser.TYPE, nmp));
index e841ed6213274bee0bf658075ccff897112d33e1..93d27ad953433f506afda4187803443648bf529b 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.protocol.bgp.parser.impl.message;
 import com.google.common.base.Preconditions;
 
 import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
@@ -21,21 +22,20 @@ import org.opendaylight.yangtools.yang.binding.Notification;
 
 public class BGPKeepAliveMessageParser implements MessageParser, MessageSerializer {
     public static final int TYPE = 4;
-
-    private final Keepalive msg = new KeepaliveBuilder().build();
-    private final byte[] bytes = MessageUtil.formatMessage(TYPE, new byte[0]);
+    private static final ByteBuf bytes = Unpooled.copiedBuffer(MessageUtil.formatMessage(TYPE, new byte[0]));
+    private static final Keepalive msg = new KeepaliveBuilder().build();
 
     @Override
     public Keepalive parseMessageBody(final ByteBuf body, final int messageLength) throws BGPDocumentedException {
-        if (body.readableBytes() != 0) {
+        if (body.isReadable()) {
             throw BGPDocumentedException.badMessageLength("Message length field not within valid range.", messageLength);
         }
         return this.msg;
     }
 
     @Override
-    public byte[] serializeMessage(final Notification message) {
+    public void serializeMessage(final Notification message, ByteBuf bytes) {
         Preconditions.checkArgument(message instanceof Keepalive);
-        return this.bytes;
+        bytes.writeBytes(this.bytes);
     }
 }
index d41d6113942514f1a3a7e5e630f61fbef225d686..ab9543c8ace9206ca5df5e167c1c8269fcacb0ed 100644 (file)
@@ -8,11 +8,9 @@
 package org.opendaylight.protocol.bgp.parser.impl.message;
 
 import com.google.common.primitives.UnsignedBytes;
-
 import io.netty.buffer.ByteBuf;
-
+import io.netty.buffer.ByteBufUtil;
 import java.util.Arrays;
-
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
@@ -29,6 +27,7 @@ import org.slf4j.LoggerFactory;
  * Parser for BGPNotification message.
  */
 public final class BGPNotificationMessageParser implements MessageParser, MessageSerializer {
+
     public static final int TYPE = 3;
 
     private static final Logger LOG = LoggerFactory.getLogger(BGPNotificationMessageParser.class);
@@ -42,7 +41,7 @@ public final class BGPNotificationMessageParser implements MessageParser, Messag
      * @return BGP Notification message converted to byte array
      */
     @Override
-    public byte[] serializeMessage(final Notification msg) {
+    public void serializeMessage(final Notification msg, ByteBuf bytes) {
         if (msg == null) {
             throw new IllegalArgumentException("BGP Notification message cannot be null");
         }
@@ -60,9 +59,8 @@ public final class BGPNotificationMessageParser implements MessageParser, Messag
             System.arraycopy(ntf.getData(), 0, msgBody, ERROR_SIZE, ntf.getData().length);
         }
 
-        final byte[] ret = MessageUtil.formatMessage(TYPE, msgBody);
-        LOG.trace("Notification message serialized to: {}", Arrays.toString(ret));
-        return ret;
+        bytes.writeBytes(MessageUtil.formatMessage(TYPE, msgBody));
+        LOG.trace("Notification message serialized to: {}", ByteBufUtil.hexDump(bytes));
     }
 
     /**
index 9125e93cc2d51a493114836527f35e68af253058..2e51c13bd3e08336798e722a7a103d6174fd26d3 100644 (file)
@@ -11,14 +11,12 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.primitives.UnsignedBytes;
-
 import io.netty.buffer.ByteBuf;
-
+import io.netty.buffer.ByteBufUtil;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
@@ -42,6 +40,7 @@ import org.slf4j.LoggerFactory;
  * Parser for BGP Open message.
  */
 public final class BGPOpenMessageParser implements MessageParser, MessageSerializer {
+
     public static final int TYPE = 1;
 
     private static final Logger LOG = LoggerFactory.getLogger(BGPOpenMessageParser.class);
@@ -71,7 +70,7 @@ public final class BGPOpenMessageParser implements MessageParser, MessageSeriali
      * @return BGP Open message converted to byte array
      */
     @Override
-    public byte[] serializeMessage(final Notification msg) {
+    public void serializeMessage(final Notification msg, ByteBuf bytes) {
         if (msg == null) {
             throw new IllegalArgumentException("BGPOpen message cannot be null");
         }
@@ -121,9 +120,8 @@ public final class BGPOpenMessageParser implements MessageParser, MessageSeriali
                 index += entry.getValue();
             }
         }
-        final byte[] ret = MessageUtil.formatMessage(TYPE, msgBody);
-        LOG.trace("Open message serialized to: {}", Arrays.toString(ret));
-        return ret;
+        bytes.writeBytes(MessageUtil.formatMessage(TYPE, msgBody));
+        LOG.trace("Open message serialized to: {}", ByteBufUtil.hexDump(bytes));
     }
 
     /**
index 5599a66ffb6d7b216568b74fbd97f90ba1c3b31b..94209f23538f8469186b579f98d00946e1609353 100644 (file)
@@ -11,6 +11,8 @@ package org.opendaylight.protocol.bgp.parser.impl.message;
 import com.google.common.base.Preconditions;
 
 import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
 
 import java.util.Arrays;
 import java.util.List;
@@ -20,6 +22,8 @@ import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
+import org.opendaylight.protocol.bgp.parser.spi.MessageSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
 import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
@@ -28,6 +32,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.update.NlriBuilder;
 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.WithdrawnRoutesBuilder;
+import org.opendaylight.yangtools.yang.binding.Notification;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,9 +40,8 @@ import org.slf4j.LoggerFactory;
  * LENGTH fields, that denote the length of the fields with variable length, have fixed SIZE.
  *
  * @see <a href="http://tools.ietf.org/html/rfc4271#section-4.3">BGP-4 Update Message Format</a>
- *
  */
-public class BGPUpdateMessageParser implements MessageParser {
+public class BGPUpdateMessageParser implements MessageParser, MessageSerializer {
     public static final int TYPE = 2;
 
     private static final Logger LOG = LoggerFactory.getLogger(BGPUpdateMessageParser.class);
@@ -46,7 +50,6 @@ public class BGPUpdateMessageParser implements MessageParser {
      * Size of the withdrawn_routes_length field, in bytes.
      */
     public static final int WITHDRAWN_ROUTES_LENGTH_SIZE = 2;
-
     /**
      * Size of the total_path_attr_length field, in bytes.
      */
@@ -97,4 +100,23 @@ public class BGPUpdateMessageParser implements MessageParser {
         LOG.debug("BGP Update message was parsed {}.", msg);
         return msg;
     }
+
+    @Override
+    public void serializeMessage(Notification message,ByteBuf bytes) {
+        if (message == null) {
+            throw new IllegalArgumentException("BGPUpdate message cannot be null");
+        }
+        LOG.trace("Started serializing update message: {}", message);
+        final Update update = (Update) message;
+
+        ByteBuf messageBody = Unpooled.buffer();
+
+        if (update.getPathAttributes() != null) {
+            this.reg.serializeAttribute(update.getPathAttributes(), messageBody);
+        }
+
+        LOG.trace("Update message serialized to {}", ByteBufUtil.hexDump(messageBody));
+        //FIXME: switch to ByteBuf
+        bytes.writeBytes(MessageUtil.formatMessage(TYPE,ByteArray.getAllBytes(messageBody)));
+    }
 }
index d188e0843f031f6784b82583eae3c2f146404402..63f128eed86d530f509fcc40a3e5fa1a7dc0e95b 100644 (file)
@@ -13,10 +13,11 @@ import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
 
 public final class AS4AggregatorAttributeParser implements AttributeParser {
+
     public static final int TYPE = 17;
 
     @Override
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) {
         // AS4 Aggregator is ignored
     }
-}
\ No newline at end of file
+}
index 86525b583c01ff8fa136fe0eb1b17b3b7f3e7652..421fd4df10488b3edfd1dae689f911aab616ade7 100644 (file)
@@ -13,10 +13,11 @@ import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
 
 public final class AS4PathAttributeParser implements AttributeParser {
+
     public static final int TYPE = 18;
 
     @Override
     public void parseAttribute(final ByteBuf bytes, final PathAttributesBuilder builder) {
         // AS4 Path is ignored
     }
-}
\ No newline at end of file
+}
index 60f964bef0b27b72ff66f3c609c067f6a3703ee0..d02ef7d2e0180a63920fc9b00ede0b922b9eef3e 100644 (file)
@@ -12,15 +12,20 @@ import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
 
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.protocol.util.ReferenceCache;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Aggregator;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AggregatorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class AggregatorAttributeParser implements AttributeParser, AttributeSerializer {
 
-public final class AggregatorAttributeParser implements AttributeParser {
     public static final int TYPE = 7;
 
     private final ReferenceCache refCache;
@@ -33,7 +38,7 @@ public final class AggregatorAttributeParser implements AttributeParser {
      * Parse AGGREGATOR from bytes
      *
      * @param buffer byte buffer to be parsed
-     * @return BGP Aggregator
+     * @return {@link Aggregator} BGP Aggregator
      */
     @Override
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) {
@@ -41,4 +46,16 @@ public final class AggregatorAttributeParser implements AttributeParser {
         final Ipv4Address address = Ipv4Util.addressForBytes(ByteArray.readAllBytes(buffer));
         builder.setAggregator(new AggregatorBuilder().setAsNumber(asNumber).setNetworkAddress(address).build());
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        Aggregator aggregator = pathAttributes.getAggregator();
+        if (aggregator == null) {
+            return;
+        }
+        Preconditions.checkArgument(aggregator.getAsNumber() != null, "Missing AS number that formed the aggregate route (encoded as 2 octets).");
+        byteAggregator.writeInt(aggregator.getAsNumber().getValue().shortValue());
+        byteAggregator.writeBytes(Ipv4Util.bytesForAddress(aggregator.getNetworkAddress()));
+    }
+}
index c8890b462845dc6bb002e370443f0e0c6d2d8537..02831bef795ec5373142ffcd514e15dfb21e0f56 100644 (file)
@@ -20,22 +20,33 @@ import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.AsPathSegmentParser.SegmentType;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.util.ReferenceCache;
 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.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AsPath;
 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.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.PathAttributesBuilder;
+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.AListCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.ASetCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.ASetCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.a.list._case.AListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.a.list._case.a.list.AsSequence;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.a.set._case.ASetBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public final class AsPathAttributeParser implements AttributeParser, AttributeSerializer {
 
-public final class AsPathAttributeParser implements AttributeParser {
     public static final int TYPE = 2;
+
     private final ReferenceCache refCache;
+    private static final Logger LOG = LoggerFactory.getLogger(AsPathAttributeParser.class);
 
     public AsPathAttributeParser(final ReferenceCache refCache) {
         this.refCache = Preconditions.checkNotNull(refCache);
@@ -44,13 +55,12 @@ public final class AsPathAttributeParser implements AttributeParser {
     /**
      * Parses AS_PATH from bytes.
      *
-     * @param bytes byte array to be parsed
+     * @param buffer bytes to be parsed
      * @return new ASPath object
      * @throws BGPDocumentedException if there is no AS_SEQUENCE present (mandatory)
      * @throws BGPParsingException
      */
-    private static AsPath parseAsPath(final ReferenceCache refCache, final ByteBuf buffer) throws BGPDocumentedException,
-            BGPParsingException {
+    private static AsPath parseAsPath(final ReferenceCache refCache, final ByteBuf buffer) throws BGPDocumentedException, BGPParsingException {
         final List<Segments> ases = Lists.newArrayList();
         boolean isSequence = false;
         while (buffer.isReadable()) {
@@ -83,8 +93,27 @@ public final class AsPathAttributeParser implements AttributeParser {
     }
 
     @Override
-    public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) throws BGPDocumentedException,
-            BGPParsingException {
+    public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) throws BGPDocumentedException, BGPParsingException {
         builder.setAsPath(parseAsPath(this.refCache, buffer));
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        if (pathAttributes.getAsPath() == null) {
+            return;
+        }
+        AsPath asPath = pathAttributes.getAsPath();
+        for (Segments segments : asPath.getSegments()) {
+            if (segments.getCSegment() instanceof AListCase) {
+                AListCase listCase = (AListCase) segments.getCSegment();
+                AsPathSegmentParser.serializeAsSequence(listCase, byteAggregator);
+            } else if (segments.getCSegment() instanceof ASetCase) {
+                ASetCase set = (ASetCase) segments.getCSegment();
+                AsPathSegmentParser.serializeAsSet(set, byteAggregator);
+            } else {
+                LOG.warn("CSegment class is neither AListCase nor ASetCase.");
+            }
+        }
+    }
+}
index b8b6f55c29ed3d3eb71d8d94a4217c1e927b32ca..289135a6684bcf0260cea6130429d6d2d13019eb 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.protocol.bgp.parser.impl.message.update;
 
+import static org.opendaylight.protocol.bgp.parser.impl.message.update.AsPathSegmentParser.SegmentType.AS_SEQUENCE;
+import static org.opendaylight.protocol.bgp.parser.impl.message.update.AsPathSegmentParser.SegmentType.AS_SET;
 import io.netty.buffer.ByteBuf;
 
 import java.util.ArrayList;
@@ -15,22 +17,20 @@ import java.util.List;
 
 import org.opendaylight.protocol.util.ReferenceCache;
 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.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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.a.list._case.AList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.a.list._case.a.list.AsSequence;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.a.list._case.a.list.AsSequenceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.as.path.segment.c.segment.a.set._case.ASet;
 
 /**
- *
  * Representation of one AS Path Segment. It is, in fact, a TLV, but the length field is representing the count of AS
  * Numbers in the collection (in its value). If the segment is of type AS_SEQUENCE, the collection is a List, if AS_SET,
  * the collection is a Set.
- *
  */
 public final class AsPathSegmentParser {
 
-    public static final int TYPE_LENGTH = 1;
-
-    public static final int LENGTH_SIZE = 1;
-
     public static final int AS_NUMBER_LENGTH = 4;
 
     /**
@@ -44,12 +44,23 @@ public final class AsPathSegmentParser {
 
     }
 
+    static int serializeType(final SegmentType type) {
+        switch (type) {
+        case AS_SET:
+            return 1;
+        case AS_SEQUENCE:
+            return 2;
+        default:
+            return 0;
+        }
+    }
+
     static SegmentType parseType(final int type) {
         switch (type) {
         case 1:
-            return SegmentType.AS_SET;
+            return AS_SET;
         case 2:
-            return SegmentType.AS_SEQUENCE;
+            return AS_SEQUENCE;
         default:
             return null;
         }
@@ -58,8 +69,8 @@ public final class AsPathSegmentParser {
     static List<AsSequence> parseAsSequence(final ReferenceCache refCache, final int count, final ByteBuf buffer) {
         final List<AsSequence> coll = new ArrayList<>();
         for (int i = 0; i < count; i++) {
-            coll.add(refCache.getSharedReference(new AsSequenceBuilder().setAs(
-                    refCache.getSharedReference(new AsNumber(buffer.readUnsignedInt()))).build()));
+            coll.add(
+                    refCache.getSharedReference(new AsSequenceBuilder().setAs(refCache.getSharedReference(new AsNumber(buffer.readUnsignedInt()))).build()));
         }
         return coll;
     }
@@ -67,8 +78,33 @@ public final class AsPathSegmentParser {
     static List<AsNumber> parseAsSet(final ReferenceCache refCache, final int count, final ByteBuf buffer) {
         final List<AsNumber> coll = new ArrayList<>();
         for (int i = 0; i < count; i++) {
-            coll.add(refCache.getSharedReference(new AsNumber(buffer.readUnsignedInt())));
+            coll.add(refCache.getSharedReference(
+                    new AsNumber(buffer.readUnsignedInt())));
         }
         return coll;
     }
+
+    static void serializeAsSet(ASetCase aSetCase, ByteBuf byteAggregator) {
+        ASet aset = aSetCase.getASet();
+        if (aset == null || aset.getAsSet() == null) {
+            return;
+        }
+        byteAggregator.writeByte(serializeType(AS_SET));
+        byteAggregator.writeByte(aset.getAsSet().size());
+        for (AsNumber asNumber : aset.getAsSet()) {
+            byteAggregator.writeShort(asNumber.getValue().shortValue());
+        }
+    }
+
+    static void serializeAsSequence(AListCase aListCase, ByteBuf byteAggregator) {
+        AList alist = aListCase.getAList();
+        if (alist == null || alist.getAsSequence() == null) {
+            return;
+        }
+        byteAggregator.writeByte(serializeType(AS_SEQUENCE));
+        byteAggregator.writeByte(alist.getAsSequence().size());
+        for (AsSequence value : alist.getAsSequence()) {
+            byteAggregator.writeShort(value.getAs().getValue().shortValue());
+        }
+    }
 }
index 5b2d4ccab028b193e20867fc5a0df7642415ee90..520a39bec08abc0896a264264794fff00f731e99 100644 (file)
@@ -10,14 +10,23 @@ package org.opendaylight.protocol.bgp.parser.impl.message.update;
 import io.netty.buffer.ByteBuf;
 
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AtomicAggregateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class AtomicAggregateAttributeParser implements AttributeParser,AttributeSerializer {
 
-public final class AtomicAggregateAttributeParser implements AttributeParser {
     public static final int TYPE = 6;
 
     @Override
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) {
         builder.setAtomicAggregate(new AtomicAggregateBuilder().build());
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        // FIXME: add attribute type/length, does not contain any value by definition
+        return;
+    }
+}
index e1d3cf5c4c3a19ee68a4ac451b63aa20f18c4a70..99c0f5834d69fa662794cfcb44e54c37d0618e06 100644 (file)
@@ -14,12 +14,15 @@ import io.netty.buffer.ByteBuf;
 import java.util.List;
 
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.util.ByteArray;
 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.types.rev130919.ClusterIdentifier;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class ClusterIdAttributeParser implements AttributeParser, AttributeSerializer {
 
-public final class ClusterIdAttributeParser implements AttributeParser {
     public static final int TYPE = 10;
 
     private static final int CLUSTER_LENGTH = 4;
@@ -32,4 +35,9 @@ public final class ClusterIdAttributeParser implements AttributeParser {
         }
         builder.setClusterId(list);
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        //TODO implement this
+    }
+}
index 3180b2dc2fdc93e0c458b9ef90584e09b8c43033..fd0347339850156ba6659073c4c74d2ef2f6b3a2 100644 (file)
@@ -16,11 +16,16 @@ import java.util.List;
 
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.util.ReferenceCache;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Communities;
 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.types.rev130919.Community;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class CommunitiesAttributeParser implements AttributeParser, AttributeSerializer {
 
-public final class CommunitiesAttributeParser implements AttributeParser {
     public static final int TYPE = 8;
 
     private final ReferenceCache refCache;
@@ -37,7 +42,18 @@ public final class CommunitiesAttributeParser implements AttributeParser {
                     CommunitiesParser.COMMUNITY_LENGTH)));
             buffer.skipBytes(CommunitiesParser.COMMUNITY_LENGTH);
         }
-
         builder.setCommunities(set);
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        List<Communities> communities = pathAttributes.getCommunities();
+        if (communities == null) {
+            return;
+        }
+        for (Community community : communities) {
+            byteAggregator.writeInt(community.getAsNumber().getValue().intValue());
+        }
+    }
+}
index c68a6e5bc8a79f8d18fa6d0d57ca46a59a39e8cc..267d51ea7c026a0ca765abee8422d67d0651410b 100644 (file)
@@ -16,11 +16,21 @@ import java.util.List;
 
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
+import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.util.ReferenceCache;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.ExtendedCommunities;
 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.types.rev130919.extended.community.extended.community.AsSpecificExtendedCommunityCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.Inet4SpecificExtendedCommunityCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.OpaqueExtendedCommunityCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.RouteOriginExtendedCommunityCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.extended.community.RouteTargetExtendedCommunityCase;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class ExtendedCommunitiesAttributeParser implements AttributeParser,AttributeSerializer {
 
-public final class ExtendedCommunitiesAttributeParser implements AttributeParser {
     public static final int TYPE = 16;
 
     private final ReferenceCache refCache;
@@ -33,11 +43,69 @@ public final class ExtendedCommunitiesAttributeParser implements AttributeParser
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) throws BGPDocumentedException {
         final List<ExtendedCommunities> set = Lists.newArrayList();
         while (buffer.isReadable()) {
-            final ExtendedCommunities comm = CommunitiesParser.parseExtendedCommunity(this.refCache, buffer.slice(buffer.readerIndex(),
-                    CommunitiesParser.EXTENDED_COMMUNITY_LENGTH));
+            final ExtendedCommunities comm = CommunitiesParser.parseExtendedCommunity(this.refCache, buffer.slice(buffer.readerIndex(), CommunitiesParser.EXTENDED_COMMUNITY_LENGTH));
             buffer.skipBytes(CommunitiesParser.EXTENDED_COMMUNITY_LENGTH);
             set.add(comm);
         }
         builder.setExtendedCommunities(set);
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        List<ExtendedCommunities> communitiesList = pathAttributes.getExtendedCommunities();
+        if (communitiesList == null) {
+            return;
+        }
+        for (ExtendedCommunities extendedCommunities : communitiesList) {
+            if (extendedCommunities.getCommSubType() != null) {
+                byteAggregator.writeShort(extendedCommunities.getCommSubType());
+            }
+            if (extendedCommunities.getExtendedCommunity() instanceof AsSpecificExtendedCommunityCase) {
+                AsSpecificExtendedCommunityCase asSpecificExtendedCommunity = (AsSpecificExtendedCommunityCase) extendedCommunities.getExtendedCommunity();
+
+                //TODO resolve types correctly
+                byteAggregator.writeByte(0);
+                byteAggregator.writeByte(1);
+
+                byteAggregator.writeShort(asSpecificExtendedCommunity.getAsSpecificExtendedCommunity().getGlobalAdministrator().getValue().shortValue());
+                byteAggregator.writeBytes(asSpecificExtendedCommunity.getAsSpecificExtendedCommunity().getLocalAdministrator());
+            }
+            if (extendedCommunities.getExtendedCommunity() instanceof Inet4SpecificExtendedCommunityCase) {
+                Inet4SpecificExtendedCommunityCase inet4SpecificExtendedCommunity = (Inet4SpecificExtendedCommunityCase) extendedCommunities.getExtendedCommunity();
+
+                //TODO resolve types correctly
+                byteAggregator.writeByte(1);
+                byteAggregator.writeByte(4);
+
+                byteAggregator.writeBytes(Ipv4Util.bytesForAddress(inet4SpecificExtendedCommunity.getInet4SpecificExtendedCommunity().getGlobalAdministrator()));
+                byteAggregator.writeBytes(inet4SpecificExtendedCommunity.getInet4SpecificExtendedCommunity().getLocalAdministrator());
+            }
+            if (extendedCommunities.getExtendedCommunity() instanceof OpaqueExtendedCommunityCase) {
+                OpaqueExtendedCommunityCase opaqueExtendedCommunity = (OpaqueExtendedCommunityCase) extendedCommunities.getExtendedCommunity();
+                //TODO resolve types correctly
+                byteAggregator.writeByte(3);
+                byteAggregator.writeByte(4);
+
+                byteAggregator.writeBytes(opaqueExtendedCommunity.getOpaqueExtendedCommunity().getValue());
+            }
+            if (extendedCommunities.getExtendedCommunity() instanceof RouteTargetExtendedCommunityCase) {
+                RouteTargetExtendedCommunityCase routeTargetExtendedCommunity = (RouteTargetExtendedCommunityCase) extendedCommunities.getExtendedCommunity();
+                //TODO how to determine, which numbering space global administrator number is originated from
+                byteAggregator.writeByte(0);
+                byteAggregator.writeByte(2);
+
+                byteAggregator.writeShort(routeTargetExtendedCommunity.getRouteTargetExtendedCommunity().getGlobalAdministrator().getValue().shortValue());
+                byteAggregator.writeBytes(routeTargetExtendedCommunity.getRouteTargetExtendedCommunity().getLocalAdministrator());
+            }
+            if (extendedCommunities.getExtendedCommunity() instanceof RouteOriginExtendedCommunityCase) {
+                RouteOriginExtendedCommunityCase routeOriginExtendedCommunity = (RouteOriginExtendedCommunityCase) extendedCommunities.getExtendedCommunity();
+                //TODO how to determine, which numbering space global administrator number is originated from
+                byteAggregator.writeByte(2);
+                byteAggregator.writeByte(3);
+                byteAggregator.writeShort(routeOriginExtendedCommunity.getRouteOriginExtendedCommunity().getGlobalAdministrator().getValue().shortValue());
+                byteAggregator.writeBytes(routeOriginExtendedCommunity.getRouteOriginExtendedCommunity().getLocalAdministrator());
+            }
+        }
+    }
+}
index 7a4cd243632fd371f058ff502380e9c65244cb71..5b46f3c0b0a091897ec92425c245478193f742d7 100644 (file)
@@ -10,14 +10,29 @@ package org.opendaylight.protocol.bgp.parser.impl.message.update;
 import io.netty.buffer.ByteBuf;
 
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.LocalPref;
 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.update.PathAttributesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class LocalPreferenceAttributeParser implements AttributeParser,AttributeSerializer {
 
-public final class LocalPreferenceAttributeParser implements AttributeParser {
     public static final int TYPE = 5;
 
     @Override
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) {
         builder.setLocalPref(new LocalPrefBuilder().setPref(buffer.readUnsignedInt()).build());
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        LocalPref lp = pathAttributes.getLocalPref();
+        if (lp == null) {
+            return;
+        }
+        byteAggregator.writeInt(lp.getPref().shortValue());
+    }
+}
index 09803874962501517b70b16dda68e2c812e08423..5407d602984bf5e3962d0c6d73d26874741e6ac6 100644 (file)
@@ -15,12 +15,15 @@ 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.AttributeSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.NlriRegistry;
 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.multiprotocol.rev130919.PathAttributes1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class MPReachAttributeParser implements AttributeParser,AttributeSerializer {
 
-public final class MPReachAttributeParser implements AttributeParser {
     public static final int TYPE = 14;
 
     private final NlriRegistry reg;
@@ -38,4 +41,9 @@ public final class MPReachAttributeParser implements AttributeParser {
             throw new BGPDocumentedException("Could not parse MP_REACH_NLRI", BGPError.OPT_ATTR_ERROR, e);
         }
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        //FIXME: implement this
+    }
+}
index b5b5f801eee46d16d0c04172eff929677bad53df..44085876b84d2adee0d73dee1b06fc769e0184bf 100644 (file)
@@ -15,12 +15,15 @@ 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.AttributeSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.NlriRegistry;
 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.multiprotocol.rev130919.PathAttributes2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class MPUnreachAttributeParser implements AttributeParser,AttributeSerializer {
 
-public final class MPUnreachAttributeParser implements AttributeParser {
     public static final int TYPE = 15;
 
     private final NlriRegistry reg;
@@ -38,4 +41,9 @@ public final class MPUnreachAttributeParser implements AttributeParser {
             throw new BGPDocumentedException("Could not parse MP_UNREACH_NLRI", BGPError.OPT_ATTR_ERROR, e);
         }
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        //FIME: implement this
+    }
+}
index 9c1162bee5a0a7db18fc1b7d9a8469862e705b88..6b2e0f4ed7555246b717003f5bb05dfd7bdb2567 100644 (file)
@@ -10,14 +10,29 @@ package org.opendaylight.protocol.bgp.parser.impl.message.update;
 import io.netty.buffer.ByteBuf;
 
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.MultiExitDisc;
 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.update.PathAttributesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class MultiExitDiscriminatorAttributeParser implements AttributeParser, AttributeSerializer {
 
-public final class MultiExitDiscriminatorAttributeParser implements AttributeParser {
     public static final int TYPE = 4;
 
     @Override
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) {
         builder.setMultiExitDisc(new MultiExitDiscBuilder().setMed(buffer.readUnsignedInt()).build());
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        MultiExitDisc multiExitDisc = pathAttributes.getMultiExitDisc();
+        if (multiExitDisc == null) {
+            return;
+        }
+        byteAggregator.writeInt(multiExitDisc.getMed().intValue());
+    }
+}
index c9a86d15fe544915bb2e831bb7a69a77c5757027..e6c713677a395db4f8ffe28475c4eea9aa0eeec7 100644 (file)
@@ -12,20 +12,48 @@ import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
 
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.protocol.concepts.Ipv6Util;
 import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.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.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class NextHopAttributeParser implements AttributeParser, AttributeSerializer {
 
-public final class NextHopAttributeParser implements AttributeParser {
     public static final int TYPE = 3;
 
     @Override
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) {
-        Preconditions.checkArgument(buffer.readableBytes() == Ipv4Util.IP4_LENGTH,
-                "Length of byte array for NEXT_HOP should be %s, but is %s", buffer.readableBytes(), Ipv4Util.IP4_LENGTH);
+        Preconditions.checkArgument(buffer.readableBytes() == Ipv4Util.IP4_LENGTH, "Length of byte array for NEXT_HOP should be %s, but is %s", buffer.readableBytes(), Ipv4Util.IP4_LENGTH);
         builder.setCNextHop(new Ipv4NextHopCaseBuilder().setIpv4NextHop(
                 new Ipv4NextHopBuilder().setGlobal(Ipv4Util.addressForBytes(ByteArray.readAllBytes(buffer))).build()).build());
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        CNextHop cNextHop = pathAttributes.getCNextHop();
+        if (cNextHop == null) {
+            return;
+        }
+        if (cNextHop instanceof Ipv4NextHopCase) {
+            Ipv4NextHopCase nextHop = (Ipv4NextHopCase) cNextHop;
+            byteAggregator.writeBytes(Ipv4Util.bytesForAddress(nextHop.getIpv4NextHop().getGlobal()));
+        } else if (cNextHop instanceof Ipv6NextHopCase) {
+            Ipv6NextHopCase nextHop = (Ipv6NextHopCase) cNextHop;
+            if (nextHop.getIpv6NextHop().getGlobal() != null) {
+                byteAggregator.writeBytes(Ipv6Util.bytesForAddress(nextHop.getIpv6NextHop().getGlobal()));
+            }
+            if (nextHop.getIpv6NextHop().getLinkLocal() != null) {
+                byteAggregator.writeBytes(Ipv6Util.bytesForAddress(nextHop.getIpv6NextHop().getLinkLocal()));
+            }
+        }
+    }
+}
index 2d48d862916a743a579f066c2f5688286d13e96e..7d45bd88fff7f3c64f92b53cc93134403cdc6d4a 100644 (file)
@@ -14,11 +14,16 @@ import io.netty.buffer.ByteBuf;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Origin;
 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.update.PathAttributesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class OriginAttributeParser implements AttributeParser, AttributeSerializer {
 
-public final class OriginAttributeParser implements AttributeParser {
     public static final int TYPE = 1;
 
     @Override
@@ -26,9 +31,18 @@ public final class OriginAttributeParser implements AttributeParser {
         byte rawOrigin = buffer.readByte();
         final BgpOrigin borigin = BgpOrigin.forValue(UnsignedBytes.toInt(rawOrigin));
         if (borigin == null) {
-            throw new BGPDocumentedException("Unknown Origin type.", BGPError.ORIGIN_ATTR_NOT_VALID, new byte[] { (byte) 0x01, (byte) 0x01,
-                rawOrigin });
+            throw new BGPDocumentedException("Unknown Origin type.", BGPError.ORIGIN_ATTR_NOT_VALID, new byte[] { (byte) 0x01, (byte) 0x01, rawOrigin} );
         }
         builder.setOrigin(new OriginBuilder().setValue(borigin).build());
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        Origin origin = pathAttributes.getOrigin();
+        if (origin == null) {
+            return;
+        }
+        byteAggregator.writeByte(origin.getValue().getIntValue());
+    }
+}
index 3295350d61bcbc6b80b575ba7c0baad7e18295d7..77499dc527d7bfa6d8ad254dd47dd1af037a6f9a 100644 (file)
@@ -12,19 +12,26 @@ import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
 
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
+import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.concepts.Ipv4Util;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+public final class OriginatorIdAttributeParser implements AttributeParser, AttributeSerializer {
 
-public final class OriginatorIdAttributeParser implements AttributeParser {
     public static final int TYPE = 9;
 
     private static final int ORIGINATOR_LENGTH = 4;
 
     @Override
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) {
-        Preconditions.checkArgument(buffer.readableBytes() == ORIGINATOR_LENGTH,
-                "Length of byte array for ORIGINATOR_ID should be %s, but is %s", ORIGINATOR_LENGTH, buffer.readableBytes());
+        Preconditions.checkArgument(buffer.readableBytes() == ORIGINATOR_LENGTH, "Length of byte array for ORIGINATOR_ID should be %s, but is %s", ORIGINATOR_LENGTH, buffer.readableBytes());
         builder.setOriginatorId(Ipv4Util.addressForBytes(ByteArray.readBytes(buffer, ORIGINATOR_LENGTH)));
     }
-}
\ No newline at end of file
+
+    @Override
+    public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
+        //FIXME: implement this
+    }
+}
index 288d42e54bc7f79740494ac4dfe28595a298d6e8..11c11ef87844ba59e7b3e336c9c151b58da2d812 100644 (file)
@@ -256,7 +256,7 @@ public class ComplementaryTest {
         final MessageRegistry msgReg = ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getMessageRegistry();
         String ex = "";
         try {
-            msgReg.serializeMessage(null);
+            msgReg.serializeMessage(null, Unpooled.EMPTY_BUFFER);
         } catch (final NullPointerException e) {
             ex = e.getMessage();
         }
index 0808482a2fbabcf6fc5649dd3dba1748dd66ebf8..6b7d706a491aea6ec1708cc0c029500ce8638cdf 100644 (file)
@@ -11,11 +11,15 @@ import static org.junit.Assert.assertArrayEquals;
 
 import com.google.common.collect.Lists;
 
+import io.netty.buffer.ByteBuf;
+
+import io.netty.buffer.Unpooled;
 import java.util.List;
 
 import org.junit.Test;
 import org.opendaylight.protocol.bgp.parser.impl.message.BGPOpenMessageParser;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
+import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
@@ -40,7 +44,8 @@ public class OpenTest {
                 new As4BytesCaseBuilder().setAs4BytesCapability(new As4BytesCapabilityBuilder().setAsNumber(new AsNumber(1000L)).build()).build()).build());
         final Open open = new OpenBuilder().setBgpIdentifier(new Ipv4Address("127.0.0.1")).setMyAsNumber(30).setHoldTimer(3).setVersion(
                 new ProtocolVersion((short) 4)).setBgpParameters(tlvs).build();
-        final byte[] msg = new BGPOpenMessageParser(ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getParameterRegistry()).serializeMessage(open);
-        assertArrayEquals(this.result, msg);
+        final ByteBuf msg = Unpooled.buffer();
+        new BGPOpenMessageParser(ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getParameterRegistry()).serializeMessage(open,msg);
+        assertArrayEquals(this.result, ByteArray.getAllBytes(msg));
     }
 }
index 99e53ccf20dc9dfc2f3f9d0de2cf58e5c0bb7f44..8b57833e0a5233248f12ffee83257d0723be31b8 100644 (file)
@@ -18,6 +18,7 @@ import static org.junit.matchers.JUnitMatchers.containsString;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
+import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 
 import java.net.UnknownHostException;
@@ -56,29 +57,31 @@ import org.opendaylight.yangtools.yang.binding.Notification;
 public class ParserTest {
 
     public static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14, (byte) 0x14,
-        (byte) 0x14, (byte) 0x14, (byte) 0x00 };
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
+        (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
 
     public static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0x00, (byte) 0x13, (byte) 0x04 };
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
 
     public static final byte[] notificationBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
 
     public static final byte[] openWithCpblt1 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0x00, (byte) 0x2d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4, (byte) 0xac, (byte) 0x14,
-        (byte) 0xa0, (byte) 0xaa, (byte) 0x10, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x00,
-        (byte) 0x01, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x40, (byte) 0x04, (byte) 0x00, (byte) 0x47 };
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0x00, (byte) 0x2d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4,
+        (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x10, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04,
+        (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x40,
+        (byte) 0x04, (byte) 0x00, (byte) 0x47 };
 
     public static final byte[] openWithCpblt2 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0x00, (byte) 0x2d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4, (byte) 0xac, (byte) 0x14,
-        (byte) 0xa0, (byte) 0xaa, (byte) 0x10, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x40, (byte) 0x04, (byte) 0x00,
-        (byte) 0x47, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01 };
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0x00, (byte) 0x2d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4,
+        (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x10, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04,
+        (byte) 0x40, (byte) 0x04, (byte) 0x00, (byte) 0x47, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x00,
+        (byte) 0x01, (byte) 0x00, (byte) 0x01 };
 
     static MessageRegistry reg;
 
@@ -89,8 +92,7 @@ public class ParserTest {
 
     @Test
     public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException {
-        byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
+        byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
         wrong = ByteArray.cutBytes(wrong, 16);
         try {
             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(wrong));
@@ -104,7 +106,7 @@ public class ParserTest {
 
     @Test
     public void testBadMsgType() throws BGPParsingException {
-        final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        final byte[] bytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
             (byte) 0x00, (byte) 0x13, (byte) 0x08 };
         try {
@@ -120,10 +122,11 @@ public class ParserTest {
     @Test
     public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException {
         final Notification keepAlive = new KeepaliveBuilder().build();
-        final byte[] bytes = ParserTest.reg.serializeMessage(keepAlive);
-        assertArrayEquals(keepAliveBMsg, bytes);
+        ByteBuf buffer = Unpooled.buffer();
+        ParserTest.reg.serializeMessage(keepAlive, buffer);
+        assertArrayEquals(keepAliveBMsg, ByteArray.getAllBytes(buffer));
 
-        final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
+        final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)));
 
         assertTrue(m instanceof Keepalive);
     }
@@ -149,8 +152,9 @@ public class ParserTest {
     public void testOpenMessage() throws UnknownHostException, BGPParsingException, BGPDocumentedException {
         final Notification open = new OpenBuilder().setMyAsNumber(100).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("20.20.20.20")).setVersion(
                 new ProtocolVersion((short) 4)).build();
-        final byte[] bytes = ParserTest.reg.serializeMessage(open);
-        assertArrayEquals(openBMsg, bytes);
+        ByteBuf bytes = Unpooled.buffer();
+        ParserTest.reg.serializeMessage(open, bytes);
+        assertArrayEquals(openBMsg, ByteArray.getAllBytes(bytes));
 
         final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
 
@@ -217,8 +221,9 @@ public class ParserTest {
     public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException {
         Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode()).setErrorSubcode(
                 BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build();
-        byte[] bytes = ParserTest.reg.serializeMessage(notMsg);
-        assertArrayEquals(notificationBMsg, bytes);
+        ByteBuf bytes = Unpooled.buffer();
+        ParserTest.reg.serializeMessage(notMsg, bytes);
+        assertArrayEquals(notificationBMsg, ByteArray.subByte(bytes.array(),0,bytes.writerIndex()));
 
         Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
 
@@ -228,7 +233,10 @@ public class ParserTest {
 
         notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode(
                 BGPError.CONNECTION_NOT_SYNC.getSubcode()).build();
-        bytes = ParserTest.reg.serializeMessage(notMsg);
+
+        bytes.clear();
+
+        ParserTest.reg.serializeMessage(notMsg, bytes);
 
         m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
 
@@ -292,9 +300,10 @@ public class ParserTest {
         final Open open = new OpenBuilder().setMyAsNumber(72).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("172.20.160.170")).setVersion(
                 new ProtocolVersion((short) 4)).setBgpParameters(tlvs).build();
 
-        final byte[] result = ParserTest.reg.serializeMessage(open);
+        ByteBuf result = Unpooled.buffer();
+        ParserTest.reg.serializeMessage(open, result);
 
         // the capabilities can be swapped.
-        assertTrue(Arrays.equals(openWithCpblt1, result) || Arrays.equals(openWithCpblt2, result));
+        assertTrue(Arrays.equals(openWithCpblt1, ByteArray.getAllBytes(result)) || Arrays.equals(openWithCpblt2, ByteArray.getAllBytes(result)));
     }
 }
index 26b39de070950b5079ce641ee78e218069af89da..d68837b55ec5ea3e078ad2ee7cac00dc786f0c71 100644 (file)
@@ -41,8 +41,8 @@ public class BGPMessageParserMock implements MessageRegistry {
     }
 
     @Override
-    public byte[] serializeMessage(final Notification msg) {
-        // nothing
-        return null;
+    public void serializeMessage(final Notification msg, final ByteBuf buffer) {
+        // no action needed, it's a mock for parsing, not serializing
+        return;
     }
 }
index f7afa9a7b9a09a8c8c808c2bb2fa27f6a99d73bf..d1ea5e5eee7cd5fbfce43c0142abcb67a7c81bdb 100644 (file)
@@ -26,7 +26,7 @@ public abstract class AbstractMessageRegistry implements MessageRegistry {
 
     protected abstract Notification parseBody(final int type, final ByteBuf body, final int messageLength) throws BGPDocumentedException;
 
-    protected abstract byte[] serializeMessageImpl(final Notification message);
+    protected abstract void serializeMessageImpl(final Notification message, final ByteBuf buffer);
 
     static {
         MARKER = new byte[MessageUtil.MARKER_LENGTH];
@@ -66,10 +66,8 @@ public abstract class AbstractMessageRegistry implements MessageRegistry {
     }
 
     @Override
-    public final byte[] serializeMessage(final Notification message) {
+    public final void serializeMessage(final Notification message, final ByteBuf buffer) {
         Preconditions.checkNotNull(message, "BGPMessage is mandatory.");
-        final byte[] ret = serializeMessageImpl(message);
-        Preconditions.checkNotNull(ret, "Unknown instance of BGPMessage. Passed ", message.getClass());
-        return ret;
+        serializeMessageImpl(message, buffer);
     }
 }
index 5102a4094bc4b827a604a2657e66bc927a78b61c..6220d8a6fd0103848b5ff49662e40b6f35ce0f4c 100644 (file)
@@ -15,7 +15,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
 public interface AttributeRegistry {
-    PathAttributes parseAttributes(ByteBuf buffer) throws BGPDocumentedException, BGPParsingException;
 
-    byte[] serializeAttribute(DataObject attribute);
+    PathAttributes parseAttributes(final ByteBuf buffer) throws BGPDocumentedException, BGPParsingException;
+
+    void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator);
 }
index 6ed40737ca9b5f18ab96fa382dd967ca2dc8354e..e3f334687cf3be079e23ba8ee7422ebee85ff88a 100644 (file)
@@ -7,8 +7,12 @@
  */
 package org.opendaylight.protocol.bgp.parser.spi;
 
+import io.netty.buffer.ByteBuf;
+
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
 public interface AttributeSerializer {
-    byte[] serializeAttribute(final DataObject attribute);
+
+    void serializeAttribute(final DataObject attribute,final ByteBuf byteAggregator);
+
 }
index 83ae7de21ed7236644eea37c3650233fbf7680d7..8c2da168dacb1b5fc352b44521e038e064bde22b 100644 (file)
@@ -14,7 +14,8 @@ import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
 public interface MessageRegistry {
-    Notification parseMessage(ByteBuf bytes) throws BGPDocumentedException, BGPParsingException;
 
-    byte[] serializeMessage(Notification message);
+    Notification parseMessage(final ByteBuf bytes) throws BGPDocumentedException, BGPParsingException;
+
+    void serializeMessage(final Notification message, final ByteBuf buffer);
 }
index 7d3482fbf6bddd3a53ed6ab76a4c64f8baaeb908..2ca3e355a5375963eeb54fb3b5cc2b6d2c170d3f 100644 (file)
@@ -7,8 +7,10 @@
  */
 package org.opendaylight.protocol.bgp.parser.spi;
 
+import io.netty.buffer.ByteBuf;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
 public interface MessageSerializer {
-    byte[] serializeMessage(Notification message);
+
+    void serializeMessage(Notification message, ByteBuf bytes);
 }
index 5faad29fc26b50e6a9ca93c8bf972ebc5da0b869..75c8ac5b549583dadc8128e4e509d4a5fe3b696a 100644 (file)
@@ -115,11 +115,9 @@ final class SimpleAttributeRegistry implements AttributeRegistry {
     }
 
     @Override
-    public byte[] serializeAttribute(final DataObject attribute) {
-        final AttributeSerializer serializer = this.handlers.getSerializer(attribute.getImplementedInterface());
-        if (serializer == null) {
-            return null;
+    public void serializeAttribute(final DataObject attribute,final ByteBuf byteAggregator) {
+        for (AttributeSerializer serializer : this.handlers.getAllSerializers()) {
+            serializer.serializeAttribute(attribute, byteAggregator);
         }
-        return serializer.serializeAttribute(attribute);
     }
 }
index 57b815e684bda2cf7bfdecf4b2183d44a64cf827..dbeee1d9b43c209155dc2215283c41dd035da589 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
 final class SimpleMessageRegistry extends AbstractMessageRegistry {
+
     private final HandlerRegistry<DataContainer, MessageParser, MessageSerializer> handlers = new HandlerRegistry<>();
 
     @Override
@@ -31,13 +32,12 @@ final class SimpleMessageRegistry extends AbstractMessageRegistry {
     }
 
     @Override
-    protected byte[] serializeMessageImpl(final Notification message) {
+    protected void serializeMessageImpl(final Notification message, final ByteBuf buffer) {
         final MessageSerializer serializer = this.handlers.getSerializer(message.getImplementedInterface());
         if (serializer == null) {
-            return null;
+            return;
         }
-
-        return serializer.serializeMessage(message);
+        serializer.serializeMessage(message, buffer);
     }
 
     AutoCloseable registerMessageParser(final int messageType, final MessageParser parser) {
index ad46f6eb99ed412e548524e79d13255f6de5dddb..fc2cc8d1f7f81b16832ed3a110eda419d8bd86cc 100644 (file)
@@ -15,6 +15,7 @@ import io.netty.buffer.Unpooled;
 import org.junit.Test;
 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.Keepalive;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.KeepaliveBuilder;
 import org.opendaylight.yangtools.yang.binding.Notification;
@@ -22,14 +23,14 @@ import org.opendaylight.yangtools.yang.binding.Notification;
 public class AbstractMessageRegistryTest {
 
     public static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0x00, (byte) 0x13, (byte) 0x04 };
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
 
     private final AbstractMessageRegistry registry = new AbstractMessageRegistry() {
 
         @Override
-        protected byte[] serializeMessageImpl(Notification message) {
-            return keepAliveBMsg;
+        protected void serializeMessageImpl(final Notification message, final ByteBuf buffer) {
+            buffer.writeBytes(keepAliveBMsg);
         }
 
         @Override
@@ -41,8 +42,9 @@ public class AbstractMessageRegistryTest {
     @Test
     public void testRegistry() throws BGPDocumentedException, BGPParsingException {
         final Notification keepAlive = new KeepaliveBuilder().build();
-        final byte[] serialized = this.registry.serializeMessage(keepAlive);
-        assertArrayEquals(keepAliveBMsg, serialized);
+        final ByteBuf buffer = Unpooled.buffer();
+        this.registry.serializeMessage(keepAlive, buffer);
+        assertArrayEquals(keepAliveBMsg, ByteArray.getAllBytes(buffer));
 
         final Notification not = this.registry.parseMessage(Unpooled.copiedBuffer(keepAliveBMsg));
         assertTrue(not instanceof Keepalive);
index 633d232788d609e95e8087c5760da9e13244e8fa..7ccb289599c9deec15e871442c175a5d4b9cb874 100644 (file)
@@ -10,12 +10,12 @@ package org.opendaylight.protocol.bgp.rib.impl;
 import com.google.common.base.Preconditions;
 
 import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
 import io.netty.channel.ChannelHandler.Sharable;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToByteEncoder;
 
 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
-import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yangtools.yang.binding.Notification;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,9 +35,8 @@ final class BGPMessageToByteEncoder extends MessageToByteEncoder<Notification> {
     @Override
     protected void encode(final ChannelHandlerContext ctx, final Notification msg, final ByteBuf out) {
         LOG.trace("Encoding message: {}", msg);
-        final byte[] bytes = this.registry.serializeMessage(msg);
-        LOG.trace("Encoded message: {}", ByteArray.bytesToHexString(bytes));
-        out.writeBytes(bytes);
+        this.registry.serializeMessage(msg, out);
+        LOG.trace("Encoded message: {}", ByteBufUtil.hexDump(out));
         LOG.debug("Message sent to output: {}", msg);
     }
 }