[ONOS-1959][ONOS-2007][ONOS-2008][ONOS-2009][ONOS-2010][ONOS-2011][ONOS-2016][ONOS-2017][ONOS-2018]
1.fix bug in query subscription command in Tunnel management
2.add RemoveTunnelByIdCommand
3.add UpdateTunnelBandWithCommand
4.add QueryAllTunnelsCommand
5.add queryAllTunnels api in TunnelService and TunnelStore
6.store the Path of the tunnel in the store
7.remove to check parameters iif they are null in the construtors of
DefaultTunnel.e.g
8.add the method of querying in SB
9.Fix the bug that the src/dst end point of Vlan-type tunnel is the
instance of OpticalTunnelEndPoint
10. invert the verb-noun into noun-verb for tunnel commands and label
commands

Change-Id: I90378b37c2bc73b58e6f8f234f009d64f07f758e
diff --git a/cli/src/main/java/org/onosproject/cli/net/TunnelQueryCommand.java b/cli/src/main/java/org/onosproject/cli/net/TunnelQueryCommand.java
index 4e1fe28..e1bf52a 100644
--- a/cli/src/main/java/org/onosproject/cli/net/TunnelQueryCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/TunnelQueryCommand.java
@@ -16,96 +16,209 @@
 package org.onosproject.cli.net;
 
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Optional;
 
-import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
 import org.onlab.packet.IpAddress;
 import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.provider.ProviderId;
 import org.onosproject.incubator.net.tunnel.DefaultOpticalTunnelEndPoint;
 import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
 import org.onosproject.incubator.net.tunnel.OpticalLogicId;
 import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint;
 import org.onosproject.incubator.net.tunnel.Tunnel;
 import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.incubator.net.tunnel.TunnelService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.provider.ProviderId;
 
 /**
- * Supports for querying all tunnels by using IP address and optical as tunnel
- * end point now. It's used by consumers.
+ * Supports for querying tunnels. It's used by consumers.
  */
