Add support for disjoint Paths to paths CLI

+ minor changes

Change-Id: I9fa65ed3e8633327c44d0f8142f98f6be9b35a48
diff --git a/cli/src/main/java/org/onosproject/cli/net/PathListCommand.java b/cli/src/main/java/org/onosproject/cli/net/PathListCommand.java
index c15251c..92c2d0a 100644
--- a/cli/src/main/java/org/onosproject/cli/net/PathListCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/PathListCommand.java
@@ -20,9 +20,13 @@
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
 import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
+import org.onosproject.net.device.DeviceService;
 
 import java.util.Set;
 
@@ -47,19 +51,38 @@
               required = true, multiValued = false)
     String dst = null;
 
+    @Option(name = "--disjoint", description = "Show disjoint Paths")
+    boolean disjoint = false;
+
     @Override
     protected void execute() {
         init();
-        if (src.split("/").length != 1 || dst.split("/").length != 1) {
-            print("Expected device IDs as arguments");
+        DeviceService deviceService = get(DeviceService.class);
+        DeviceId srcDid = deviceId(src);
+        if (deviceService.getDevice(srcDid) == null) {
+            print("Unknown device %s", src);
             return;
         }
-        Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst));
+        DeviceId dstDid = deviceId(dst);
+        if (deviceService.getDevice(dstDid) == null) {
+            print("Unknown device %s", dst);
+            return;
+        }
+        Set<? extends Path> paths;
+        if (disjoint) {
+            paths = service.getDisjointPaths(topology, srcDid, dstDid);
+        } else {
+            paths = service.getPaths(topology, srcDid, dstDid);
+        }
         if (outputJson()) {
             print("%s", json(this, paths));
         } else {
             for (Path path : paths) {
                 print(pathString(path));
+                if (path instanceof DisjointPath) {
+                    // print backup right after primary
+                    print(pathString(((DisjointPath) path).backup()));
+                }
             }
         }
     }
@@ -71,13 +94,22 @@
      * @param paths collection of paths
      * @return JSON array
      */
-    public static JsonNode json(AbstractShellCommand context, Iterable<Path> paths) {
-        ObjectMapper mapper = new ObjectMapper();
+    public static JsonNode json(AbstractShellCommand context,
+                                Iterable<? extends Path> paths) {
+        ObjectMapper mapper = context.mapper();
         ArrayNode result = mapper.createArrayNode();
         for (Path path : paths) {
             result.add(LinksListCommand.json(context, path)
                     .put("cost", path.cost())
                     .set("links", LinksListCommand.json(context, path.links())));
+
+            if (path instanceof DisjointPath) {
+                // [ (primay), (backup), ...]
+                DisjointPath backup = (DisjointPath) path;
+                result.add(LinksListCommand.json(context, backup.backup())
+                           .put("cost", backup.cost())
+                           .set("links", LinksListCommand.json(context, backup.links())));
+            }
         }
         return result;
     }
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index da7c4af..8b60699 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -252,6 +252,7 @@
             <completers>
                 <ref component-id="deviceIdCompleter"/>
                 <ref component-id="deviceIdCompleter"/>
+                <null/> <!-- no more arguments -->
             </completers>
         </command>