[ONOS-7525]Implement INTService

Change-Id: I525365f89e711420046f31ba363bf0ae6a08c62e
diff --git a/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntConfig.java b/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntConfig.java
new file mode 100644
index 0000000..dc93312
--- /dev/null
+++ b/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntConfig.java
@@ -0,0 +1,247 @@
+/*
+ * 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.onosproject.net.Port;
+
+/**
+ * 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 Port collectorPort;
+    private final MacAddress collectorNextHopMac;
+    private final IpAddress sinkIp;
+    private final MacAddress sinkMac;
+    private final TelemetrySpec spec;
+    private boolean enabled;
+
+    private IntConfig(IpAddress collectorIp, Port 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 Port 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 (P4INT or IOAM).
+     *
+     * @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;
+    }
+
+    /**
+     * An IntConfig object builder.
+     */
+    public static final class Builder {
+
+        private IpAddress collectorIp;
+        private Port 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(Port 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 withEnabled(boolean enabled) {
+            this.enabled = enabled;
+            return this;
+        }
+
+        /**
+         * Bulids the IntConfig object.
+         *
+         * @return an IntConfig object
+         */
+        public IntConfig build() {
+            return new IntConfig(collectorIp, collectorPort, collectorNextHopMac,
+                                 sinkIp, sinkMac, spec, enabled);
+        }
+    }
+}
diff --git a/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntIntent.java b/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntIntent.java
new file mode 100644
index 0000000..4cc1ff2
--- /dev/null
+++ b/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntIntent.java
@@ -0,0 +1,286 @@
+/*
+ * 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.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Represents an INT monitoring intent. Each intent is made up of a traffic slice
+ * to be monitored, as a form of TrafficSelector, types of metadata to collect,
+ * and other required parameters (INT header type, INT Report type, and Telemetry mode).
+ *
+ * IntIntent is converted to a set of flow rules to be installed on each INT-capable
+ * switch in the network, by IntService.
+ *
+ * Terminologies and descriptions are borrowed from INT specification.
+ *
+ * @see <a href="https://github.com/p4lang/p4-applications/blob/master/docs/INT.pdf">
+ *     INT sepcification</a>
+ */
+@Beta
+public final class IntIntent {
+    /**
+     * Represents a type of INT metadata.
+     */
+    public enum IntMetadataType {
+        /**
+         * The unique ID of a switch.
+         */
+        SWITCH_ID,
+        /**
+         * The ports on which the INT packet was received and sent out.
+         */
+        L1_PORT_ID,
+        /**
+         * Time taken for the INT packet to be switched within the device.
+         */
+        HOP_LATENCY,
+        /**
+         * The build-up of traffic in the queue that the INT packet observes
+         * in the device while being forwarded.
+         */
+        QUEUE_OCCUPANCY,
+        /**
+         * The device local time when the INT packet was received on the ingress port.
+         */
+        INGRESS_TIMESTAMP,
+        /**
+         * The device local time when the INT packet was processed by the egress port.
+         */
+        EGRESS_TIMESTAMP,
+        /**
+         * The logical ports on which the INT packet was received and sent out.
+         */
+        L2_PORT_ID,
+        /**
+         * Current utilization of the egress port via witch the INT packet was sent out.
+         */
+        EGRESS_TX_UTIL
+    }
+
+    /**
+     * Represents an INT header type.
+     */
+    public enum IntHeaderType {
+        /**
+         * Intemediate devices must process this type of INT header.
+         */
+        HOP_BY_HOP,
+        /**
+         * Intemediate devices must ignore this type of INT header.
+         */
+        DESTINATION
+    }
+
+    /**
+     * Represents a type of telemetry report.
+     */
+    public enum IntReportType {
+        /**
+         * Report for flows matching certain definitions.
+         */
+        TRACKED_FLOW,
+        /**
+         * Reports for all dropeed packets matching a drop watchlist.
+         */
+        DROPPED_PACKET,
+        /**
+         * Reports for traffic entering a specific queue during a period of queue congestion.
+         */
+        CONGESTED_QUEUE
+    }
+
+    /**
+     * Represents telemetry mode.
+     */
+    public enum TelemetryMode {
+        /**
+         * Each network device generates its own telemetry reports.
+         */
+        POSTCARD,
+        /**
+         * Telemetry metadata is embedded in between the original
+         * headers of data packets as they traverse the network.
+         */
+        INBAND_TELEMETRY
+    }
+
+    private static final int DEFAULT_PRIORITY = 10;
+
+    // TrafficSelector to describe target flows to monitor
+    private final TrafficSelector selector;
+    // set of metadata type to collect
+    private final Set<IntMetadataType> metadataTypes;
+    // hop-by-hop or destination
+    private final IntHeaderType headerType;
+    // telemetry report types
+    private final Set<IntReportType> reportTypes;
+    // telemetry mode
+    private final TelemetryMode telemetryMode;
+
+    /**
+     * Creates an IntIntent.
+     *
+     * @param selector      the traffic selector that identifies traffic to enable INT
+     * @param metadataTypes the types of metadata to collect
+     * @param headerType    the type of INT header
+     * @param reportTypes   the types of report to be generated
+     * @param telemetryMode the telemetry mode
+     */
+    private IntIntent(TrafficSelector selector, Set<IntMetadataType> metadataTypes,
+                      IntHeaderType headerType, Set<IntReportType> reportTypes,
+                      TelemetryMode telemetryMode) {
+        this.selector = selector;
+        this.metadataTypes = new HashSet<>(metadataTypes);
+        this.headerType = headerType;
+        this.reportTypes = new HashSet<>(reportTypes);
+        this.telemetryMode = telemetryMode;
+    }
+
+    /**
+     * Returns traffic selector of this intent.
+     *
+     * @return traffic selector
+     */
+    public TrafficSelector selector() {
+        return selector;
+    }
+
+    /**
+     * Returns a set of metadata type to be collected by this intent.
+     *
+     * @return set of metadata type
+     */
+    public Set<IntMetadataType> metadataTypes() {
+        return metadataTypes;
+    }
+
+    /**
+     * Returns a INT header type specified in this intent.
+     *
+     * @return INT header type
+     */
+    public IntHeaderType headerType() {
+        return headerType;
+    }
+
+    /**
+     * Returns a set of report type to be generated.
+     *
+     * @return set of report type
+     */
+    public Set<IntReportType> reportTypes() {
+        return reportTypes;
+    }
+
+    /**
+     * Returns a telemetry mode specified in this intent.
+     *
+     * @return telemtry mode
+     */
+    public TelemetryMode telemetryMode() {
+        return telemetryMode;
+    }
+
+    /**
+     * An IntIntent builder.
+     */
+    public static final class Builder {
+        private TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        private Set<IntMetadataType> metadataTypes = new HashSet<>();
+        private IntHeaderType headerType = IntHeaderType.HOP_BY_HOP;
+        private Set<IntReportType> reportTypes = new HashSet<>();
+        private TelemetryMode telemetryMode = TelemetryMode.INBAND_TELEMETRY;
+
+        /**
+         * Assigns a selector to the IntIntent.
+         *
+         * @param selector a traffic selector
+         * @return an IntIntent builder
+         */
+        public IntIntent.Builder withSelector(TrafficSelector selector) {
+            this.selector = selector;
+            return this;
+        }
+
+        /**
+         * Add a metadata type to the IntIntent.
+         *
+         * @param metadataType a type of metadata to collect
+         * @return an IntIntent builder
+         */
+        public IntIntent.Builder withMetadataType(IntMetadataType metadataType) {
+            this.metadataTypes.add(metadataType);
+            return this;
+        }
+
+        /**
+         * Assigns a header type to the IntIntent.
+         *
+         * @param headerType a header type
+         * @return an IntIntent builder
+         */
+        public IntIntent.Builder withHeaderType(IntHeaderType headerType) {
+            this.headerType = headerType;
+            return this;
+        }
+
+        /**
+         * Add a report type to the IntIntent.
+         *
+         * @param reportType a type of report
+         * @return an IntIntent builder
+         */
+        public IntIntent.Builder withReportType(IntReportType reportType) {
+            this.reportTypes.add(reportType);
+            return this;
+        }
+
+        /**
+         * Assigns a telemetry mode to the IntIntent.
+         *
+         * @param telemetryMode a telemetry mode
+         * @return an IntIntent builder
+         */
+        public IntIntent.Builder withTelemetryMode(TelemetryMode telemetryMode) {
+            this.telemetryMode = telemetryMode;
+            return this;
+        }
+
+        /**
+         * Builds the IntIntent.
+         *
+         * @return an IntIntent
+         */
+        public IntIntent build() {
+            checkArgument(!selector.criteria().isEmpty(), "Empty selector cannot match any flow.");
+            checkArgument(!metadataTypes.isEmpty(), "Metadata types cannot be empty.");
+            checkNotNull(headerType, "Header type cannot be null.");
+            checkNotNull(!reportTypes.isEmpty(), "Report types cannot be empty.");
+            checkNotNull(telemetryMode, "Telemetry mode cannot be null.");
+
+            return new IntIntent(selector, metadataTypes, headerType, reportTypes, telemetryMode);
+        }
+    }
+}
diff --git a/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntService.java b/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntService.java
new file mode 100644
index 0000000..a666a1b
--- /dev/null
+++ b/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/IntService.java
@@ -0,0 +1,111 @@
+/*
+ * 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.onosproject.net.DeviceId;
+
+import java.util.Set;
+
+/**
+ * Service for controlling INT-capable pipelines.
+ */
+@Beta
+public interface IntService {
+    /**
+     * Represents the role of INT-capable devices.
+     */
+    enum IntDeviceRole {
+        /**
+         * Intermediate device to add its own INT metadata to an INT packet by
+         * following the INT instruction in the INT header.
+         */
+        TRANSIT,
+        /**
+         * A device that creates, inserts INT headers into the packet, and
+         * extracts the INT headers.
+         */
+        SOURCE_SINK
+    }
+
+    /**
+     * Starts the INT functionalities in all INT-capable devices.
+     * This will include populating tables to process INT packets.
+     */
+    void startInt();
+
+    /**
+     * Starts the INT functionalities in specified set of INT transit devices.
+     * <p>
+     * Note: this is an experimental API, which can be either changed or removed.
+     *
+     * @param transitDevices set of devices to start INT functionalities
+     */
+    void startInt(Set<DeviceId> transitDevices);
+
+    /**
+     * Stops the INT functionalities in all INT-capable devices.
+     */
+    void stopInt();
+
+    /**
+     * Stops the INT functionalities in specified set of INT transit devices.
+     * <p>
+     * Note: this is an experimental API, which can be either changed or removed.
+     *
+     * @param transitDevices set of devices to stop INT functionalities
+     */
+    void stopInt(Set<DeviceId> transitDevices);
+
+    /**
+     * Configures all INT-capable devices with given configuration.
+     *
+     * @param cfg configuration to set up
+     */
+    void setConfig(IntConfig cfg);
+
+    /**
+     * Retrieves the INT configuration.
+     *
+     * @return configuration
+     */
+    IntConfig getConfig();
+
+    /**
+     * Installs an IntIntent to devices.
+     *
+     * @param intIntent an IntIntent
+     * @return an ID corresponding to given intIntent
+     */
+    int installIntIntent(IntIntent intIntent);
+
+    /**
+     * Removes an IntIntent from devices.
+     *
+     * @param intentId ID of the intIntent to remove
+     */
+    void removeIntIntent(int intentId);
+
+    /**
+     * Returns an intIntent for given intent ID.
+     *
+     * @param intentId id of the intIntent to retrieve
+     * @return an IntIntent
+     */
+    IntIntent getIntIntent(int intentId);
+
+    //TODO: [ONOS-7616] Design IntEvent and related APIs
+}
\ No newline at end of file
diff --git a/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/package-info.java b/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/package-info.java
new file mode 100644
index 0000000..9e80ee5
--- /dev/null
+++ b/apps/inbandtelemetry/intmgr/src/main/java/org/onosproject/inbandtelemetry/api/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Service to control a network of devices capable of collecting and exporting
+ * data plane telemetry via in-band mechanism.
+ */
+package org.onosproject.inbandtelemetry.api;