AETHER-233 Move IntProgrammable behavior to core APIs

Before, the behavior interface and other concrete classes used it by
were part of the inbandtelemetry app. To make this behavior available to
third-party apps (such as the fabric-tna pipeconf), we move it to the
core APIs.

In this process, we do some clean-up of the behavior API. For example,
we remove references to network-level semantics (as behaviors should
only abstract device-level ones). That helps in reducing the number of
classes required to maintain in the core.

Change-Id: I3ba24ea93cdfea115cee454d5e921e15ec17eee9
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntDeviceConfig.java b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntDeviceConfig.java
new file mode 100644
index 0000000..c77b7bd
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntDeviceConfig.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.net.behaviour.inbandtelemetry;
+
+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;
+
+/**
+ * Device-level configuration of the INT process.
+ */
+@Beta
+public final class IntDeviceConfig {
+    /**
+     * Represents a type of telemetry spec to collect in the dataplane.
+     */
+    public 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 IntDeviceConfig(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 IntDeviceConfig.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 IntDeviceConfig.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 IntDeviceConfig.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 IntDeviceConfig.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 IntDeviceConfig.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 IntDeviceConfig.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 IntDeviceConfig.Builder enabled(boolean enabled) {
+            this.enabled = enabled;
+            return this;
+        }
+
+        /**
+         * Builds the IntConfig object.
+         *
+         * @return an IntConfig object
+         */
+        public IntDeviceConfig 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 IntDeviceConfig(collectorIp, collectorPort, collectorNextHopMac,
+                                 sinkIp, sinkMac, spec, enabled);
+        }
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntMetadataType.java b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntMetadataType.java
new file mode 100644
index 0000000..fec5a17
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntMetadataType.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020-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.net.behaviour.inbandtelemetry;
+
+/**
+ * Represents a type of INT metadata.
+ */
+public enum IntMetadataType {
+    /**
+     * ID of a switch, unique in the scope of the whole network.
+     */
+    SWITCH_ID,
+    /**
+     * The port 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
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntObjective.java b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntObjective.java
new file mode 100644
index 0000000..b73e9c2
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntObjective.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2018-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.net.behaviour.inbandtelemetry;
+
+import com.google.common.collect.ImmutableSet;
+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;
+
+/**
+ * Represents a device-level objective to collect INT metadata for packets
+ * identified by a traffic selector.
+ */
+public final class IntObjective {
+
+    private static final int DEFAULT_PRIORITY = 10;
+
+    // TrafficSelector to describe target flows to monitor
+    private final TrafficSelector selector;
+    // Set of metadata types to collect
+    private final ImmutableSet<IntMetadataType> metadataTypes;
+
+    /**
+     * Creates an IntObjective.
+     *
+     * @param selector      the traffic selector that identifies traffic to enable INT
+     * @param metadataTypes a set of metadata types to collect
+     */
+    private IntObjective(TrafficSelector selector, Set<IntMetadataType> metadataTypes) {
+        this.selector = selector;
+        this.metadataTypes = ImmutableSet.copyOf(metadataTypes);
+    }
+
+    /**
+     * Returns traffic selector of this objective.
+     *
+     * @return traffic selector
+     */
+    public TrafficSelector selector() {
+        return selector;
+    }
+
+    /**
+     * Returns a set of metadata types specified in this objective.
+     *
+     * @return instruction bitmap
+     */
+    public Set<IntMetadataType> metadataTypes() {
+        return metadataTypes;
+    }
+
+    /**
+     * An IntObjective builder.
+     */
+    public static final class Builder {
+        private TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        private final Set<IntMetadataType> metadataTypes = new HashSet<>();
+
+        /**
+         * Assigns a selector to the IntObjective.
+         *
+         * @param selector a traffic selector
+         * @return an IntObjective builder
+         */
+        public IntObjective.Builder withSelector(TrafficSelector selector) {
+            this.selector = selector;
+            return this;
+        }
+
+        /**
+         * Add a metadata type to the IntObjective.
+         *
+         * @param metadataTypes a set of metadata types
+         * @return an IntObjective builder
+         */
+        public IntObjective.Builder withMetadataTypes(Set<IntMetadataType> metadataTypes) {
+            this.metadataTypes.addAll(metadataTypes);
+            return this;
+        }
+
+        /**
+         * Builds the IntObjective.
+         *
+         * @return an IntObjective
+         */
+        public IntObjective build() {
+            checkArgument(!selector.criteria().isEmpty(), "Empty selector cannot match any flow.");
+            checkArgument(!metadataTypes.isEmpty(), "Metadata types cannot be empty");
+
+            return new IntObjective(selector, metadataTypes);
+        }
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntProgrammable.java b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntProgrammable.java
new file mode 100644
index 0000000..5560e8c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/IntProgrammable.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2018-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.net.behaviour.inbandtelemetry;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.HandlerBehaviour;
+
+/**
+ * Abstraction of a device implementing In-band Network Telemetry (INT)
+ * capabilities.
+ */
+@Beta
+public interface IntProgrammable extends HandlerBehaviour {
+
+    /**
+     * INT functionalities that a device can implement.
+     */
+    enum IntFunctionality {
+        /**
+         * Source functionality.
+         */
+        SOURCE,
+        /**
+         * Sink functionality.
+         */
+        SINK,
+        /**
+         * Transit functionality.
+         */
+        TRANSIT
+    }
+
+    /**
+     * Initializes the pipeline, by installing required flow rules not relevant
+     * to specific watchlist, report and event. Returns true if the operation
+     * was successful, false otherwise.
+     *
+     * @return true if successful, false otherwise
+     */
+    boolean init();
+
+    /**
+     * Configures the given port as an INT source port. Packets received via
+     * this port can be modified to add the INT header, if a corresponding INT
+     * objective is matched. Returns true if the operation was successful, false
+     * otherwise.
+     *
+     * @param port port
+     * @return true if successful, false otherwise
+     */
+    boolean setSourcePort(PortNumber port);
+
+    /**
+     * Configures the given port as an INT sink port. Packets forwarded via this
+     * port will be stripped of the INT header and a corresponding INT report
+     * will be generated. Returns true if the operation was successful, false
+     * otherwise.
+     *
+     * @param port port
+     * @return true if successful, false otherwise
+     */
+    boolean setSinkPort(PortNumber port);
+
+    /**
+     * Adds a given IntObjective to the device.
+     *
+     * @param obj an IntObjective
+     * @return true if the objective was successfully added; false otherwise.
+     */
+    boolean addIntObjective(IntObjective obj);
+
+    /**
+     * Removes a given IntObjective entry from the device.
+     *
+     * @param obj an IntObjective
+     * @return true if the objective was successfully removed; false otherwise.
+     */
+    boolean removeIntObjective(IntObjective obj);
+
+    /**
+     * Set up report-related configuration.
+     *
+     * @param config a configuration regarding to the collector
+     * @return true if the objective is successfully added; false otherwise.
+     */
+    boolean setupIntConfig(IntDeviceConfig config);
+
+    /**
+     * Clean up any INT-related configuration from the device.
+     */
+    void cleanup();
+
+    /**
+     * Returns true if this device supports the given INT functionality.
+     *
+     * @param functionality INt functionality
+     * @return true if functionality is supported, false otherwise
+     */
+    boolean supportsFunctionality(IntFunctionality functionality);
+
+    //TODO: [ONOS-7616] Design IntEvent and related APIs
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/package-info.java b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/package-info.java
new file mode 100644
index 0000000..fcbdf71
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/inbandtelemetry/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Behaviors abstracting devices supporting in-band network telemetry.
+ */
+package org.onosproject.net.behaviour.inbandtelemetry;