Small INT app and UI improvements

[INT App]
 - Load INT report config when activate the app
 - Remove config listener and config factory from app when deactivate
 - Check INT intent map before remove a INT intent
 - Add more check to check the input from frontend UI
 - Change log level of UI message handler from info to debug

[GUI1]
 - Reformat CSS code
 - Remove '$scope.sendIntConfigString' which breaks the UI
 - Fix regular expression that matches IP prefix
 - Remove "required" attribute from all field
 - Add additional check to prevent sending invalid input to backend
 - Use 'let' instead of 'var' to limit the scope of variable
 - Make INT button aligned with other elements
 - Show message if any field is invalid

[GUI2]
 - Remove INT collector config panel
 - Reformat HTML code
 - Fix regular expression which matches the IP prefix

[API]
 - Add default value '0' for all fields in INT device config
 - Skip checking the metadata types when building the IntObjective since
   some pipeline won't need it

Change-Id: Ica260c35d411336419f77eb0de5787e943dc1887
diff --git a/apps/inbandtelemetry/api/src/main/java/org/onosproject/inbandtelemetry/api/IntIntent.java b/apps/inbandtelemetry/api/src/main/java/org/onosproject/inbandtelemetry/api/IntIntent.java
index 6e2e92b..8ce9d0f 100644
--- a/apps/inbandtelemetry/api/src/main/java/org/onosproject/inbandtelemetry/api/IntIntent.java
+++ b/apps/inbandtelemetry/api/src/main/java/org/onosproject/inbandtelemetry/api/IntIntent.java
@@ -247,7 +247,6 @@
          */
         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.");
             checkArgument(!reportTypes.isEmpty(), "Report types cannot be empty.");
             checkNotNull(telemetryMode, "Telemetry mode cannot be null.");
