Adding first set of changes for bug onos-5071
Addressed review comments
Addressed review comments for patch-2
Addressed review comments for patch-3
Fixed broken "show intent" on topo view.

Change-Id: Ie76deca917d6cd6c98d121135e53b9093b5ed8ee
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
index 71c017d..d48a089 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
@@ -88,6 +88,7 @@
 import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
 import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
 import static org.onosproject.ui.JsonUtils.envelope;
+import static org.onosproject.ui.JsonUtils.string;
 import static org.onosproject.ui.topo.TopoJson.highlightsMessage;
 import static org.onosproject.ui.topo.TopoJson.json;
 
@@ -100,6 +101,7 @@
     private static final String REQ_DETAILS = "requestDetails";
     private static final String UPDATE_META = "updateMeta";
     private static final String ADD_HOST_INTENT = "addHostIntent";
+    private static final String REMOVE_INTENT = "removeIntent";
     private static final String ADD_MULTI_SRC_INTENT = "addMultiSourceIntent";
     private static final String REQ_RELATED_INTENTS = "requestRelatedIntents";
     private static final String REQ_NEXT_INTENT = "requestNextRelatedIntent";
@@ -220,6 +222,7 @@
                 // TODO: migrate traffic related to separate app
                 new AddHostIntent(),
                 new AddMultiSourceIntent(),
+                new RemoveIntent(),
 
                 new ReqAllFlowTraffic(),
                 new ReqAllPortTraffic(),
@@ -426,6 +429,37 @@
         }
     }
 
+    private Intent findIntentByPayload(ObjectNode payload) {
+        int appId = Integer.parseInt(string(payload, APP_ID));
+        String appName = string(payload, APP_NAME);
+        ApplicationId applicId = new DefaultApplicationId(appId, appName);
+        long intentKey = Long.decode(string(payload, KEY));
+
+        Key key = Key.of(intentKey, applicId);
+        log.debug("Attempting to select intent by key={}", key);
+
+        Intent intent = intentService.getIntent(key);
+
+        return intent;
+    }
+
+    private final class RemoveIntent extends RequestHandler {
+        private RemoveIntent() {
+            super(REMOVE_INTENT);
+        }
+
+        @Override
+        public void process(long sid, ObjectNode payload) {
+            Intent intent = findIntentByPayload(payload);
+            if (intent == null) {
+                log.warn("Unable to find intent from payload {}", payload);
+            } else {
+                log.debug("Removing intent {}", intent.key());
+                intentService.withdraw(intent);
+            }
+        }
+    }
+
     private final class AddMultiSourceIntent extends RequestHandler {
         private AddMultiSourceIntent() {
             super(ADD_MULTI_SRC_INTENT);
@@ -551,19 +585,11 @@
 
         @Override
         public void process(long sid, ObjectNode payload) {
-            int appId = Integer.parseInt(string(payload, APP_ID));
-            String appName = string(payload, APP_NAME);
-            ApplicationId applicId = new DefaultApplicationId(appId, appName);
-            long intentKey = Long.decode(string(payload, KEY));
-
-            Key key = Key.of(intentKey, applicId);
-            log.debug("Attempting to select intent key={}", key);
-
-            Intent intent = intentService.getIntent(key);
+            Intent intent = findIntentByPayload(payload);
             if (intent == null) {
-                log.debug("no such intent found!");
+                log.warn("Unable to find intent from payload {}", payload);
             } else {
-                log.debug("starting to monitor intent {}", key);
+                log.debug("starting to monitor intent {}", intent.key());
                 traffic.monitor(intent);
             }
         }
diff --git a/web/gui/src/main/webapp/app/view/intent/intent.css b/web/gui/src/main/webapp/app/view/intent/intent.css
index 501e5b7..72a52f6 100644
--- a/web/gui/src/main/webapp/app/view/intent/intent.css
+++ b/web/gui/src/main/webapp/app/view/intent/intent.css
@@ -23,7 +23,7 @@
 }
 
 #ov-intent div.ctrl-btns {
-    width: 110px;
+    width: 150px;
 }
 
 
diff --git a/web/gui/src/main/webapp/app/view/intent/intent.html b/web/gui/src/main/webapp/app/view/intent/intent.html
index 85ccf04..309174a 100644
--- a/web/gui/src/main/webapp/app/view/intent/intent.html
+++ b/web/gui/src/main/webapp/app/view/intent/intent.html
@@ -11,9 +11,16 @@
             <div class="separator"></div>
 
             <div ng-class="{active: !!selId}"
-                    icon icon-id="topo" icon-size="42"
-                    tooltip tt-msg="topoTip"
-                    ng-click="showIntent()"></div>
+                 icon icon-id="topo" icon-size="42"
+                 tooltip tt-msg="topoTip"
+                 ng-click="showIntent()"></div>
+
+            <div ng-class="{'active': !!selId}"
+                 icon icon-id="stop" icon-size="42"
+                 tooltip tt-msg="deactivateTip"
+                 ng-click="deactivateIntent()"></div>
+
+
         </div>
     </div>
 
