[ONOS-7675] Initial implementation of IntProgrammable

Change-Id: I277ea7a56bb3a38debbb2959823df394a4103541
diff --git a/apps/inbandtelemetry/api/src/main/java/org/onosproject/inbandtelemetry/api/IntConfig.java b/apps/inbandtelemetry/api/src/main/java/org/onosproject/inbandtelemetry/api/IntConfig.java
new file mode 100644
index 0000000..a3e6148
--- /dev/null
+++ b/apps/inbandtelemetry/api/src/main/java/org/onosproject/inbandtelemetry/api/IntConfig.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2015-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.inbandtelemetry.api;
+
+import com.google.common.annotations.Beta;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Network-level INT configuration.
+ */
+@Beta
+public final class IntConfig {
+    /**
+     * Represents a type of telemetry spec to collect in the dataplane.
+     */
+    enum TelemetrySpec {
+        /**
+         * Embeds telemetry metadata according to the INT specification.
+         *
+         * @see <a href="https://github.com/p4lang/p4-applications/blob/master/docs/INT.pdf">
+         *     INT sepcification</a>
+         */
+        INT,
+        /**
+         * Embeds telemetry metadata according to the OAM specification.
+         *
+         * @see <a href="https://tools.ietf.org/html/draft-ietf-ippm-ioam-data">
+         *     Data fields for In-situ OAM</a>
+         */
+        IOAM
+    }
+
+    private final IpAddress collectorIp;
+    private final TpPort collectorPort;
+    private final MacAddress collectorNextHopMac;
+    private final IpAddress sinkIp;
+    private final MacAddress sinkMac;
+    private final TelemetrySpec spec;
+    private boolean enabled;
+
+    private IntConfig(IpAddress collectorIp, TpPort collectorPort, MacAddress collectorNextHopMac,
+                      IpAddress sinkIp, MacAddress sinkMac, TelemetrySpec spec, boolean enabled) {
+        this.collectorIp = collectorIp;
+        this.collectorPort = collectorPort;
+        this.collectorNextHopMac = collectorNextHopMac;
+        this.sinkIp = sinkIp;
+        this.sinkMac = sinkMac;
+        this.spec = spec;
+        this.enabled = enabled;
+    }
+
+    /**
+     * Returns IP address of the collector.
+     * This is the destination IP address that will be used for all INT reports
+     * generated by all sink devices.
+     *
+     * @return collector IP address
+     */
+    public IpAddress collectorIp() {
+        return collectorIp;
+    }
+
+    /**
+     * Returns UDP port number of the collector.
+     * This is the destination UDP port number that will be used for all INT reports
+     * generated by all sink devices.
+     *
+     * @return collector UDP port number
+     */
+    public TpPort collectorPort() {
+        return collectorPort;
+    }
+
+    /**
+     * Returns MAC address of next hop of INT report packets.
+     * This can be either MAC address of the collector or a router.
+     * This is an optional parameter, which means that the usage of this
+     * parameter depends on IntProgrammable implementation.
+     * (e.g., If a report packet needs to be routed to reach the collector,
+     * IntProgrammable will ignore this value and choose next hop router's MAC address.
+     * If a collector itself is the next hop of INT report packets, then
+     * this value will be used as a destination MAC address for all INT report packets.)
+     *
+     * @return MAC address of next hop of INT report packets
+     */
+    public MacAddress collectorNextHopMac() {
+        return collectorNextHopMac;
+    }
+
+    /**
+     * Returns IP address of the sink device.
+     * All sink devices share this address as the source IP address
+     * for all INT reports.
+     *
+     * @return sink device's IP address
+     */
+    public IpAddress sinkIp() {
+        return sinkIp;
+    }
+
+    /**
+     * Returns MAC address of the sink device.
+     * All sink devices share this address as the source MAC address
+     * for all INT reports.
+     *
+     * @return sink device's MAC address
+     */
+    public MacAddress sinkMac() {
+        return sinkMac;
+    }
+
+    /**
+     * Returns the type of telemetry spec as per {@link TelemetrySpec}.
+     *
+     * @return telemetry spec
+     */
+    public TelemetrySpec spec() {
+        return spec;
+    }
+
+    /**
+     * Returns the status of INT functionality.
+     *
+     * @return true if INT is enabled; false otherwise.
+     */
+    public boolean enabled() {
+        return enabled;
+    }
+
+    /**
+     * Returns a new builder.
+     *
+     * @return new builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * An IntConfig object builder.
+     */
+    public static final class Builder {
+
+        private IpAddress collectorIp;
+        private TpPort collectorPort;
+        private MacAddress collectorNextHopMac;
+        private IpAddress sinkIp;
+        private MacAddress sinkMac;
+        private TelemetrySpec spec = TelemetrySpec.INT;
+        private boolean enabled = false;
+
+        /**
+         * Assigns a collector IP address to the IntConfig object.
+         *
+         * @param collectorIp IP address of the collector
+         * @return an IntConfig builder
+         */
+        public IntConfig.Builder withCollectorIp(IpAddress collectorIp) {
+            this.collectorIp = collectorIp;
+            return this;
+        }
+
+        /**
+         * Assigns a collector UDP port to the IntConfig object.
+         *
+         * @param collectorPort UDP port number of the collector
+         * @return an IntConfig builder
+         */
+        public IntConfig.Builder withCollectorPort(TpPort collectorPort) {
+            this.collectorPort = collectorPort;
+            return this;
+        }
+
+        /**
+         * Assigns a MAC address of the next hop to the collector
+         * to the IntConfig object.
+         *
+         * @param collectorNextHopMac MAC address of the collector
+         * @return an IntConfig builder
+         */
+        public IntConfig.Builder withCollectorNextHopMac(MacAddress collectorNextHopMac) {
+            this.collectorNextHopMac = collectorNextHopMac;
+            return this;
+        }
+
+        /**
+         * Assigns an IP address of the sink device to the IntConfig object.
+         *
+         * @param sinkIp sink device's IP address
+         * @return an IntConfig builder
+         */
+        public IntConfig.Builder withSinkIp(IpAddress sinkIp) {
+            this.sinkIp = sinkIp;
+            return this;
+        }
+
+        /**
+         * Assigns a MAC address of the sink device to the IntConfig object.
+         *
+         * @param sinkMac sink device's MAC address
+         * @return an IntConfig builder
+         */
+        public IntConfig.Builder withSinkMac(MacAddress sinkMac) {
+            this.sinkMac = sinkMac;
+            return this;
+        }
+
+        /**
+         * Assigns the type of telemetry spec to the IntConfig object.
+         *
+         * @param spec telemetry spec
+         * @return an IntConfig builder
+         */
+        public IntConfig.Builder withTelemetrySpec(TelemetrySpec spec) {
+            this.spec = spec;
+            return this;
+        }
+
+        /**
+         * Assigns the status of INT.
+         * True to enable INT functionality, false otherwise.
+         *
+         * @param enabled the status of INT
+         * @return an IntConfig builder
+         */
+        public IntConfig.Builder enabled(boolean enabled) {
+            this.enabled = enabled;
+            return this;
+        }
+
+        /**
+         * Builds the IntConfig object.
+         *
+         * @return an IntConfig object
+         */
+        public IntConfig build() {
+            checkNotNull(collectorIp, "Collector IP should be specified.");
+            checkNotNull(collectorPort, "Collector port number should be specified.");
+            checkNotNull(collectorNextHopMac, "Next hop MAC address for report packets should be provided.");
+            checkNotNull(sinkIp, "Sink IP address for report packets should be specified.");
+            checkNotNull(sinkMac, "Sink MAC address for report packets should be specified.");
+            return new IntConfig(collectorIp, collectorPort, collectorNextHopMac,
+                                 sinkIp, sinkMac, spec, enabled);
+        }
+    }
+}