Bug-3075: BMP message parsers/serializers implementation 03/21103/5
authorMilos Fabian <milfabia@cisco.com>
Tue, 26 May 2015 09:27:10 +0000 (11:27 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 24 Jun 2015 09:27:38 +0000 (09:27 +0000)
Change-Id: Ie0b8ee9c0086ffcebff9d5d767d87c198673f9fd
Signed-off-by: Milos Fabian <milfabia@cisco.com>
bgp/bmp-impl/.project [new file with mode: 0644]
bgp/bmp-impl/pom.xml [new file with mode: 0644]
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/InitiationHandler.java [new file with mode: 0644]
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/PeerDownHandler.java [new file with mode: 0644]
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/PeerUpHandler.java [new file with mode: 0644]
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/RouteMonitoringMessageHandler.java [new file with mode: 0644]
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/StatisticsReportHandler.java [new file with mode: 0644]
bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/TerminationHandler.java [new file with mode: 0644]
bgp/pom.xml

diff --git a/bgp/bmp-impl/.project b/bgp/bmp-impl/.project
new file mode 100644 (file)
index 0000000..2bcc427
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>bgp-bmp-impl</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.m2e.core.maven2Builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.eclipse.m2e.core.maven2Nature</nature>
+       </natures>
+</projectDescription>
diff --git a/bgp/bmp-impl/pom.xml b/bgp/bmp-impl/pom.xml
new file mode 100644 (file)
index 0000000..7b36c58
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main</url>
+        <tag>HEAD</tag>
+    </scm>
+
+    <parent>
+        <groupId>org.opendaylight.bgpcep</groupId>
+        <artifactId>bgp-parent</artifactId>
+        <version>0.5.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>bgp-bmp-impl</artifactId>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+    <prerequisites>
+        <maven>3.0.4</maven>
+    </prerequisites>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>bgp-bmp-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>bgp-bmp-spi</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-handler</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+                        <Export-Package>
+                            org.opendaylight.protocol.bmp.impl.*,
+                        </Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/InitiationHandler.java b/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/InitiationHandler.java
new file mode 100644 (file)
index 0000000..1f724b2
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bmp.impl.message;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bmp.spi.parser.AbstractBmpMessageWithTlvParser;
+import org.opendaylight.protocol.bmp.spi.parser.BmpDeserializationException;
+import org.opendaylight.protocol.bmp.spi.registry.BmpTlvRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.InitiationMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.InitiationMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.Tlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.description.tlv.DescriptionTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.initiation.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.initiation.TlvsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.name.tlv.NameTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.string.informations.StringInformation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.string.informations.StringInformationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.string.tlv.StringTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.string.tlv.StringTlvBuilder;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * Created by cgasparini on 13.5.2015.
+ */
+public class InitiationHandler extends AbstractBmpMessageWithTlvParser<TlvsBuilder> {
+
+    public InitiationHandler(final BmpTlvRegistry tlvRegistry) {
+        super(tlvRegistry);
+    }
+
+    private static final int MESSAGE_TYPE = 4;
+
+    @Override
+    public void serializeMessageBody(final Notification message, final ByteBuf buffer) {
+        Preconditions.checkArgument(message instanceof InitiationMessage, "Incorrect instance of BGP message. The Initiation Message is expected.");
+        final InitiationMessage initiation = (InitiationMessage) message;
+        serializeTlvs(initiation.getTlvs(), buffer);
+    }
+
+    @Override
+    public Notification parseMessageBody(final ByteBuf bytes) throws BmpDeserializationException {
+        final InitiationMessageBuilder initiationBuilder = new InitiationMessageBuilder();
+        final TlvsBuilder tlvsBuilder = new TlvsBuilder();
+        tlvsBuilder.setStringInformation(ImmutableList.<StringInformation>of());
+        parseTlvs(tlvsBuilder, bytes);
+
+        if (tlvsBuilder.getDescriptionTlv() == null || tlvsBuilder.getDescriptionTlv().getDescription() == null) {
+            throw new BmpDeserializationException("Inclusion of sysDescr TLV is mandatory.");
+        }
+        if (tlvsBuilder.getNameTlv() == null || tlvsBuilder.getNameTlv().getName() == null) {
+            throw new BmpDeserializationException("Inclusion of sysName TLV is mandatory.");
+        }
+
+        return initiationBuilder.setTlvs(tlvsBuilder.build()).build();
+    }
+
+    @Override
+    public int getBmpMessageType() {
+        return MESSAGE_TYPE;
+    }
+
+    private void serializeTlvs(final Tlvs tlvs, final ByteBuf output) {
+        serializeTlv(tlvs.getNameTlv(), output);
+        serializeTlv(tlvs.getDescriptionTlv(), output);
+        if (tlvs.getStringInformation() != null) {
+            for (final StringInformation stringInfo : tlvs.getStringInformation()) {
+                if (stringInfo.getStringTlv() != null) {
+                    serializeTlv(stringInfo.getStringTlv(), output);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void addTlv(final TlvsBuilder builder, final Tlv tlv) {
+        if (tlv instanceof DescriptionTlv) {
+            builder.setDescriptionTlv((DescriptionTlv) tlv);
+        } else if (tlv instanceof NameTlv) {
+            builder.setNameTlv((NameTlv) tlv);
+        } else if (tlv instanceof StringTlv) {
+            builder.setStringInformation(ImmutableList.<StringInformation>builder()
+                    .addAll(builder.getStringInformation())
+                    .add(new StringInformationBuilder().setStringTlv(new StringTlvBuilder((StringTlv) tlv).build()).build()).build());
+        }
+    }
+}
diff --git a/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/PeerDownHandler.java b/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/PeerDownHandler.java
new file mode 100644 (file)
index 0000000..0aa2b87
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bmp.impl.message;
+
+import static org.opendaylight.protocol.bmp.impl.message.PeerDownHandler.Reason.REASON_FOUR;
+import static org.opendaylight.protocol.bmp.impl.message.PeerDownHandler.Reason.REASON_ONE;
+import static org.opendaylight.protocol.bmp.impl.message.PeerDownHandler.Reason.REASON_THREE;
+import static org.opendaylight.protocol.bmp.impl.message.PeerDownHandler.Reason.REASON_TWO;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import io.netty.buffer.ByteBuf;
+import java.util.Map;
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
+import org.opendaylight.protocol.bmp.spi.parser.AbstractBmpPerPeerMessageParser;
+import org.opendaylight.protocol.bmp.spi.parser.BmpDeserializationException;
+import org.opendaylight.protocol.util.ByteBufWriteUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.NotifyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.NotifyMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerDownNotification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerDownNotificationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.Data;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.FsmEventCode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.FsmEventCodeBuilder;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * Created by cgasparini on 13.5.2015.
+ */
+public class PeerDownHandler extends AbstractBmpPerPeerMessageParser<PeerDownNotificationBuilder> {
+
+    private static final int MESSAGE_TYPE = 2;
+
+    public PeerDownHandler(final MessageRegistry bgpMssageRegistry) {
+        super(bgpMssageRegistry);
+    }
+
+    @Override
+    public void serializeMessageBody(final Notification message, final ByteBuf buffer) {
+        super.serializeMessageBody(message, buffer);
+        Preconditions.checkArgument(message instanceof PeerDownNotification, "An instance of PeerDownNotification is required");
+        final PeerDownNotification peerDown = (PeerDownNotification) message;
+        if (peerDown.isLocalSystemClosed()) {
+            if (peerDown.getData() instanceof FsmEventCode) {
+                ByteBufWriteUtil.writeUnsignedByte(REASON_TWO.getValue(), buffer);
+                ByteBufWriteUtil.writeUnsignedShort(((FsmEventCode) peerDown.getData()).getFsmEventCode().intValue(), buffer);
+            } else if (peerDown.getData() instanceof
+                org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.Notification) {
+                ByteBufWriteUtil.writeUnsignedByte(REASON_ONE.getValue(), buffer);
+                serializePDU(peerDown.getData(), buffer);
+            }
+        } else {
+            if (peerDown.getData() instanceof
+                org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.Notification) {
+                ByteBufWriteUtil.writeUnsignedByte(REASON_THREE.getValue(), buffer);
+                serializePDU(peerDown.getData(), buffer);
+            } else {
+                ByteBufWriteUtil.writeUnsignedByte(REASON_FOUR.getValue(), buffer);
+            }
+        }
+    }
+
+    private void serializePDU(final Data data, final ByteBuf buffer) {
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.Notification notification
+            = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.Notification) data;
+        this.getBgpMessageRegistry().serializeMessage(new NotifyBuilder(notification.getNotification()).build(), buffer);
+    }
+
+    @Override
+    public Notification parseMessageBody(final ByteBuf bytes) throws BmpDeserializationException {
+        final PeerDownNotificationBuilder peerDown = new PeerDownNotificationBuilder().setPeerHeader(parsePerPeerHeader(bytes));
+        final Reason reason = Reason.forValue(bytes.readUnsignedByte());
+        if (reason != null) {
+            switch (reason) {
+            case REASON_ONE:
+                peerDown.setLocalSystemClosed(true);
+                peerDown.setData(parseBgpNotificationMessage(bytes));
+                break;
+            case REASON_TWO:
+                peerDown.setLocalSystemClosed(true);
+                peerDown.setData(new FsmEventCodeBuilder().setFsmEventCode(bytes.readUnsignedShort()).build());
+                break;
+            case REASON_THREE:
+                peerDown.setLocalSystemClosed(false);
+                peerDown.setData(parseBgpNotificationMessage(bytes));
+                break;
+            case REASON_FOUR:
+                peerDown.setLocalSystemClosed(false);
+                break;
+            default:
+                break;
+            }
+        }
+
+        return peerDown.build();
+    }
+
+    private org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.Notification parseBgpNotificationMessage(final ByteBuf bytes) throws BmpDeserializationException {
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.NotificationBuilder notificationCBuilder
+            = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.NotificationBuilder();
+
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.notification.NotificationBuilder notificationBuilder
+            = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.down.data.notification.NotificationBuilder();
+        try {
+            final Notification not = this.getBgpMessageRegistry().parseMessage(bytes);
+            Preconditions.checkNotNull(not, "Notify message may not be null.");
+            Preconditions.checkArgument(not instanceof NotifyMessage, "An instance of NotifyMessage is required");
+            notificationBuilder.fieldsFrom((NotifyMessage) not);
+            notificationCBuilder.setNotification(notificationBuilder.build());
+        } catch (final BGPDocumentedException | BGPParsingException e) {
+            throw new BmpDeserializationException("Error while parsing BGP Notification message.", e);
+        }
+
+        return notificationCBuilder.build();
+    }
+
+    @Override
+    public int getBmpMessageType() {
+        return MESSAGE_TYPE;
+    }
+
+    public enum Reason {
+
+        REASON_ONE((short) 1), REASON_TWO((short) 2), REASON_THREE((short) 3), REASON_FOUR((short) 4);
+
+        private static final Map<Short, Reason> VALUE_MAP;
+
+        static {
+            final ImmutableMap.Builder<Short, Reason> b = ImmutableMap.builder();
+            for (final Reason enumItem : Reason.values()) {
+                b.put(enumItem.getValue(), enumItem);
+            }
+            VALUE_MAP = b.build();
+        }
+
+        private final short value;
+
+        Reason(final short value) {
+            this.value = value;
+        }
+
+        public static Reason forValue(final short value) {
+            return VALUE_MAP.get(value);
+        }
+
+        public short getValue() {
+            return this.value;
+        }
+    }
+}
diff --git a/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/PeerUpHandler.java b/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/PeerUpHandler.java
new file mode 100644 (file)
index 0000000..fb5380d
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bmp.impl.message;
+
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
+import org.opendaylight.protocol.bmp.spi.parser.AbstractBmpPerPeerMessageParser;
+import org.opendaylight.protocol.bmp.spi.parser.BmpDeserializationException;
+import org.opendaylight.protocol.util.ByteBufWriteUtil;
+import org.opendaylight.protocol.util.Ipv4Util;
+import org.opendaylight.protocol.util.Ipv6Util;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUpNotification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUpNotificationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.up.ReceivedOpenBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.up.SentOpenBuilder;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * Created by cgasparini on 13.5.2015.
+ */
+public class PeerUpHandler extends AbstractBmpPerPeerMessageParser<PeerUpNotificationBuilder> {
+
+    private static final int MESSAGE_TYPE = 3;
+
+    public PeerUpHandler(final MessageRegistry bgpMssageRegistry) {
+        super(bgpMssageRegistry);
+    }
+
+    @Override
+    public void serializeMessageBody(final Notification message, final ByteBuf buffer) {
+        super.serializeMessageBody(message, buffer);
+        Preconditions.checkArgument(message instanceof PeerUpNotification, "An instance of Peer Up notification is required");
+        final PeerUpNotification peerUp = (PeerUpNotification) message;
+
+        if (peerUp.getLocalAddress().getIpv4Address() != null) {
+            buffer.writeZero(Ipv6Util.IPV6_LENGTH - Ipv4Util.IP4_LENGTH);
+            ByteBufWriteUtil.writeIpv4Address(peerUp.getLocalAddress().getIpv4Address(), buffer);
+        } else {
+            ByteBufWriteUtil.writeIpv6Address(peerUp.getLocalAddress().getIpv6Address(), buffer);
+        }
+        ByteBufWriteUtil.writeUnsignedShort(peerUp.getLocalPort().getValue(), buffer);
+        ByteBufWriteUtil.writeUnsignedShort(peerUp.getRemotePort().getValue(), buffer);
+
+        getBgpMessageRegistry().serializeMessage(new OpenBuilder(peerUp.getReceivedOpen()).build(), buffer);
+        getBgpMessageRegistry().serializeMessage(new OpenBuilder(peerUp.getSentOpen()).build(), buffer);
+    }
+
+    @Override
+    public Notification parseMessageBody(final ByteBuf bytes) throws BmpDeserializationException {
+        final PeerUpNotificationBuilder peerUpNot = new PeerUpNotificationBuilder().setPeerHeader(parsePerPeerHeader(bytes));
+
+        if (peerUpNot.getPeerHeader().isIpv4()) {
+            bytes.skipBytes(Ipv6Util.IPV6_LENGTH - Ipv4Util.IP4_LENGTH);
+            peerUpNot.setLocalAddress(new IpAddress(Ipv4Util.addressForByteBuf(bytes)));
+        } else {
+            peerUpNot.setLocalAddress(new IpAddress(Ipv6Util.addressForByteBuf(bytes)));
+        }
+        peerUpNot.setLocalPort(new PortNumber(bytes.readUnsignedShort()));
+        peerUpNot.setRemotePort(new PortNumber(bytes.readUnsignedShort()));
+        try {
+            final Notification opSent = getBgpMessageRegistry().parseMessage(bytes.readSlice(getBgpMessageLength(bytes)));
+            Preconditions.checkNotNull(opSent, "Error on parse Sent OPEN Message, Sent OPEN Message is null");
+            Preconditions.checkArgument(opSent instanceof OpenMessage, "An instance of OpenMessage notification is required");
+            final OpenMessage sent = (OpenMessage) opSent;
+
+            final Notification opRec = getBgpMessageRegistry().parseMessage(bytes);
+            Preconditions.checkNotNull(opRec, "Error on parse Received  OPEN Message, Received  OPEN Message is null");
+            Preconditions.checkArgument(opRec instanceof OpenMessage, "An instance of OpenMessage notification is required");
+            final OpenMessage received = (OpenMessage) opRec;
+
+            peerUpNot.setSentOpen(new SentOpenBuilder(sent).build());
+            peerUpNot.setReceivedOpen(new ReceivedOpenBuilder(received).build());
+        } catch (final BGPDocumentedException | BGPParsingException e) {
+            throw new BmpDeserializationException("Error while parsing BGP Open Message.", e);
+        }
+
+        return peerUpNot.build();
+    }
+
+    @Override
+    public int getBmpMessageType() {
+        return MESSAGE_TYPE;
+    }
+
+    private static int getBgpMessageLength(final ByteBuf buffer) {
+        return buffer.getUnsignedShort(buffer.readerIndex() + MessageUtil.MARKER_LENGTH);
+    }
+}
diff --git a/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/RouteMonitoringMessageHandler.java b/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/RouteMonitoringMessageHandler.java
new file mode 100644 (file)
index 0000000..5f50365
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bmp.impl.message;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
+import org.opendaylight.protocol.bmp.spi.parser.AbstractBmpPerPeerMessageParser;
+import org.opendaylight.protocol.bmp.spi.parser.BmpDeserializationException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.UpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.UpdateMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMonitoringMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMonitoringMessageBuilder;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * Created by cgasparini on 13.5.2015.
+ */
+public class RouteMonitoringMessageHandler extends AbstractBmpPerPeerMessageParser<RouteMonitoringMessageBuilder> {
+
+    private static final int MESSAGE_TYPE = 0;
+
+    public RouteMonitoringMessageHandler(final MessageRegistry bgpMssageRegistry) {
+        super(bgpMssageRegistry);
+    }
+
+    @Override
+    public void serializeMessageBody(final Notification message, final ByteBuf buffer) {
+        super.serializeMessageBody(message, buffer);
+        Preconditions.checkArgument(message instanceof RouteMonitoringMessage, "An instance of RouteMonitoringMessage is required");
+        final RouteMonitoringMessage routeMonitor = (RouteMonitoringMessage) message;
+        getBgpMessageRegistry().serializeMessage(new UpdateBuilder(routeMonitor.getUpdate()).build(), buffer);
+    }
+
+    @Override
+    public Notification parseMessageBody(final ByteBuf bytes) throws BmpDeserializationException {
+        final RouteMonitoringMessageBuilder routeMonitor = new RouteMonitoringMessageBuilder().setPeerHeader(parsePerPeerHeader(bytes));
+        try {
+            final Notification message = getBgpMessageRegistry().parseMessage(bytes);
+            Preconditions.checkNotNull(message, "UpdateMessage may not be null");
+            Preconditions.checkArgument(message instanceof UpdateMessage, "An instance of UpdateMessage is required");
+            final UpdateMessage updateMessage = (UpdateMessage) message;
+            final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.route.monitoring
+                .message.Update update = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message
+                .rev150512.route.monitoring.message.UpdateBuilder(updateMessage).build();
+            routeMonitor.setUpdate(update);
+        } catch (final BGPDocumentedException | BGPParsingException e) {
+            throw new BmpDeserializationException("Error while parsing Update Message.", e);
+        }
+
+        return routeMonitor.build();
+    }
+
+    @Override
+    public int getBmpMessageType() {
+        return MESSAGE_TYPE;
+    }
+}
diff --git a/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/StatisticsReportHandler.java b/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/StatisticsReportHandler.java
new file mode 100644 (file)
index 0000000..63b0d6d
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bmp.impl.message;
+
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.INT_BYTES_LENGTH;
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedInt;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
+import org.opendaylight.protocol.bmp.spi.parser.AbstractBmpPerPeerMessageParser;
+import org.opendaylight.protocol.bmp.spi.parser.BmpDeserializationException;
+import org.opendaylight.protocol.bmp.spi.registry.BmpTlvRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.StatsReportsMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.StatsReportsMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.Tlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.TlvsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.AdjRibsInRoutesTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.DuplicatePrefixAdvertisementsTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.DuplicateWithdrawsTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.InvalidatedAsConfedLoopTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.InvalidatedAsPathLoopTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.InvalidatedClusterListLoopTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.InvalidatedOriginatorIdTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.LocRibRoutesTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.tlvs.RejectedPrefixesTlv;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * Created by cgasparini on 13.5.2015.
+ */
+public class StatisticsReportHandler extends AbstractBmpPerPeerMessageParser<TlvsBuilder> {
+
+    private static final int MESSAGE_TYPE = 1;
+
+    public StatisticsReportHandler(final MessageRegistry bgpMssageRegistry, final BmpTlvRegistry tlvRegistry) {
+        super(bgpMssageRegistry, tlvRegistry);
+    }
+
+    @Override
+    public void serializeMessageBody(final Notification message, final ByteBuf buffer) {
+        super.serializeMessageBody(message, buffer);
+        Preconditions.checkArgument(message instanceof StatsReportsMessage, "An instance of Statistics Reports message is required");
+        final StatsReportsMessage statsReport = (StatsReportsMessage) message;
+        serializeTlvs(statsReport.getTlvs(), buffer);
+    }
+
+    @Override
+    public Notification parseMessageBody(final ByteBuf bytes) throws BmpDeserializationException {
+        final StatsReportsMessageBuilder statReport = new StatsReportsMessageBuilder().setPeerHeader(parsePerPeerHeader(bytes));
+        final TlvsBuilder tlvsBuilder = new TlvsBuilder();
+        bytes.skipBytes(INT_BYTES_LENGTH);
+        parseTlvs(tlvsBuilder, bytes);
+
+        return statReport.setTlvs(tlvsBuilder.build()).build();
+    }
+
+    @Override
+    public int getBmpMessageType() {
+        return MESSAGE_TYPE;
+    }
+
+    protected void serializeTlvs(final Tlvs tlvs, final ByteBuf output) {
+        final AtomicInteger counter = new AtomicInteger(0);
+        final ByteBuf tlvsBuffer = Unpooled.buffer();
+        serializeStatTlv(tlvs.getRejectedPrefixesTlv(), tlvsBuffer, counter);
+        serializeStatTlv(tlvs.getDuplicatePrefixAdvertisementsTlv(), tlvsBuffer, counter);
+        serializeStatTlv(tlvs.getDuplicateWithdrawsTlv(), tlvsBuffer, counter);
+        serializeStatTlv(tlvs.getInvalidatedClusterListLoopTlv(), tlvsBuffer, counter);
+        serializeStatTlv(tlvs.getInvalidatedAsPathLoopTlv(), tlvsBuffer, counter);
+        serializeStatTlv(tlvs.getInvalidatedOriginatorIdTlv(), tlvsBuffer, counter);
+        serializeStatTlv(tlvs.getInvalidatedAsConfedLoopTlv(), tlvsBuffer, counter);
+        serializeStatTlv(tlvs.getAdjRibsInRoutesTlv(), tlvsBuffer, counter);
+        serializeStatTlv(tlvs.getLocRibRoutesTlv(), tlvsBuffer, counter);
+        writeUnsignedInt(counter.longValue(), output);
+        output.writeBytes(tlvsBuffer);
+    }
+
+    private void serializeStatTlv(final Tlv tlv, final ByteBuf tlvsBuffer, final AtomicInteger counter) {
+        if (tlv != null) {
+            counter.incrementAndGet();
+            serializeTlv(tlv, tlvsBuffer);
+        }
+    }
+
+    @Override
+    protected void addTlv(final TlvsBuilder builder, final Tlv tlv) {
+        if (tlv instanceof AdjRibsInRoutesTlv) {
+            builder.setAdjRibsInRoutesTlv((AdjRibsInRoutesTlv) tlv);
+        } else if (tlv instanceof DuplicatePrefixAdvertisementsTlv) {
+            builder.setDuplicatePrefixAdvertisementsTlv((DuplicatePrefixAdvertisementsTlv) tlv);
+        } else if (tlv instanceof DuplicateWithdrawsTlv) {
+            builder.setDuplicateWithdrawsTlv((DuplicateWithdrawsTlv) tlv);
+        } else if (tlv instanceof InvalidatedAsConfedLoopTlv) {
+            builder.setInvalidatedAsConfedLoopTlv((InvalidatedAsConfedLoopTlv) tlv);
+        } else if (tlv instanceof InvalidatedAsPathLoopTlv) {
+            builder.setInvalidatedAsPathLoopTlv((InvalidatedAsPathLoopTlv) tlv);
+        } else if (tlv instanceof InvalidatedClusterListLoopTlv) {
+            builder.setInvalidatedClusterListLoopTlv((InvalidatedClusterListLoopTlv) tlv);
+        } else if (tlv instanceof InvalidatedOriginatorIdTlv) {
+            builder.setInvalidatedOriginatorIdTlv((InvalidatedOriginatorIdTlv) tlv);
+        } else if (tlv instanceof LocRibRoutesTlv) {
+            builder.setLocRibRoutesTlv((LocRibRoutesTlv) tlv);
+        } else if (tlv instanceof RejectedPrefixesTlv) {
+            builder.setRejectedPrefixesTlv((RejectedPrefixesTlv) tlv);
+        }
+    }
+
+}
diff --git a/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/TerminationHandler.java b/bgp/bmp-impl/src/main/java/org/opendaylight/protocol/bmp/impl/message/TerminationHandler.java
new file mode 100644 (file)
index 0000000..35ae6a9
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bmp.impl.message;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bmp.spi.parser.AbstractBmpMessageWithTlvParser;
+import org.opendaylight.protocol.bmp.spi.parser.BmpDeserializationException;
+import org.opendaylight.protocol.bmp.spi.registry.BmpTlvRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.TerminationMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.TerminationMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.Tlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.reason.tlv.ReasonTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.string.informations.StringInformation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.string.informations.StringInformationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.string.tlv.StringTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.string.tlv.StringTlvBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.termination.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.termination.TlvsBuilder;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * Created by cgasparini on 13.5.2015.
+ */
+public class TerminationHandler extends AbstractBmpMessageWithTlvParser<TlvsBuilder> {
+
+    public TerminationHandler(final BmpTlvRegistry tlvRegistry) {
+        super(tlvRegistry);
+    }
+
+    private static final int MESSAGE_TYPE = 5;
+
+    @Override
+    public Notification parseMessageBody(final ByteBuf bytes) throws BmpDeserializationException {
+        final TerminationMessageBuilder terminationMessage = new TerminationMessageBuilder();
+        final TlvsBuilder tlvsBuilder = new TlvsBuilder();
+        tlvsBuilder.setStringInformation(ImmutableList.<StringInformation>of());
+        parseTlvs(tlvsBuilder, bytes);
+        if (tlvsBuilder.getReasonTlv() == null || tlvsBuilder.getReasonTlv().getReason() == null) {
+            throw new BmpDeserializationException("Inclusion of Reason TLV is mandatory.");
+        }
+        return terminationMessage.setTlvs(tlvsBuilder.build()).build();
+    }
+
+
+    @Override
+    public void serializeMessageBody(final Notification message, final ByteBuf buffer) {
+        Preconditions.checkArgument(message instanceof TerminationMessage, "An instance of Termination message is required");
+        final TerminationMessage terminationMsg = (TerminationMessage) message;
+        serializeTlvs(terminationMsg.getTlvs(), buffer);
+    }
+
+    @Override
+    public int getBmpMessageType() {
+        return MESSAGE_TYPE;
+    }
+
+    protected void serializeTlvs(final Tlvs tlvs, final ByteBuf output) {
+        serializeTlv(tlvs.getReasonTlv(), output);
+        if (tlvs.getStringInformation() != null) {
+            for (final StringInformation stringInfo : tlvs.getStringInformation()) {
+                if (stringInfo.getStringTlv() != null) {
+                    serializeTlv(stringInfo.getStringTlv(), output);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void addTlv(final TlvsBuilder builder, final Tlv tlv) {
+        if (tlv instanceof ReasonTlv) {
+            builder.setReasonTlv((ReasonTlv) tlv);
+        } else if (tlv instanceof StringTlv) {
+            builder.setStringInformation(ImmutableList.<StringInformation>builder()
+                    .addAll(builder.getStringInformation())
+                    .add(new StringInformationBuilder().setStringTlv(new StringTlvBuilder((StringTlv) tlv).build()).build()).build());
+        }
+    }
+}
index 848fffba5862a3278bea7546d5ddab57c0f43736..afa9d1dadb2c17a4b3820aa65b6902bdfadbee5c 100644 (file)
@@ -47,7 +47,7 @@
         <module>util</module>
         <module>bmp-api</module>
         <module>bmp-spi</module>
-
+        <module>bmp-impl</module>
         <module>controller-config</module>
     </modules>
 </project>