From: Dana Kutenicsova Date: Mon, 16 Jun 2014 22:05:31 +0000 (+0200) Subject: Bug 611 - BGP Update message serialization X-Git-Tag: release/helium~220 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=5321f0235aa629aafaf39b358281c796759ac863;p=bgpcep.git Bug 611 - BGP Update message serialization - 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 Signed-off-by: Dana Kutenicsova --- diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/BGPActivator.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/BGPActivator.java index 9bbaedf337..90f68664ef 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/BGPActivator.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/BGPActivator.java @@ -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 startImpl(final BGPExtensionProviderContext context) { final List 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)); diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPKeepAliveMessageParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPKeepAliveMessageParser.java index e841ed6213..93d27ad953 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPKeepAliveMessageParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPKeepAliveMessageParser.java @@ -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); } } diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPNotificationMessageParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPNotificationMessageParser.java index d41d611394..ab9543c8ac 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPNotificationMessageParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPNotificationMessageParser.java @@ -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)); } /** diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPOpenMessageParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPOpenMessageParser.java index 9125e93cc2..2e51c13bd3 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPOpenMessageParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPOpenMessageParser.java @@ -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)); } /** diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPUpdateMessageParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPUpdateMessageParser.java index 5599a66ffb..94209f2353 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPUpdateMessageParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/BGPUpdateMessageParser.java @@ -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 BGP-4 Update Message Format - * */ -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))); + } } diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4AggregatorAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4AggregatorAttributeParser.java index d188e0843f..63f128eed8 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4AggregatorAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4AggregatorAttributeParser.java @@ -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 +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4PathAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4PathAttributeParser.java index 86525b583c..421fd4df10 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4PathAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AS4PathAttributeParser.java @@ -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 +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AggregatorAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AggregatorAttributeParser.java index 60f964bef0..d02ef7d2e0 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AggregatorAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AggregatorAttributeParser.java @@ -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())); + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java index c8890b4628..02831bef79 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java @@ -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 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."); + } + } + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathSegmentParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathSegmentParser.java index b8b6f55c29..289135a668 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathSegmentParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathSegmentParser.java @@ -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 parseAsSequence(final ReferenceCache refCache, final int count, final ByteBuf buffer) { final List 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 parseAsSet(final ReferenceCache refCache, final int count, final ByteBuf buffer) { final List 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()); + } + } } diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AtomicAggregateAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AtomicAggregateAttributeParser.java index 5b2d4ccab0..520a39bec0 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AtomicAggregateAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AtomicAggregateAttributeParser.java @@ -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; + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ClusterIdAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ClusterIdAttributeParser.java index e1d3cf5c4c..99c0f5834d 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ClusterIdAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ClusterIdAttributeParser.java @@ -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 + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesAttributeParser.java index 3180b2dc2f..fd03473398 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/CommunitiesAttributeParser.java @@ -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 = pathAttributes.getCommunities(); + if (communities == null) { + return; + } + for (Community community : communities) { + byteAggregator.writeInt(community.getAsNumber().getValue().intValue()); + } + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ExtendedCommunitiesAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ExtendedCommunitiesAttributeParser.java index c68a6e5bc8..267d51ea7c 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ExtendedCommunitiesAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/ExtendedCommunitiesAttributeParser.java @@ -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 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 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()); + } + } + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LocalPreferenceAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LocalPreferenceAttributeParser.java index 7a4cd24363..5b46f3c0b0 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LocalPreferenceAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/LocalPreferenceAttributeParser.java @@ -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()); + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java index 0980387496..5407d60298 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java @@ -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 + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java index b5b5f801ee..44085876b8 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java @@ -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 + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MultiExitDiscriminatorAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MultiExitDiscriminatorAttributeParser.java index 9c1162bee5..6b2e0f4ed7 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MultiExitDiscriminatorAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MultiExitDiscriminatorAttributeParser.java @@ -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()); + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/NextHopAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/NextHopAttributeParser.java index c9a86d15fe..e6c713677a 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/NextHopAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/NextHopAttributeParser.java @@ -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())); + } + } + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java index 2d48d86291..7d45bd88ff 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java @@ -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()); + } +} diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginatorIdAttributeParser.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginatorIdAttributeParser.java index 3295350d61..77499dc527 100644 --- a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginatorIdAttributeParser.java +++ b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginatorIdAttributeParser.java @@ -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 + } +} diff --git a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ComplementaryTest.java b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ComplementaryTest.java index 288d42e54b..11c11ef878 100644 --- a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ComplementaryTest.java +++ b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ComplementaryTest.java @@ -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(); } diff --git a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/OpenTest.java b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/OpenTest.java index 0808482a2f..6b7d706a49 100644 --- a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/OpenTest.java +++ b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/OpenTest.java @@ -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)); } } diff --git a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java index 99e53ccf20..8b57833e0a 100644 --- a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java +++ b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java @@ -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))); } } diff --git a/bgp/parser-mock/src/main/java/org/opendaylight/protocol/bgp/parser/mock/BGPMessageParserMock.java b/bgp/parser-mock/src/main/java/org/opendaylight/protocol/bgp/parser/mock/BGPMessageParserMock.java index 26b39de070..d68837b55e 100644 --- a/bgp/parser-mock/src/main/java/org/opendaylight/protocol/bgp/parser/mock/BGPMessageParserMock.java +++ b/bgp/parser-mock/src/main/java/org/opendaylight/protocol/bgp/parser/mock/BGPMessageParserMock.java @@ -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; } } diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistry.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistry.java index f7afa9a7b9..d1ea5e5eee 100644 --- a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistry.java +++ b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistry.java @@ -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); } } diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeRegistry.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeRegistry.java index 5102a4094b..6220d8a6fd 100644 --- a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeRegistry.java +++ b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeRegistry.java @@ -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); } diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeSerializer.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeSerializer.java index 6ed40737ca..e3f334687c 100644 --- a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeSerializer.java +++ b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/AttributeSerializer.java @@ -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); + } diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageRegistry.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageRegistry.java index 83ae7de21e..8c2da168da 100644 --- a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageRegistry.java +++ b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageRegistry.java @@ -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); } diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageSerializer.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageSerializer.java index 7d3482fbf6..2ca3e355a5 100644 --- a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageSerializer.java +++ b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/MessageSerializer.java @@ -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); } diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleAttributeRegistry.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleAttributeRegistry.java index 5faad29fc2..75c8ac5b54 100644 --- a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleAttributeRegistry.java +++ b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleAttributeRegistry.java @@ -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); } } diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleMessageRegistry.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleMessageRegistry.java index 57b815e684..dbeee1d9b4 100644 --- a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleMessageRegistry.java +++ b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleMessageRegistry.java @@ -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 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) { diff --git a/bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistryTest.java b/bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistryTest.java index ad46f6eb99..fc2cc8d1f7 100644 --- a/bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistryTest.java +++ b/bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/AbstractMessageRegistryTest.java @@ -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); diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPMessageToByteEncoder.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPMessageToByteEncoder.java index 633d232788..7ccb289599 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPMessageToByteEncoder.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPMessageToByteEncoder.java @@ -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 { @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); } }