diff --git a/web/gui/src/main/webapp/app/view/intent/intent.js b/web/gui/src/main/webapp/app/view/intent/intent.js
index b6698f8..3571228 100644
--- a/web/gui/src/main/webapp/app/view/intent/intent.js
+++ b/web/gui/src/main/webapp/app/view/intent/intent.js
@@ -21,11 +21,17 @@
 (function () {
     'use strict';
 
+    var dialogId = 'remove-intent-dialog',
+        dialogOpts = {
+            edge: 'right'
+        };
+
     angular.module('ovIntent', [])
         .controller('OvIntentCtrl',
         ['$log', '$scope', 'TableBuilderService', 'NavService',
+            'TopoTrafficService', 'DialogService',
 
-        function ($log, $scope, tbs, ns) {
+        function ($log, $scope, tbs, ns, tts, ds) {
 
             function selCb($event, row) {
                 $log.debug('Got a click on:', row);
@@ -34,9 +40,9 @@
                     name = m ? m[2] : null;
 
                 $scope.intentData = ($scope.selId && m) ? {
-                    intentAppId: id,
-                    intentAppName: name,
-                    intentKey: row.key
+                    appId: id,
+                    appName: name,
+                    key: row.key
                 } : null;
             }
 
@@ -48,12 +54,42 @@
             });
 
             $scope.topoTip = 'Show selected intent on topology view';
+            $scope.deactivateTip = 'Remove selected intent';
 
             $scope.showIntent = function () {
                 var d = $scope.intentData;
                 d && ns.navTo('topo', d);
             };
 
-            $log.log('OvIntentCtrl has been created');
+            $scope.deactivateIntent = function () {
+                var content = ds.createDiv();
+
+                content.append('p')
+                    .text('Are you sure you want to remove the selected intent?');
+
+                function dOk() {
+                    var d = $scope.intentData;
+                    d && tts.removeIntent(d);
+                }
+
+                function dCancel() {
+                    ds.closeDialog();
+                    $log.debug('Canceling remove-intent action');
+                }
+
+                ds.openDialog(dialogId, dialogOpts)
+                    .setTitle('Confirm Action')
+                    .addContent(content)
+                    .addOk(dOk)
+                    .addCancel(dCancel)
+                    .bindKeys();
+            };
+
+            $scope.$on('$destroy', function () {
+                ds.closeDialog();
+                $log.debug('OvIntentCtrl has been destroyed');
+            });
+
+            $log.debug('OvIntentCtrl has been created');
         }]);
 }());
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index 33353b0..fa3e1db 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -585,11 +585,11 @@
                 setMap: setMap
             });
 
-            if (params.intentKey && params.intentAppId && params.intentAppName) {
+            if (params.key && params.appId && params.appName) {
                 $scope.intentData = {
-                    key: params.intentKey,
-                    appId: params.intentAppId,
-                    appName: params.intentAppName
+                    key: params.key,
+                    appId: params.appId,
+                    appName: params.appName
                 };
             }
 
diff --git a/web/gui/src/main/webapp/app/view/topo/topoTraffic.js b/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
index 2ca71cc..8b6085c 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
@@ -176,6 +176,18 @@
         flash.flash('Host-to-Host flow added');
     }
 
+    function removeIntent (d) {
+        $log.debug('Entering removeIntent');
+        wss.sendEvent('removeIntent', {
+            appId: d.appId,
+            appName: d.appName,
+            key: d.key
+        });
+        trafficMode = 'intents';
+        hoverMode = null;
+        flash.flash('Intent removed');
+    }
+
     function addMultiSourceIntent () {
         var so = api.selectOrder();
         wss.sendEvent('addMultiSourceIntent', {
@@ -223,7 +235,8 @@
                 // TODO: these should move to new UI demo app
                 // invoked from buttons on detail (multi-select) panel
                 addHostIntent: addHostIntent,
-                addMultiSourceIntent: addMultiSourceIntent
+                addMultiSourceIntent: addMultiSourceIntent,
+                removeIntent: removeIntent
             };
         }]);
 }());
diff --git a/web/gui/src/main/webapp/tests/app/view/topo/topoTraffic-spec.js b/web/gui/src/main/webapp/tests/app/view/topo/topoTraffic-spec.js
index 16686e1..4febcb1 100644
--- a/web/gui/src/main/webapp/tests/app/view/topo/topoTraffic-spec.js
+++ b/web/gui/src/main/webapp/tests/app/view/topo/topoTraffic-spec.js
@@ -49,6 +49,7 @@
             'requestTrafficForMode',
             'addHostIntent',
             'addMultiSourceIntent',
+            'removeIntent',
         ])).toBeTruthy();
     });