CORD GUI - Added logout call, and implemented the notion of session.

Change-Id: I44fc42c909071755c73ac367bf03427cfbe6b643
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java
index 87edd3d..1f24663 100644
--- a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordModelCache.java
@@ -62,9 +62,11 @@
     private static final String BUNDLE = "bundle";
     private static final String USERS = "users";
     private static final String LEVEL = "level";
+    private static final String LOGOUT = "logout";
 
     private static final Map<Integer, Integer> LOOKUP = new HashMap<>();
 
+    private String email = null;
     private int subscriberId;
     private int ssid;
     private Bundle currentBundle;
@@ -84,8 +86,6 @@
         ObjectNode map = XosManager.INSTANCE.initXosSubscriberLookups();
         initLookupMap(map);
         log.info("{} entries in SSID->SubID lookup map", LOOKUP.size());
-        // force DEMO subscriber to be installed by default
-        init("foo@bar");
     }
 
     private void initLookupMap(ObjectNode map) {
@@ -122,6 +122,8 @@
         // defaults to the demo account
         int ssid = DEMO_SSID;
 
+        this.email = email;
+
         // obviously not scalable, but good enough for demo code...
         if (EMAIL_0.equals(email)) {
             ssid = 0;
@@ -144,12 +146,16 @@
     }
 
     private void initUsers() {
+        // start with a clean slate
+        userMap.clear();
+
         ArrayNode users = XosManager.INSTANCE.getUserList();
         if (users == null) {
             log.warn("no user list for SSID {} (subid {})", ssid, subscriberId);
             return;
         }
 
+        StringBuilder sb = new StringBuilder();
         for (JsonNode u: users) {
             ObjectNode user = (ObjectNode) u;
 
@@ -164,8 +170,10 @@
             //       memento in which to store the level.
             SubscriberUser su = createUser(id, name, mac, level);
             userMap.put(id, su);
-            log.info("..caching user {} (id:{})", name, id);
+            sb.append(String.format("\n..cache user %s [%d], %s, %s",
+                                    name, id, mac, level));
         }
+        log.info(sb.toString());
     }
 
     private SubscriberUser createUser(int uid, String name, String mac,
@@ -274,6 +282,7 @@
     private void addSubId(ObjectNode root) {
         root.put(SUB_ID, subscriberId);
         root.put(SSID, ssid);
+        root.put(EMAIL, email);
     }
 
 
@@ -287,9 +296,9 @@
      * @return JSON acknowledgement
      */
     public String jsonLogin(String email) {
+        log.info("jsonLogin(\"{}\")", email);
         init(email);
         ObjectNode root = objectNode();
-        root.put(EMAIL, email);
         addSubId(root);
         return root.toString();
     }
@@ -300,6 +309,12 @@
      * @return dashboard page JSON data
      */
     public String jsonDashboard() {
+        log.info("jsonDashboard()");
+
+        if (email == null) {
+            return jsonLogout();
+        }
+
         ObjectNode root = objectNode();
         root.put(BUNDLE, currentBundle.descriptor().displayName());
         root.set(USERS, userJsonArray());
@@ -313,6 +328,12 @@
      * @return bundle page JSON data
      */
     public String jsonBundle() {
+        log.info("jsonBundle()");
+
+        if (email == null) {
+            return jsonLogout();
+        }
+
         ObjectNode root = BundleFactory.toObjectNode(currentBundle);
         addSubId(root);
         return root.toString();
@@ -324,6 +345,12 @@
      * @return users page JSON data
      */
     public String jsonUsers() {
+        log.info("jsonUsers()");
+
+        if (email == null) {
+            return jsonLogout();
+        }
+
         ObjectNode root = objectNode();
         root.set(USERS, userJsonArray());
         addSubId(root);
@@ -331,6 +358,21 @@
     }
 
     /**
+     * Returns logout acknowledgement as JSON.
+     *
+     * @return logout acknowledgement
+     */
+    public String jsonLogout() {
+        log.info("jsonLogout()");
+        ObjectNode root = objectNode().put(LOGOUT, true);
+        addSubId(root);
+
+        email = null;   // signifies no one logged in
+
+        return root.toString();
+    }
+
+    /**
      * Singleton instance.
      */
     public static final CordModelCache INSTANCE = new CordModelCache();
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordWebResource.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordWebResource.java
index ab3f311..7fc4afe 100644
--- a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordWebResource.java
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/CordWebResource.java
@@ -31,6 +31,13 @@
 
     @GET
     @Produces(MediaType.APPLICATION_JSON)
+    @Path("login/{email}")
+    public Response login(@PathParam("email") String email) {
+        return Response.ok(CordModelCache.INSTANCE.jsonLogin(email)).build();
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
     @Path("dashboard")
     public Response dashboard() {
         return Response.ok(CordModelCache.INSTANCE.jsonDashboard()).build();
@@ -50,15 +57,15 @@
         return Response.ok(CordModelCache.INSTANCE.jsonUsers()).build();
     }
 
-    // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
     @GET
     @Produces(MediaType.APPLICATION_JSON)
-    @Path("login/{email}")
-    public Response login(@PathParam("email") String email) {
-        return Response.ok(CordModelCache.INSTANCE.jsonLogin(email)).build();
+    @Path("logout")
+    public Response logout() {
+        return Response.ok(CordModelCache.INSTANCE.jsonLogout()).build();
     }
 
+    // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     @Path("bundle/{id}")
diff --git a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/XosManagerRestUtils.java b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/XosManagerRestUtils.java
index 376591b..50ccde3 100644
--- a/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/XosManagerRestUtils.java
+++ b/apps/demo/cord-gui/src/main/java/org/onosproject/cord/gui/XosManagerRestUtils.java
@@ -64,7 +64,7 @@
         this.xosServerAddress = xosServerAddress;
         this.xosServerPort = xosServerPort;
         this.baseUri = baseUri;
-        log.info("XMRU:: {}:{}/{}", xosServerAddress, xosServerPort, baseUri);
+        log.info("XMRU:: {}:{}{}", xosServerAddress, xosServerPort, baseUri);
     }
 
     // build the base URL from the pieces we know...
diff --git a/apps/demo/cord-gui/src/scripts/run.me b/apps/demo/cord-gui/src/scripts/run.me
index d0ebb17..db76fb6 100644
--- a/apps/demo/cord-gui/src/scripts/run.me
+++ b/apps/demo/cord-gui/src/scripts/run.me
@@ -9,6 +9,13 @@
 export DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n"
 export LOG=cord.log
 
+DBG=""
+if [ "$1" = "debug" ]
+then
+    shift
+    DBG=$DEBUG
+fi
+
 IP="$1"
 PORT="$2"
 
@@ -26,8 +33,7 @@
   PARAM2=""
 fi
 
-java $PARAM1 $PARAM2 $LOGDBG $JETTY --port $LISTENPORT $CORD >$LOG 2>&1 &
-#java $PARAM1 $PARAM2 $LOGDBG $DEBUG $JETTY --port $LISTENPORT $CORD >$LOG 2>&1 &
+java $PARAM1 $PARAM2 $LOGDBG $DBG $JETTY --port $LISTENPORT $CORD >$LOG 2>&1 &
 
 echo jetty-runner started {$PARAM1:$PARAM2}
 echo .. logging to $LOG