-@Command(scope = "onos", name = "query-tunnels", description = "Supports for querying all tunnels by using IP address"
-        + " and optical as tunnel end point now."
+@Command(scope = "onos", name = "tunnels", description = "Supports for querying tunnels."
         + " It's used by consumers.")
 public class TunnelQueryCommand extends AbstractShellCommand {
-    @Argument(index = 0, name = "src", description = "Source tunnel point."
+    @Option(name = "-s", aliases = "--src", description = "Source tunnel point."
             + " Only supports for IpTunnelEndPoint and OpticalTunnelEndPoint as end point now."
             + " If deletess a ODUK or OCH type tunnel, the formatter of this argument is DeviceId-PortNumber."
-            + " Otherwise src means IP address.", required = true, multiValued = false)
+            + " Otherwise src means IP address.", required = false, multiValued = false)
     String src = null;
-    @Argument(index = 1, name = "dst", description = "Destination tunnel point."
+    @Option(name = "-d", aliases = "--dst", description = "Destination tunnel point."
             + " Only supports for IpTunnelEndPoint and OpticalTunnelEndPoint as end point now."
             + " If deletess a ODUK or OCH type tunnel, the formatter of this argument is DeviceId-PortNumber."
-            + " Otherwise dst means IP address.", required = true, multiValued = false)
+            + " Otherwise dst means IP address.", required = false, multiValued = false)
     String dst = null;
 
-    @Argument(index = 2, name = "type", description = "The type of tunnels,"
-            + " It includes MPLS, VLAN, VXLAN, GRE, ODUK, OCH", required = true, multiValued = false)
+    @Option(name = "-t", aliases = "--type", description = "The type of tunnels,"
+            + " It includes MPLS, VLAN, VXLAN, GRE, ODUK, OCH", required = false, multiValued = false)
     String type = null;
 
-    private static final String FMT = "src=%s, dst=%s,"
+    @Option(name = "-i", aliases = "--tunnelId",
+            description = "the tunnel identity.", required = false, multiValued = false)
+    String tunnelId = null;
+
+    private static final String FMT = "tunnelId=%s, src=%s, dst=%s,"
             + "type=%s, state=%s, producerName=%s, tunnelName=%s,"
-            + "groupId=%s";
+            + "groupId=%s, path=%s%s";
 
     @Override
     protected void execute() {
+        Tunnel.Type trueType = null;
         TunnelService service = get(TunnelService.class);
         ProviderId producerName = new ProviderId("default",
                                                  "org.onosproject.provider.tunnel.default");
-        TunnelEndPoint srcPoint = null;
-        TunnelEndPoint dstPoint = null;
-        if ("MPLS".equals(type) || "VLAN".equals(type) || "VXLAN".equals(type)
-                || "GRE".equals(type)) {
-            srcPoint = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(src));
-            dstPoint = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(dst));
-        } else if ("ODUK".equals(type) || "OCH".equals(type)) {
-            String[] srcArray = src.split("-");
-            String[] dstArray = dst.split("-");
-            srcPoint = new DefaultOpticalTunnelEndPoint(
-                                                        producerName,
-                                                        Optional.of(DeviceId
-                                                                .deviceId(srcArray[0])),
-                                                        Optional.of(PortNumber
-                                                                .portNumber(srcArray[1])),
-                                                        null,
-                                                        OpticalTunnelEndPoint.Type.LAMBDA,
-                                                        OpticalLogicId
-                                                                .logicId(0),
-                                                        true);
-            dstPoint = new DefaultOpticalTunnelEndPoint(
-                                                        producerName,
-                                                        Optional.of(DeviceId
-                                                                .deviceId(dstArray[0])),
-                                                        Optional.of(PortNumber
-                                                                .portNumber(dstArray[1])),
-                                                        null,
-                                                        OpticalTunnelEndPoint.Type.LAMBDA,
-                                                        OpticalLogicId
-                                                                .logicId(0),
-                                                        true);
-        } else {
-            print("Illegal tunnel type. Please input MPLS, VLAN, VXLAN, GRE, ODUK or OCH.");
-            return;
+        Collection<Tunnel> tunnelSet = null;
+        if (isNull(src) && isNull(dst) && isNull(type) && isNull(tunnelId)) {
+            tunnelSet = service.queryAllTunnels();
         }
-        Collection<Tunnel> tunnelSet = service.queryTunnel(srcPoint, dstPoint);
-        for (Tunnel tunnel : tunnelSet) {
-            print(FMT, tunnel.src().toString(), tunnel.dst().toString(), tunnel.type(),
-                  tunnel.state(), tunnel.providerId(), tunnel.tunnelName(),
-                  tunnel.groupId());
+
+        if (!isNull(src) && !isNull(dst) && !isNull(type)) {
+            TunnelEndPoint srcPoint = null;
+            TunnelEndPoint dstPoint = null;
+            if ("MPLS".equals(type) || "VXLAN".equals(type)
+                    || "GRE".equals(type)) {
+                srcPoint = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+                        .valueOf(src));
+                dstPoint = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+                        .valueOf(dst));
+            } else if ("VLAN".equals(type)) {
+                String[] srcArray = src.split("-");
+                String[] dstArray = dst.split("-");
+                srcPoint = new DefaultOpticalTunnelEndPoint(
+                                                            producerName,
+                                                            Optional.of(DeviceId
+                                                                    .deviceId(srcArray[0])),
+                                                            Optional.of(PortNumber
+                                                                    .portNumber(srcArray[1])),
+                                                            null,
+                                                            null,
+                                                            OpticalLogicId
+                                                                    .logicId(0),
+                                                            true);
+                dstPoint = new DefaultOpticalTunnelEndPoint(
+                                                            producerName,
+                                                            Optional.of(DeviceId
+                                                                    .deviceId(dstArray[0])),
+                                                            Optional.of(PortNumber
+                                                                    .portNumber(dstArray[1])),
+                                                            null,
+                                                            null,
+                                                            OpticalLogicId
+                                                                    .logicId(0),
+                                                            true);
+            } else if ("ODUK".equals(type)) {
+                String[] srcArray = src.split("-");
+                String[] dstArray = dst.split("-");
+                srcPoint = new DefaultOpticalTunnelEndPoint(
+                                                            producerName,
+                                                            Optional.of(DeviceId
+                                                                    .deviceId(srcArray[0])),
+                                                            Optional.of(PortNumber
+                                                                    .portNumber(srcArray[1])),
+                                                            null,
+                                                            OpticalTunnelEndPoint.Type.LAMBDA,
+                                                            OpticalLogicId
+                                                                    .logicId(0),
+                                                            true);
+                dstPoint = new DefaultOpticalTunnelEndPoint(
+                                                            producerName,
+                                                            Optional.of(DeviceId
+                                                                    .deviceId(dstArray[0])),
+                                                            Optional.of(PortNumber
+                                                                    .portNumber(dstArray[1])),
+                                                            null,
+                                                            OpticalTunnelEndPoint.Type.LAMBDA,
+                                                            OpticalLogicId
+                                                                    .logicId(0),
+                                                            true);
+            } else if ("OCH".equals(type)) {
+                String[] srcArray = src.split("-");
+                String[] dstArray = dst.split("-");
+                srcPoint = new DefaultOpticalTunnelEndPoint(
+                                                            producerName,
+                                                            Optional.of(DeviceId
+                                                                    .deviceId(srcArray[0])),
+                                                            Optional.of(PortNumber
+                                                                    .portNumber(srcArray[1])),
+                                                            null,
+                                                            OpticalTunnelEndPoint.Type.TIMESLOT,
+                                                            OpticalLogicId
+                                                                    .logicId(0),
+                                                            true);
+                dstPoint = new DefaultOpticalTunnelEndPoint(
+                                                            producerName,
+                                                            Optional.of(DeviceId
+                                                                    .deviceId(dstArray[0])),
+                                                            Optional.of(PortNumber
+                                                                    .portNumber(dstArray[1])),
+                                                            null,
+                                                            OpticalTunnelEndPoint.Type.TIMESLOT,
+                                                            OpticalLogicId
+                                                                    .logicId(0),
+                                                            true);
+            } else {
+                print("Illegal tunnel type. Please input MPLS, VLAN, VXLAN, GRE, ODUK or OCH.");
+                return;
+            }
+            tunnelSet = service.queryTunnel(srcPoint, dstPoint);
+        }
+        if (!isNull(type)) {
+            if ("MPLS".equals(type)) {
+                trueType = Tunnel.Type.MPLS;
+            } else if ("VLAN".equals(type)) {
+                trueType = Tunnel.Type.VLAN;
+            } else if ("VXLAN".equals(type)) {
+                trueType = Tunnel.Type.VXLAN;
+            } else if ("GRE".equals(type)) {
+                trueType = Tunnel.Type.GRE;
+            } else if ("ODUK".equals(type)) {
+                trueType = Tunnel.Type.ODUK;
+            } else if ("OCH".equals(type)) {
+                trueType = Tunnel.Type.OCH;
+            } else {
+                print("Illegal tunnel type. Please input MPLS, VLAN, VXLAN, GRE, ODUK or OCH.");
+                return;
+            }
+            tunnelSet = service.queryTunnel(trueType);
+        }
+        if (!isNull(tunnelId)) {
+            TunnelId id = TunnelId.valueOf(tunnelId);
+            Tunnel tunnel = service.queryTunnel(id);
+            tunnelSet = new HashSet<Tunnel>();
+            tunnelSet.add(tunnel);
+        }
+        if (tunnelSet != null) {
+            for (Tunnel tunnel : tunnelSet) {
+                print(FMT, tunnel.tunnelId(), tunnel.src().toString(), tunnel.dst().toString(),
+                      tunnel.type(), tunnel.state(), tunnel.providerId(),
+                      tunnel.tunnelName(), tunnel.groupId(),
+                      showPath(tunnel.path()),
+                      annotations(tunnel.annotations()));
+            }
         }
     }
 
+    private String showPath(Path path) {
+        if (path == null) {
+            return "";
+        }
+        StringBuilder builder = new StringBuilder("(");
+        for (Link link : path.links()) {
+            builder.append("(DeviceId:" + link.src().deviceId() + " Port:"
+                    + link.src().port().toString());
+            builder.append(" DeviceId:" + link.dst().deviceId() + " Port:"
+                    + link.dst().port().toString() + ")");
+        }
+        builder.append(annotations(path.annotations()) + ")");
+        return builder.toString();
+    }
+
+    private boolean isNull(String s) {
+        return s == null || "".equals(s);
+    }
 }