BMP termination message decoder

Change-Id: Iaf32429a1956553d79b22f3ab6b2525f12a962df
diff --git a/apps/bgpmonitoring/BUILD b/apps/bgpmonitoring/BUILD
new file mode 100644
index 0000000..204f124
--- /dev/null
+++ b/apps/bgpmonitoring/BUILD
@@ -0,0 +1,14 @@
+BUNDLES = [
+    "//apps/bgpmonitoring/api:onos-apps-bgpmonitoring-api",
+    "//apps/bgpmonitoring/app:onos-apps-bgpmonitoring-app",
+    "//protocols/bgp/bgpio:onos-protocols-bgp-bgpio",
+]
+
+onos_app(
+    app_name = "org.onosproject.bgpmonitoring",
+    category = "BGP Monitoring",
+    description = "BGP monitoring protocol application.",
+    included_bundles = BUNDLES,
+    title = "BGP Monitoring Protocol",
+    url = "http://onosproject.org",
+)
diff --git a/apps/bgpmonitoring/app/BUILD b/apps/bgpmonitoring/app/BUILD
new file mode 100644
index 0000000..787edb2
--- /dev/null
+++ b/apps/bgpmonitoring/app/BUILD
@@ -0,0 +1,11 @@
+COMPILE_DEPS = CORE_DEPS + JACKSON + METRICS + KRYO + CLI + REST + [
+    "//apps/bgpmonitoring/api:onos-apps-bgpmonitoring-api",
+    "//protocols/bgp/bgpio:onos-protocols-bgp-bgpio",
+    "//protocols/bgp/api:onos-protocols-bgp-api",
+    "@io_netty_netty_common//jar",
+    "@io_netty_netty//jar",
+]
+
+osgi_jar(
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/impl/package-info.java b/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/impl/package-info.java
new file mode 100644
index 0000000..29b06b0
--- /dev/null
+++ b/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * BGP monitoring application components.
+ */
+package org.onosproject.bgpmonitoring.impl;
\ No newline at end of file
diff --git a/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/BmpTerminationMessage.java b/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/BmpTerminationMessage.java
new file mode 100644
index 0000000..e60ddfd
--- /dev/null
+++ b/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/BmpTerminationMessage.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpmonitoring.type;
+
+
+import com.google.common.base.MoreObjects;
+import org.onosproject.bgpmonitoring.TerminationMessage;
+import org.onosproject.bgpmonitoring.BmpParseException;
+import org.onosproject.bgpmonitoring.TerminationType;
+
+import java.nio.charset.StandardCharsets;
+import java.nio.ByteBuffer;
+
+import org.onlab.packet.Deserializer;
+
+import java.util.function.BiPredicate;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * A means for the monitored router to inform the
+ * monitoring station of why it is closing a BMP session.
+ * The termination message provides a way for a monitored router to
+ * indicate why it is terminating a session.  Although use of this
+ * message is RECOMMENDED, a monitoring station must always be prepared
+ * for the session to terminate with no message.  Once the router has
+ * sent a termination message, it MUST close the TCP session without
+ * sending any further messages.  Likewise, the monitoring station MUST
+ * close the TCP session after receiving a termination message.
+ * <p>
+ * The termination message consists of the common BMP header followed by
+ * one or more TLVs containing information about the reason for the
+ * termination, as follows:
+ * Type = 0: String.  The Information field contains a free-form
+ * UTF-8 string whose length is given by the Information Length
+ * field.  Inclusion of this TLV is optional.  It MAY be used to
+ * provide further detail for any of the defined reasons.
+ * Multiple String TLVs MAY be included in the message.
+ */
+public final class BmpTerminationMessage extends TerminationMessage {
+
+/*
+      0                   1                   2                   3
+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |          Information Type     |       Information Length      |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                 Information (variable)                        |
+     ~                                                               ~
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+
+    private TerminationType terminationType;
+
+    private int informationLength;
+
+    private String information;
+
+    public BmpTerminationMessage(Builder builder) {
+        this.terminationType = builder.terminationType;
+        this.informationLength = builder.informationLength;
+        this.information = builder.information;
+    }
+
+    /**
+     * Returns BMP session termination type.
+     *
+     * @return BMP session termination type
+     */
+    @Override
+    public TerminationType getTerminationType() {
+        return terminationType;
+    }
+
+    /**
+     * Returns BMP session termination message length.
+     *
+     * @return BMP session termination message length
+     */
+    @Override
+    public int getInformationLength() {
+        return informationLength;
+    }
+
+    /**
+     * Returns BMP session termination message.
+     *
+     * @return BMP session termination message
+     */
+    @Override
+    public String getInformation() {
+        return information;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        BmpTerminationMessage that = (BmpTerminationMessage) o;
+        return informationLength == that.informationLength &&
+                terminationType == that.terminationType;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(terminationType, informationLength, information);
+        result = 31 * result;
+        return result;
+    }
+
+    /**
+     * Data deserializer function for BMP termination message.
+     *
+     * @return data deserializer function
+     */
+    public static Deserializer<BmpTerminationMessage> deserializer() {
+        return (data, offset, length) -> {
+            BiPredicate<ByteBuffer, Integer> isValidBuffer = (b, l)
+                    -> b.hasRemaining() && b.remaining() >= l;
+
+            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
+            if (!isValidBuffer.test(bb, TERMINATION_HEADER_MIN_LENGTH)) {
+                throw new BmpParseException("Invalid bmp termination message record buffer size.");
+            }
+            Builder builder = new Builder();
+            builder.terminationType(TerminationType.getType(bb.getInt()))
+                    .informationLength(bb.getInt());
+            if (builder.terminationType != TerminationType.UTF8_STRING) {
+                throw new BmpParseException("Not supported termination type");
+            }
+
+            byte[] information = new byte[builder.informationLength];
+            bb.get(information);
+
+            return builder.information(new String(information, StandardCharsets.UTF_8))
+                    .build();
+        };
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("terminationType", terminationType)
+                .add("informationLength", informationLength)
+                .add("information", information)
+                .toString();
+    }
+
+    /**
+     * Builder for BMP termination message.
+     */
+    private static class Builder {
+
+        private TerminationType terminationType;
+
+        private int informationLength;
+
+        private String information;
+
+
+        /**
+         * Setter bmp termination type.
+         *
+         * @param terminationType bmp termination type.
+         * @return this class builder.
+         */
+        public Builder terminationType(TerminationType terminationType) {
+            this.terminationType = terminationType;
+            return this;
+        }
+
+        /**
+         * Setter bmp termination message length.
+         *
+         * @param informationLength bmp termination message length.
+         * @return this class builder.
+         */
+        public Builder informationLength(int informationLength) {
+            this.informationLength = informationLength;
+            return this;
+        }
+
+        /**
+         * Setter bmp termination message.
+         *
+         * @param information bmp termination message.
+         * @return this class builder.
+         */
+        public Builder information(String information) {
+            this.information = information;
+            return this;
+        }
+
+        /**
+         * Checks arguments for bmp termination message.
+         */
+        private void checkArguments() {
+            checkState(terminationType != null, "Invalid bmp termination type.");
+            checkState(informationLength != 0, "Invalid bmp termination message length.");
+        }
+
+        /**
+         * Builds bmp termination message.
+         *
+         * @return bmp termination message object.
+         */
+        public BmpTerminationMessage build() {
+            checkArguments();
+            return new BmpTerminationMessage(this);
+        }
+    }
+}
diff --git a/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/package-info.java b/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/package-info.java
new file mode 100644
index 0000000..e4bb4bb
--- /dev/null
+++ b/apps/bgpmonitoring/app/src/main/java/org/onosproject/bgpmonitoring/type/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * BMP message type components.
+ */
+package org.onosproject.bgpmonitoring.type;
\ No newline at end of file
diff --git a/apps/bgpmonitoring/app/src/test/java/org/onosproject/bgpmonitoring/impl/package-info.java b/apps/bgpmonitoring/app/src/test/java/org/onosproject/bgpmonitoring/impl/package-info.java
new file mode 100644
index 0000000..7a1bb51
--- /dev/null
+++ b/apps/bgpmonitoring/app/src/test/java/org/onosproject/bgpmonitoring/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * BGP monitoring application components test.
+ */
+package org.onosproject.bgpmonitoring.impl;
\ No newline at end of file
diff --git a/apps/bgpmonitoring/app/src/test/java/org/onosproject/bgpmonitoring/type/package-info.java b/apps/bgpmonitoring/app/src/test/java/org/onosproject/bgpmonitoring/type/package-info.java
new file mode 100644
index 0000000..3c2d25f
--- /dev/null
+++ b/apps/bgpmonitoring/app/src/test/java/org/onosproject/bgpmonitoring/type/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * BMP message type components test.
+ */
+package org.onosproject.bgpmonitoring.type;
\ No newline at end of file
diff --git a/tools/build/bazel/modules.bzl b/tools/build/bazel/modules.bzl
index 8452919..0c050fd 100644
--- a/tools/build/bazel/modules.bzl
+++ b/tools/build/bazel/modules.bzl
@@ -224,6 +224,7 @@
     "//apps/mobility:onos-apps-mobility-oar": [],
     "//apps/ipflow-monitor/netflow:onos-apps-ipflow-monitor-netflow-oar": [],
     "//apps/ipflow-monitor/sflow:onos-apps-ipflow-monitor-sflow-oar": [],
+    "//apps/bgpmonitoring:onos-apps-bgpmonitoring-oar": [],
     "//apps/network-troubleshoot:onos-apps-network-troubleshoot-oar": [],
     "//apps/newoptical:onos-apps-newoptical-oar": [],
     "//apps/nodemetrics:onos-apps-nodemetrics-oar": [],