diff --git a/apps/inbandtelemetry/app/src/main/java/org/onosproject/inbandtelemetry/app/ui/IntAppUiMessageHandler.java b/apps/inbandtelemetry/app/src/main/java/org/onosproject/inbandtelemetry/app/ui/IntAppUiMessageHandler.java
index 9d1fb90..af47755 100644
--- a/apps/inbandtelemetry/app/src/main/java/org/onosproject/inbandtelemetry/app/ui/IntAppUiMessageHandler.java
+++ b/apps/inbandtelemetry/app/src/main/java/org/onosproject/inbandtelemetry/app/ui/IntAppUiMessageHandler.java
@@ -18,6 +18,7 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.collect.ImmutableSet;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.IPv4;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.TpPort;
@@ -60,10 +61,8 @@
 
         @Override
         public void process(ObjectNode payload) {
-            log.info("intIntentDelRequest: {}", payload);
-
+            log.debug("intIntentDelRequest: {}", payload);
             intService = get(IntService.class);
-
             if (payload.get("intentId") != null) {
                 intService.removeIntIntent(IntIntentId.valueOf(payload.get("intentId").asLong()));
             }
@@ -77,66 +76,80 @@
 
         @Override
         public void process(ObjectNode payload) {
-            log.info("intIntentAddRequest: {}", payload);
+            log.debug("intIntentAddRequest: {}", payload);
 
             intService = get(IntService.class);
 
             TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
             IntIntent.Builder builder = IntIntent.builder();
 
-            if (payload.get("ip4SrcPrefix") != null) {
-                sBuilder.matchIPSrc(parseIp4Prefix(payload.get("ip4SrcPrefix").asText()));
+            JsonNode jsonNodeVal = payload.get("ip4SrcPrefix");
+            if (jsonNodeVal != null && !jsonNodeVal.asText().isEmpty()) {
+                sBuilder.matchIPSrc(parseIp4Prefix(jsonNodeVal.asText()));
             }
 
-            if (payload.get("ip4DstPrefix") != null) {
-                sBuilder.matchIPDst(parseIp4Prefix(payload.get("ip4DstPrefix").asText()));
+            jsonNodeVal = payload.get("ip4DstPrefix");
+            if (jsonNodeVal != null && !jsonNodeVal.asText().isEmpty()) {
+                sBuilder.matchIPDst(parseIp4Prefix(jsonNodeVal.asText()));
             }
 
-            if (payload.get("l4SrcPort") != null) {
-                if (payload.get("protocol") != null && payload.get("protocol").asText().equalsIgnoreCase("TCP")) {
-                    sBuilder.matchTcpSrc(TpPort.tpPort(payload.get("l4SrcPort").asInt()));
-                } else {
-                    sBuilder.matchUdpSrc(TpPort.tpPort(payload.get("l4SrcPort").asInt()));
+            jsonNodeVal = payload.get("protocol");
+            byte ipProtocol = 0;
+            if (jsonNodeVal != null) {
+                if (jsonNodeVal.asText().equalsIgnoreCase("TCP")) {
+                    ipProtocol = IPv4.PROTOCOL_TCP;
+                } else if (jsonNodeVal.asText().equalsIgnoreCase("UDP")) {
+                    ipProtocol = IPv4.PROTOCOL_UDP;
                 }
             }
 
-            if (payload.get("l4DstPort") != null) {
-                if (payload.get("protocol") != null && payload.get("protocol").asText().equalsIgnoreCase("TCP")) {
-                    sBuilder.matchTcpDst(TpPort.tpPort(payload.get("l4DstPort").asInt()));
-                } else {
-                    sBuilder.matchUdpDst(TpPort.tpPort(payload.get("l4DstPort").asInt()));
+            jsonNodeVal = payload.get("l4SrcPort");
+            if (jsonNodeVal != null) {
+                int portNo = jsonNodeVal.asInt(0);
+                if (portNo != 0 && ipProtocol == IPv4.PROTOCOL_TCP) {
+                    sBuilder.matchTcpSrc(TpPort.tpPort(portNo));
+                } else if (portNo != 0 && ipProtocol == IPv4.PROTOCOL_UDP) {
+                    sBuilder.matchUdpSrc(TpPort.tpPort(portNo));
                 }
             }
 
-            if (payload.get("metadata") != null) {
-                JsonNode meta = payload.get("metadata");
-                if (meta.isArray()) {
-                    for (final JsonNode json : meta) {
-                        switch (json.asText()) {
-                            case "SWITCH_ID":
-                                builder.withMetadataType(IntMetadataType.SWITCH_ID);
-                                break;
-                            case "PORT_ID":
-                                builder.withMetadataType(IntMetadataType.L1_PORT_ID);
-                                break;
-                            case "HOP_LATENCY":
-                                builder.withMetadataType(IntMetadataType.HOP_LATENCY);
-                                break;
-                            case "QUEUE_OCCUPANCY":
-                                builder.withMetadataType(IntMetadataType.QUEUE_OCCUPANCY);
-                                break;
-                            case "INGRESS_TIMESTAMP":
-                                builder.withMetadataType(IntMetadataType.INGRESS_TIMESTAMP);
-                                break;
-                            case "EGRESS_TIMESTAMP":
-                                builder.withMetadataType(IntMetadataType.EGRESS_TIMESTAMP);
-                                break;
-                            case "EGRESS_TX_UTIL":
-                                builder.withMetadataType(IntMetadataType.EGRESS_TX_UTIL);
-                                break;
-                            default:
-                                break;
-                        }
+            jsonNodeVal = payload.get("l4DstPort");
+            if (jsonNodeVal != null) {
+                int portNo = jsonNodeVal.asInt(0);
+                if (portNo != 0 && ipProtocol == IPv4.PROTOCOL_TCP) {
+                    sBuilder.matchTcpDst(TpPort.tpPort(portNo));
+                } else if (portNo != 0 && ipProtocol == IPv4.PROTOCOL_UDP) {
+                    sBuilder.matchUdpDst(TpPort.tpPort(portNo));
+                }
+            }
+
+            jsonNodeVal = payload.get("metadata");
+            if (jsonNodeVal != null && jsonNodeVal.isArray()) {
+                for (final JsonNode json : jsonNodeVal) {
+                    switch (json.asText()) {
+                        case "SWITCH_ID":
+                            builder.withMetadataType(IntMetadataType.SWITCH_ID);
+                            break;
+                        case "PORT_ID":
+                            builder.withMetadataType(IntMetadataType.L1_PORT_ID);
+                            break;
+                        case "HOP_LATENCY":
+                            builder.withMetadataType(IntMetadataType.HOP_LATENCY);
+                            break;
+                        case "QUEUE_OCCUPANCY":
+                            builder.withMetadataType(IntMetadataType.QUEUE_OCCUPANCY);
+                            break;
+                        case "INGRESS_TIMESTAMP":
+                            builder.withMetadataType(IntMetadataType.INGRESS_TIMESTAMP);
+                            break;
+                        case "EGRESS_TIMESTAMP":
+                            builder.withMetadataType(IntMetadataType.EGRESS_TIMESTAMP);
+                            break;
+                        case "EGRESS_TX_UTIL":
+                            builder.withMetadataType(IntMetadataType.EGRESS_TX_UTIL);
+                            break;
+                        default:
+                            break;
                     }
                 }
             }
diff --git a/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.css b/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.css
index 7c2bbe2..5ee2332 100644
--- a/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.css
+++ b/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.css
@@ -3,15 +3,17 @@
 #ov-int-app-main {
     padding: 20px;
 }
+
 .light #ov-int-app-main {
     color: navy;
 }
+
 .dark #ov-int-app-main {
     color: #88f;
 }
 
 #ov-int-app-main .button-panel {
-    margin: 10px;
+    margin-top: 15px;
     width: 200px;
 }
 
@@ -29,11 +31,11 @@
     text-align: center;
 }
 
-
 .light #ov-int-app-main .int-app-button {
     color: white;
     background-color: #99d;
 }
+
 .dark #ov-int-app-main .int-app-button {
     color: black;
     background-color: #aaa;
@@ -67,10 +69,16 @@
     color: white;
     background-color: #99d;
 }
+
 .dark #ov-int-app-main .int-app-config-button {
     color: black;
     background-color: #aaa;
 }
+
+#ov-int-app-main .tabular-header {
+    padding-left: 10px;
+}
+
 /*---------------------------------------------------------------------------*/
 #ov-int-app-main hr {
     border: 0;
@@ -92,6 +100,7 @@
     display: inline-block;
     margin-bottom: 10px;
 }
+
 /* #ov-int-app-main .table-body{
     display: inline-block;
     overflow-y: scroll;
@@ -107,6 +116,7 @@
 .light #ov-int-app-main-item-details-panel.floatpanel {
     background-color: rgb(229, 234, 237);
 }
+
 .dark #ov-int-app-main-item-details-panel.floatpanel {
     background-color: #3A4042;
 }
@@ -123,7 +133,12 @@
 #ov-int-app-main-item-details-panel td {
     padding: 5px;
 }
+
 #ov-int-app-main-item-details-panel td.label {
     font-style: italic;
     opacity: 0.8;
 }
+
+#ov-int-app-main p .int-intent-add-msg {
+    color: red;
+}
diff --git a/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.html b/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.html
index 44698dd..a2d3b88 100644
--- a/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.html
+++ b/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.html
@@ -19,32 +19,29 @@
                 </h3>
                 <div>
                     <label>
-                        <input placeholder="Source IP address" type="text"
-                               required
-                               pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}(/[0-9]{1,2})?$"
+                        <input placeholder="Source IP prefix" type="text"
+                               pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?$"
                                ng-model="ip4SrcPrefix">
                     </label>
                     <label>
-                        <input placeholder="Dest IP address" type="text"
-                               required
-                               pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}(/[0-9]{1,2})?$"
+                        <input placeholder="Dest IP prefix" type="text"
+                               pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?$"
                                ng-model="ip4DstPrefix">
                     </label>
                     <label>
-                        <input placeholder="Source port" type="text" required
+                        <input placeholder="Source port" type="text"
                                pattern="^[0-9]{0,5}$"
                                ng-model="l4SrcPort">
                     </label>
                     <label>
-                        <input placeholder="Dest port" type="text" required
+                        <input placeholder="Destination port" type="text"
                                pattern="^[0-9]{0,5}$"
                                ng-model="l4DstPort">
                     </label>
                     <label>
                         Protocol
                         <select name="protocol" ng-model="protocol">
-                            <option selected disabled hidden
-                                    style="display: none" value=''></option>
+                            <option value=""></option>
                             <option value="TCP">TCP</option>
                             <option value="UDP">UDP</option>
                         </select>
@@ -88,6 +85,11 @@
                 Apply Watchlist Rule
             </div>
         </div>
+        <div>
+            <p class="int-intent-add-msg">
+                {{intAddMsg}}
+            </p>
+        </div>
     </div>
     <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
     <div class='int-app-main-intents'>
diff --git a/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.js b/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.js
index efcb3b4..f8913a0 100644
--- a/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.js
+++ b/apps/inbandtelemetry/app/src/main/resources/app/view/intApp/intApp.js
@@ -2,19 +2,73 @@
     'use strict';
 
     // injected refs
-    var $log, $scope, $interval, $timeout, fs, wss, ks, ls;
+    let $log, $scope, $interval, $timeout, fs, wss, ks, ls;
 
     // constants
-    var intIntentAddReq = 'intIntentAddRequest';
-    var intIntentDelReq = 'intIntentDelRequest';
+    let intIntentAddReq = 'intIntentAddRequest';
+    let intIntentDelReq = 'intIntentDelRequest';
 
-    var refreshInterval = 1000;
+    let refreshInterval = 1000;
 
-    var propOrder = ['id', 'srcAddr', 'dstAddr', 'srcPort', 'dstPort', 'insMask'];
-    var friendlyProps = ['IntIntent ID', 'Src Address', 'Dst Address', 'Src Port', 'Dst Port', 'Ins Mask'];
+    let propOrder = ['id', 'srcAddr', 'dstAddr', 'srcPort', 'dstPort', 'insMask'];
+    let friendlyProps = ['IntIntent ID', 'Src Address', 'Dst Address', 'Src Port', 'Dst Port', 'Ins Mask'];
+
+    function checkArgAndShowMsg() {
+        // Need to match at least one field
+        if ($scope.ip4SrcPrefix === "" &&
+            $scope.ip4DstPrefix === "" &&
+            $scope.l4SrcPort === "" &&
+            $scope.l4DstPort === "" ) {
+            $scope.intAddMsg = "Nothing installed since there is no matching spec.";
+            return false;
+        }
+        // IP address validation
+        let ipv4Pattern = /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?$/;
+        if ($scope.ip4SrcPrefix !== "" && !ipv4Pattern.test($scope.ip4SrcPrefix)) {
+            $scope.intAddMsg = "Invalid source IP.";
+            return false;
+        }
+        if ($scope.ip4DstPrefix !== "" && !ipv4Pattern.test($scope.ip4DstPrefix)) {
+            $scope.intAddMsg = "Invalid destination IP.";
+            return false;
+        }
+        // L4 port validation
+        if ($scope.l4SrcPort !== "") {
+            let l4SrcPort = parseInt($scope.l4SrcPort);
+            if (isNaN(l4SrcPort)) {
+                $scope.intAddMsg = "Invalid source port number.";
+                return false;
+            }
+            if (l4SrcPort <= 0 || l4SrcPort > 65535) {
+                $scope.intAddMsg = "Invalid source port number.";
+                return false;
+            }
+            if ($scope.protocol === "") {
+                $scope.intAddMsg = "protocol cannot be empty.";
+                return false;
+            }
+        }
+        if ($scope.l4DstPort !== "") {
+            let l4DstPort = parseInt($scope.l4DstPort);
+            if (isNaN(l4DstPort)) {
+                $scope.intAddMsg = "Invalid destination port number.";
+                return false;
+            }
+            if (l4DstPort <= 0 || l4DstPort > 65535) {
+                $scope.intAddMsg = "Invalid destination port number.";
+                return false;
+            }
+            if ($scope.protocol === "") {
+                $scope.intAddMsg = "protocol cannot be empty.";
+                return false;
+            }
+        }
+        $scope.intAddMsg = "";
+        return true;
+    }
 
     function sendIntIntentString() {
-        var inst = [];
+        let inst = [];
         if ($scope.metaSwId) inst.push("SWITCH_ID");
         if ($scope.metaPortId) inst.push("PORT_ID");
         if ($scope.metaHopLatency) inst.push("HOP_LATENCY");
@@ -23,7 +77,7 @@
         if ($scope.metaEgressTstamp) inst.push("EGRESS_TIMESTAMP");
         if ($scope.metaEgressTx) inst.push("EGRESS_TX_UTIL");
 
-        var intentObjectNode = {
+        let intentObjectNode = {
             "ip4SrcPrefix": $scope.ip4SrcPrefix,
             "ip4DstPrefix": $scope.ip4DstPrefix,
             "l4SrcPort": $scope.l4SrcPort,
@@ -31,7 +85,9 @@
             "protocol": $scope.protocol,
             "metadata": inst
         };
-        wss.sendEvent(intIntentAddReq, intentObjectNode);
+        if (checkArgAndShowMsg()) {
+            wss.sendEvent(intIntentAddReq, intentObjectNode);
+        }
     }
 
     function delIntIntent() {
@@ -43,7 +99,7 @@
     }
 
     function intIntentBuildTable(o) {
-        var handlers = {},
+        let handlers = {},
             root = o.tag + 's',
             req = o.tag + 'DataRequest',
             resp = o.tag + 'DataResponse',
@@ -86,7 +142,7 @@
 
         // request
         function sortCb(params) {
-            var p = angular.extend({}, params, o.query);
+            let p = angular.extend({}, params, o.query);
             if (wss.isConnected()) {
                 wss.sendEvent(req, p);
                 ls.start();
@@ -96,7 +152,7 @@
 
         // === selecting a row functions ----------------
         function selCb($event, selRow) {
-            var selId = selRow[idKey];
+            let selId = selRow[idKey];
             o.scope.selId = (o.scope.selId === selId) ? null : selId;
             onSel && onSel($event, selRow);
         }
@@ -140,7 +196,7 @@
         startRefresh();
     }
 
-    var app1 = angular.module('ovIntApp', []);
+    let app1 = angular.module('ovIntApp', []);
     app1.controller('OvIntAppCtrl',
         ['$log', '$scope', '$interval', '$timeout', 'TableBuilderService',
             'FnService', 'WebSocketService', 'KeyService', 'LoadingService',
@@ -166,7 +222,12 @@
 
                 $scope.sendIntIntentString = sendIntIntentString;
                 $scope.delIntIntent = delIntIntent;
-                $scope.sendIntConfigString = sendIntConfigString;
+                $scope.intAddMsg = "";
+                $scope.ip4SrcPrefix = "";
+                $scope.ip4DstPrefix = "";
+                $scope.l4SrcPort = "";
+                $scope.l4DstPort = "";
+                $scope.protocol = "";
 
                 // get data the first time...
                 // getData();
diff --git a/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/SimpleIntManager.java b/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/SimpleIntManager.java
index 48a7a24..8506a40 100644
--- a/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/SimpleIntManager.java
+++ b/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/SimpleIntManager.java
@@ -210,9 +210,20 @@
 
         netcfgRegistry.registerConfigFactory(intAppConfigFactory);
         netcfgService.addListener(appConfigListener);
+        // Initialize the INT report
+        IntReportConfig reportConfig = netcfgService.getConfig(appId, IntReportConfig.class);
+        if (reportConfig != null) {
+            IntDeviceConfig intDeviceConfig = IntDeviceConfig.builder()
+                    .withMinFlowHopLatencyChangeNs(reportConfig.minFlowHopLatencyChangeNs())
+                    .withCollectorPort(reportConfig.collectorPort())
+                    .withCollectorIp(reportConfig.collectorIp())
+                    .enabled(true)
+                    .build();
+            setConfig(intDeviceConfig);
+        }
 
         startInt();
-        log.info("Started", appId.id());
+        log.info("Started");
     }
 
     @Deactivate
@@ -242,6 +253,8 @@
         });
         // Clean up INT rules from existing devices.
         deviceService.getDevices().forEach(d -> cleanupDevice(d.id()));
+        netcfgService.removeListener(appConfigListener);
+        netcfgRegistry.unregisterConfigFactory(intAppConfigFactory);
         log.info("Deactivated");
     }
 
@@ -293,7 +306,11 @@
     public void removeIntIntent(IntIntentId intentId) {
         checkNotNull(intentId);
         // Intent map event will trigger device configure.
-        intentMap.remove(intentId).value();
+        if (!intentMap.containsKey(intentId)) {
+            log.warn("INT intent {} does not exists, skip removing the intent.", intentId);
+            return;
+        }
+        intentMap.remove(intentId);
     }
 
     @Override
diff --git a/apps/inbandtelemetry/int-gui2-lib/projects/int-gui2-lib/src/lib/intapp/intapp.component.html b/apps/inbandtelemetry/int-gui2-lib/projects/int-gui2-lib/src/lib/intapp/intapp.component.html
index c1fe049..0196aef 100644
--- a/apps/inbandtelemetry/int-gui2-lib/projects/int-gui2-lib/src/lib/intapp/intapp.component.html
+++ b/apps/inbandtelemetry/int-gui2-lib/projects/int-gui2-lib/src/lib/intapp/intapp.component.html
@@ -18,118 +18,97 @@
         <h2 style="font-weight: bold">In-band Network Telemetry (INT) Control
             Application</h2>
     </div>
-
     <hr>
-
     <div class="tabular-header">
         <h2>
-            INT Collector Configuration
+            INT Watchlist Rules
         </h2>
-        <div class="config-panel">
-            <h3>
-                Collector IPv4 address and UDP port
-            </h3>
-            <form [formGroup]="formConf" (ngSubmit)="sendIntConfigString()">
-                <input type="text" placeholder="IPv4 address" [ngClass]="{ 'is-invalid': formConf.controls.colIp.errors }"
-                       class="form-control" formControlName="colIp">
-                :
-                <input type="text" placeholder="port" class="form-control" [ngClass]="{ 'is-invalid': formConf.controls.colPort.errors }" formControlName="colPort">
-                <div *ngIf="formConf.controls.colIp.errors" class="invalid-feedback">
-                    <div class="error-text" *ngIf="formConf.controls.colIp.errors.required"> Control IP is required</div>
-                    <div class="error-text" *ngIf="formConf.controls.colIp.errors.pattern">Control IP must be a valid IP address</div>
+        <div>
+            <form [formGroup]="formSend" (ngSubmit)="sendIntIntentString()">
+                <div class="input-panel">
+                    <h3>
+                        Create New Watchlist Rule
+                    </h3>
+                    <div>
+                        <label>
+                            <input type="text" placeholder="Source IP prefix"
+                                   [ngClass]="{ 'is-invalid': formSend.controls.ip4SrcPrefix.errors }"
+                                   class="form-control" formControlName="ip4SrcPrefix">
+
+                        </label>
+                        <label>
+                            <input type="text" placeholder="Dest IP prefix"
+                                   [ngClass]="{ 'is-invalid': formSend.controls.ip4DstPrefix.errors }"
+                                   class="form-control" formControlName="ip4DstPrefix">
+                        </label>
+                        <label>
+                            <input type="text" placeholder="Source port"
+                                   [ngClass]="{ 'is-invalid': formSend.controls.l4SrcPort.errors }"
+                                   class="form-control" formControlName="l4SrcPort">
+                        </label>
+                        <label>
+                            <input type="text" placeholder="Destination port"
+                                   [ngClass]="{ 'is-invalid': formSend.controls.l4DstPort.errors }"
+                                   class="form-control" formControlName="l4DstPort">
+                        </label>
+                        <label>
+                            Protocol
+                            <select name="protocol" formControlName="protocol">
+                                <option selected disabled hidden
+                                        style="display: none" value=''></option>
+                                <option value="TCP">TCP</option>
+                                <option value="UDP">UDP</option>
+                            </select>
+                        </label>
+                        <div *ngIf="formSend.controls.ip4DstPrefix.errors" class="invalid-feedback">
+                            <div class="error-text" *ngIf="formSend.controls.ip4DstPrefix.errors.required"> Destination
+                                IP is required
+                            </div>
+                            <div class="error-text" *ngIf="formSend.controls.ip4DstPrefix.errors.pattern">Destination IP
+                                must be a valid IP address
+                            </div>
+                        </div>
+                        <div *ngIf="formSend.controls.ip4SrcPrefix.errors" class="invalid-feedback">
+                            <div class="error-text" *ngIf="formSend.controls.ip4SrcPrefix.errors.required">Source IP is
+                                required
+                            </div>
+                            <div class="error-text" *ngIf="formSend.controls.ip4SrcPrefix.errors.pattern">Source IP must
+                                be a valid IP address
+                            </div>
+                        </div>
+                        <div *ngIf="formSend.controls.l4DstPort.errors" class="invalid-feedback">
+                            <div class="error-text" *ngIf="formSend.controls.l4DstPort.errors.pattern">Destination Port
+                                must be a valid Port
+                            </div>
+                        </div>
+                        <div *ngIf="formSend.controls.l4SrcPort.errors" class="invalid-feedback">
+                            <div class="error-text" *ngIf="formSend.controls.l4SrcPort.errors.pattern">Source Port must
+                                be a valid Port
+                            </div>
+                        </div>
+                    </div>
+                    <div>
+                        <div class="myrow">
+                            <div *ngFor="let data of metaData">
+                                <div class="mygrid">
+                                    <label>
+                                        <input type="checkbox"
+                                               (change)="onCheckboxChange(data.value, $event.target.checked)"/>
+                                        {{ data.name }}
+                                    </label>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
                 </div>
-                <div *ngIf="formConf.controls.colPort.errors" class="invalid-feedback">
-                    <div class="error-text" *ngIf="formConf.controls.colPort.errors.required">Port is required</div>
-                    <div class="error-text" *ngIf="formConf.controls.colPort.errors.pattern">Port must be a valid Port number</div>
-                </div>
-                <div class="config-button-panel">
+                <div class="button-panel">
                     <button class="int-app-button">
-                        Apply Configuration
+                        Apply Watchlist Rule
                     </button>
                 </div>
             </form>
         </div>
     </div>
-    <div class="tabular-header">
-        <h2 style="font-weight: bold">In-band Network Telemetry (INT) Control
-            Application</h2>
-    </div>
-
-    <hr>
-                <div class="tabular-header">
-                    <h2>
-                        INT Watchlist Rules
-                    </h2>
-                    <div>
-                        <form [formGroup]="formSend" (ngSubmit)="sendIntIntentString()">
-                        <div class="input-panel">
-                            <h3>
-                                Create New Watchlist Rule
-                            </h3>
-                            <div>
-                                <label>
-                                <input type="text" placeholder="Source IP address" [ngClass]="{ 'is-invalid': formSend.controls.ip4SrcPrefix.errors }"
-                                       class="form-control" formControlName="ip4SrcPrefix">
-
-                                </label>
-                                <label>
-                                    <input type="text" placeholder="Dest IP address" [ngClass]="{ 'is-invalid': formSend.controls.ip4DstPrefix.errors }"
-                                           class="form-control" formControlName="ip4DstPrefix">
-                                </label>
-                                <label>
-                                    <input type="text" placeholder="Source port" [ngClass]="{ 'is-invalid': formSend.controls.l4SrcPort.errors }"
-                                               class="form-control" formControlName="l4SrcPort">
-                                </label>
-                                <label>
-                                    <input type="text" placeholder="Dest port" [ngClass]="{ 'is-invalid': formSend.controls.l4DstPort.errors }"
-                                           class="form-control" formControlName="l4DstPort">
-                                </label>
-                                <label>
-                                    Protocol
-                                    <select name="protocol" formControlName="protocol">
-                                        <option selected disabled hidden
-                                                style="display: none" value=''></option>
-                                        <option value="TCP">TCP</option>
-                                        <option value="UDP">UDP</option>
-                                    </select>
-                                </label>
-                                <div *ngIf="formSend.controls.ip4DstPrefix.errors" class="invalid-feedback">
-                                    <div class="error-text" *ngIf="formSend.controls.ip4DstPrefix.errors.required"> Destination IP is required</div>
-                                    <div class="error-text" *ngIf="formSend.controls.ip4DstPrefix.errors.pattern">Destination IP must be a valid IP address</div>
-                                </div>
-                                <div *ngIf="formSend.controls.ip4SrcPrefix.errors" class="invalid-feedback">
-                                    <div class="error-text" *ngIf="formSend.controls.ip4SrcPrefix.errors.required">Source IP is required</div>
-                                    <div class="error-text" *ngIf="formSend.controls.ip4SrcPrefix.errors.pattern">Source IP must be a valid IP address</div>
-                                </div>
-                                <div *ngIf="formSend.controls.l4DstPort.errors" class="invalid-feedback">
-                                    <div class="error-text" *ngIf="formSend.controls.l4DstPort.errors.pattern">Destination Port must be a valid Port</div>
-                                </div>
-                                <div *ngIf="formSend.controls.l4SrcPort.errors" class="invalid-feedback">
-                                    <div class="error-text" *ngIf="formSend.controls.l4SrcPort.errors.pattern">Source Port must be a valid Port</div>
-                                </div>
-                            </div>
-                            <div>
-                                    <div class="myrow">
-                                        <div *ngFor="let data of metaData">
-                                            <div class="mygrid">
-                                                <label>
-                                                    <input type="checkbox"
-                                                           (change)="onCheckboxChange(data.value, $event.target.checked)"/>
-                                                    {{ data.name }}
-                                                </label>
-                                            </div>
-                                        </div>
-                                    </div>
-                            </div>
-                        </div>
-                        <div class="button-panel">
-                            <button class="int-app-button">
-                                Apply Watchlist Rule
-                            </button>
-                        </div>
-                        </form>
-                    </div>
-                </div>
 
     <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
     <div class='int-app-main-intents'>
diff --git a/apps/inbandtelemetry/int-gui2-lib/projects/int-gui2-lib/src/lib/intapp/intapp.component.ts b/apps/inbandtelemetry/int-gui2-lib/projects/int-gui2-lib/src/lib/intapp/intapp.component.ts
index c5ccf50..185ef6e 100644
--- a/apps/inbandtelemetry/int-gui2-lib/projects/int-gui2-lib/src/lib/intapp/intapp.component.ts
+++ b/apps/inbandtelemetry/int-gui2-lib/projects/int-gui2-lib/src/lib/intapp/intapp.component.ts
@@ -28,10 +28,7 @@
 // constants
 const intIntentAddReq = 'intIntentAddRequest';
 const intIntentDelReq = 'intIntentDelRequest';
-const intConfigAddReq = 'intConfigAddRequest';
-const regColIp = '^([0-9]{1,3}\\.){3}[0-9]{1,3}$';
-const regColPort = '^[0-9]{0,5}$';
-const regSendIp = '^([0-9]{1,3}\\.){3}[0-9]{1,3}(/[0-9]{1,2})?$'
+const regSendIp = '^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/[0-9]{1,2})?$'
 const regSendPort ='^[0-9]{0,5}$'
 
 export interface Metadata {
@@ -86,10 +83,6 @@
             l4DstPort: new FormControl(null, [ Validators.pattern(regSendPort)]),
             protocol: new FormControl(),
         });
-        this.formConf = this.fb.group({
-            colIp: new FormControl(null, [Validators.required, Validators.pattern(regColIp)]),
-            colPort: new FormControl( null, [Validators.required, Validators.pattern(regColPort)])
-        });
         this.log.debug('IntAppComponent initialized');
     }
 
@@ -117,17 +110,6 @@
         }
     }
 
-    sendIntConfigString() {
-        if (this.formConf.invalid) {
-            return;
-        }
-        let configObjectNode = {
-            "collectorIp": this.formConf.value.colIp,
-            "collectorPort": this.formConf.value.colPort
-        };
-        this.wss.sendEvent(intConfigAddReq, configObjectNode);
-    }
-
     sendIntIntentString() {
         if (this.formSend.invalid) {
             return;
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
index e1790bc..a21a2ae 100644
--- 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
@@ -170,12 +170,11 @@
      * 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 IpAddress collectorIp = IpAddress.valueOf(0);
+        private TpPort collectorPort = TpPort.tpPort(0);
+        private MacAddress collectorNextHopMac = MacAddress.valueOf(0);
+        private IpAddress sinkIp = IpAddress.valueOf(0);
+        private MacAddress sinkMac = MacAddress.valueOf(0);
         private TelemetrySpec spec = TelemetrySpec.INT;
         private boolean enabled = false;
         int minFlowHopLatencyChangeNs = 0;
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
index b1d842e..8f036fe 100644
--- 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
@@ -111,7 +111,6 @@
          */
         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);
         }