Fix for ONOS-5406

Change-Id: I932e8efc3cb09b021316950a3104c62fe29e1dbc
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 609b775..bd344db 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
@@ -55,6 +55,8 @@
 import org.onosproject.net.intent.IntentListener;
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.link.LinkEvent;
 import org.onosproject.net.link.LinkListener;
 import org.onosproject.ui.JsonUtils;
@@ -101,6 +103,7 @@
     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 REMOVE_INTENTS = "removeIntents";
     private static final String RESUBMIT_INTENT = "resubmitIntent";
     private static final String ADD_MULTI_SRC_INTENT = "addMultiSourceIntent";
     private static final String REQ_RELATED_INTENTS = "requestRelatedIntents";
@@ -223,6 +226,7 @@
                 new AddMultiSourceIntent(),
                 new RemoveIntent(),
                 new ResubmitIntent(),
+                new RemoveIntents(),
 
                 new ReqAllFlowTraffic(),
                 new ReqAllPortTraffic(),
@@ -507,6 +511,24 @@
         }
     }
 
+    private final class RemoveIntents extends RequestHandler {
+        private RemoveIntents() {
+            super(REMOVE_INTENTS);
+        }
+
+
+        @Override
+        public void process(ObjectNode payload) {
+            IntentService intentService = get(IntentService.class);
+            for (Intent intent : intentService.getIntents()) {
+                if (intentService.getIntentState(intent.key()) == IntentState.WITHDRAWN) {
+                    intentService.purge(intent);
+                }
+            }
+
+        }
+    }
+
     // ========= -----------------------------------------------------------------
 
     private final class ReqAllFlowTraffic extends RequestHandler {
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 18d8673..9de4c38 100644
--- a/web/gui/src/main/webapp/app/view/intent/intent.html
+++ b/web/gui/src/main/webapp/app/view/intent/intent.html
@@ -47,6 +47,10 @@
                  tooltip tt-msg="purgeTip"
                  ng-click="(!!selId && isIntentWithdrawn()) ? purgeIntent():''"></div>
 
+            <div ng-class="{'active': isHavingWithdrawn()}"
+                 icon icon-id="garbage" icon-size="47"
+                 tooltip tt-msg="purgeAllTip"
+                 ng-click="(isHavingWithdrawn()) ? purgeIntents():''"></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 71c07cf..324f389 100644
--- a/web/gui/src/main/webapp/app/view/intent/intent.js
+++ b/web/gui/src/main/webapp/app/view/intent/intent.js
@@ -74,6 +74,7 @@
             $scope.resubmitTip = 'Resubmit selected intent';
             $scope.deactivateTip = 'Remove selected intent';
             $scope.purgeTip = 'Purge selected intent';
+            $scope.purgeAllTip = 'Purge withdrawn intents';
 
             $scope.showIntent = function () {
                 var d = $scope.intentData;
@@ -88,6 +89,16 @@
                 return $scope.intentState === 'Withdrawn';
             };
 
+            $scope.isHavingWithdrawn = function () {
+                var isWithdrawn = false;
+                $scope.tableData.forEach(function (intent) {
+                    if (intent.state ==='Withdrawn') {
+                        isWithdrawn = true;
+                    }
+                });
+                return isWithdrawn;
+            };
+
             function executeAction(action) {
                 var content = ds.createDiv(),
                     txt,
@@ -119,6 +130,29 @@
                     .addCancel(dCancel)
                     .bindKeys();
             }
+            function executeActions(action) {
+                 var content = ds.createDiv(),
+                     txt='purgeIntents';
+                     content.append('p').
+                     text('Are you sure you want to purge all the withdrawn intents?');
+
+                 function dOk() {
+                     tts.removeIntents();
+                     $scope.fired = true;
+                 }
+
+                 function dCancel() {
+                     ds.closeDialog();
+                     $log.debug('Canceling remove-intents action');
+                 }
+
+                 ds.openDialog(dialogId, dialogOpts)
+                 .setTitle('Confirm Action')
+                 .addContent(content)
+                 .addOk(dOk)
+                 .addCancel(dCancel)
+                 .bindKeys();
+            }
 
             $scope.deactivateIntent = function () {
                 executeAction("withdraw");
@@ -141,6 +175,9 @@
                 $log.debug('OvIntentCtrl has been destroyed');
             });
 
+            $scope.purgeIntents = function () {
+                executeActions("purgeIntents");
+            };
             $log.debug('OvIntentCtrl has been created');
         }]);
 }());
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 5d52ab1..2db9275 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
@@ -217,6 +217,14 @@
         flash.flash('Multi-Source flow added');
     }
 
+    function removeIntents () {
+        $log.debug('Entering removeIntents');
+        wss.sendEvent('removeIntents', {});
+        trafficMode = 'intents';
+        hoverMode = null;
+        flash.flash('Intent are purged');
+    }
+
 
     // === -----------------------------------------------------
     // === MODULE DEFINITION ===
@@ -254,7 +262,8 @@
                 addHostIntent: addHostIntent,
                 addMultiSourceIntent: addMultiSourceIntent,
                 removeIntent: removeIntent,
-                resubmitIntent: resubmitIntent
+                resubmitIntent: resubmitIntent,
+                removeIntents: removeIntents
             };
         }]);
 }());
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 ff9fd72..0a04f34 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
@@ -51,6 +51,7 @@
             'addMultiSourceIntent',
             'removeIntent',
             'resubmitIntent',
+            'removeIntents',
         ])).toBeTruthy();
     });