ONOS-6336: Flows View : show app name (not integer ID).

Change-Id: I00afbb06c8dcf7e11e5e2e182b4b0f12f3a060bf
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
index 1321bb6..29ec446 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
@@ -19,6 +19,8 @@
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableSet;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.core.Application;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.DefaultApplicationId;
 import org.onosproject.net.DeviceId;
@@ -39,7 +41,9 @@
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 
 /**
@@ -59,6 +63,7 @@
     private static final String ID = "id";
     private static final String FLOW_ID = "flowId";
     private static final String APP_ID = "appId";
+    private static final String APP_NAME = "appName";
     private static final String GROUP_ID = "groupId";
     private static final String TABLE_ID = "tableId";
     private static final String PRIORITY = "priority";
@@ -77,6 +82,9 @@
     private static final String OX = "0x";
     private static final String EMPTY = "";
 
+    private static final String ONOS_PREFIX = "org.onosproject.";
+    private static final String ONOS_MARKER = "*";
+
     private static final String[] COL_IDS = {
             ID,
             STATE,
@@ -86,6 +94,7 @@
             PRIORITY,
             TABLE_ID,
             APP_ID,
+            APP_NAME,
 
             GROUP_ID,
             TIMEOUT,
@@ -111,6 +120,27 @@
         return sb;
     }
 
+    // Generate a map of shorts->application IDs
+    // (working around deficiency(?) in Application Service API)
+    private Map<Short, ApplicationId> appShortMap() {
+        Set<Application> apps =
+                get(ApplicationService.class).getApplications();
+
+        return apps.stream()
+                .collect(Collectors.toMap(a -> a.id().id(), Application::id));
+    }
+
+    // Return an application name, based on a lookup of the internal short ID
+    private String makeAppName(short id, Map<Short, ApplicationId> lookup) {
+        ApplicationId appId = lookup.get(id);
+        if (appId == null) {
+            return "Unknown <" + id + ">";
+        }
+        String appName = appId.name();
+        return appName.startsWith(ONOS_PREFIX)
+                ? appName.replaceFirst(ONOS_PREFIX, ONOS_MARKER) : appName;
+    }
+
     // handler for flow table requests
     private final class FlowDataRequest extends TableRequestHandler {
 
@@ -151,14 +181,17 @@
             String uri = string(payload, "devId");
             if (!Strings.isNullOrEmpty(uri)) {
                 DeviceId deviceId = DeviceId.deviceId(uri);
+                Map<Short, ApplicationId> lookup = appShortMap();
                 FlowRuleService frs = get(FlowRuleService.class);
+
                 for (FlowEntry flow : frs.getFlowEntries(deviceId)) {
-                    populateRow(tm.addRow(), flow);
+                    populateRow(tm.addRow(), flow, lookup);
                 }
             }
         }
 
-        private void populateRow(TableModel.Row row, FlowEntry flow) {
+        private void populateRow(TableModel.Row row, FlowEntry flow,
+                                 Map<Short, ApplicationId> lookup) {
             row.cell(ID, flow.id().value())
                     .cell(STATE, flow.state())
                     .cell(BYTES, flow.bytes())
@@ -167,6 +200,7 @@
                     .cell(PRIORITY, flow.priority())
                     .cell(TABLE_ID, flow.tableId())
                     .cell(APP_ID, flow.appId())
+                    .cell(APP_NAME, makeAppName(flow.appId(), lookup))
 
                     .cell(GROUP_ID, flow.groupId().id())
                     .cell(TIMEOUT, flow.timeout())
@@ -178,7 +212,6 @@
                     .cell(TREATMENT, flow);
         }
 
-
         private class InternalSelectorFormatter implements CellFormatter {
             private final boolean shortFormat;
 
@@ -375,6 +408,8 @@
                 data.put(FLOW_PRIORITY, flow.priority());
                 data.put(TABLE_ID, flow.tableId());
                 data.put(APP_ID, flow.appId());
+                // NOTE: horribly inefficient... make a map and retrieve a single value...
+                data.put(APP_NAME, makeAppName(flow.appId(), appShortMap()));
 
                 data.put(GROUP_ID, decorateGroupId(flow));
                 data.put(TIMEOUT, flow.hardTimeout());
diff --git a/web/gui/src/main/webapp/app/view/flow/flow.html b/web/gui/src/main/webapp/app/view/flow/flow.html
index b18e424..af24a63 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.html
+++ b/web/gui/src/main/webapp/app/view/flow/flow.html
@@ -65,7 +65,7 @@
                 <option value="tableId">Table ID</option>
                 <option value="selector">Selector</option>
                 <option value="treatment">Treatment</option>
-                <option value="appId">App ID</option>
+                <option value="appName">App Name</option>
             </select>
         </div>
 
@@ -84,7 +84,7 @@
                     <td colId="tableId" col-width="80px" sortable> Table ID </td>
                     <td colId="selector" sortable> Selector </td>
                     <td colId="treatment" sortable> Treatment </td>
-                    <td colId="appId" sortable> App ID </td>
+                    <td colId="appName" sortable> App Name </td>
                 </tr>
             </table>
         </div>
@@ -111,7 +111,7 @@
                     <td>{{flow.tableId}}</td>
                     <td>{{flow.selector_c}}</td>
                     <td>{{flow.treatment_c}}</td>
-                    <td>{{flow.appId}}</td>
+                    <td>{{flow.appName}}</td>
                 </tr>
                 <tr ng-click="selectCallback($event, flow)"
                     ng-class="{selected: flow.id === selId}"
diff --git a/web/gui/src/main/webapp/app/view/flow/flow.js b/web/gui/src/main/webapp/app/view/flow/flow.js
index 11c897d..a29abac 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.js
+++ b/web/gui/src/main/webapp/app/view/flow/flow.js
@@ -62,6 +62,7 @@
 
             'priority',
             'tableId',
+            'appName',
             'appId',
 
             'groupId',
@@ -78,6 +79,7 @@
 
             'Flow Priority',
             'Table ID',
+            'App Name',
             'App ID',
 
             'Group ID',