[ONOS-7731] Update api interface & implementation of openstack vtap app

Change-Id: I7c3c7888b00a7357b13e3b1756e9cd0a1bb6a5c0
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapAddCommand.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapAddCommand.java
index 8d9955f..5272083 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapAddCommand.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapAddCommand.java
@@ -28,13 +28,13 @@
 import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
 
 /**
- * Command line interface for adding openstack vTap rule.
+ * Adds a openstack vtap rule.
  */
 @Command(scope = "onos", name = "openstack-vtap-add",
         description = "OpenstackVtap activate")
 public class OpenstackVtapAddCommand extends AbstractShellCommand {
 
-    private final OpenstackVtapAdminService vTapService =
+    private final OpenstackVtapAdminService vtapService =
                                             get(OpenstackVtapAdminService.class);
 
     @Argument(index = 0, name = "srcIp",
@@ -48,9 +48,9 @@
     String dstIp = "";
 
     @Argument(index = 2, name = "ipProto",
-            description = "IP protocol [tcp|udp|icmp|none]",
+            description = "IP protocol [any|tcp|udp|icmp]",
             required = false, multiValued = false)
-    String ipProto = "";
+    String ipProto = "any";
 
     @Argument(index = 3, name = "srcTpPort",
             description = "source transport layer port (0 is skip)",
@@ -63,43 +63,42 @@
     int dstTpPort = 0;
 
     @Argument(index = 5, name = "type",
-            description = "vTap type [all|tx|rx]",
+            description = "vtap type [all|rx|tx]",
             required = false, multiValued = false)
-    String vTapTypeStr = "all";
+    String vtapTypeStr = "all";
 
     @Override
     protected void execute() {
-        DefaultOpenstackVtapCriterion.Builder
-                    defaultVtapCriterionBuilder = DefaultOpenstackVtapCriterion.builder();
-        if (makeCriterion(defaultVtapCriterionBuilder)) {
-            OpenstackVtap.Type type = getVtapTypeFromString(vTapTypeStr);
+        DefaultOpenstackVtapCriterion.Builder vtapCriterionBuilder = DefaultOpenstackVtapCriterion.builder();
+        if (makeCriterion(vtapCriterionBuilder)) {
+            OpenstackVtap.Type type = getVtapTypeFromString(vtapTypeStr);
             if (type == null) {
-                print("Invalid vTap type");
+                print("Invalid vtap type");
                 return;
             }
 
-            OpenstackVtap vTap = vTapService.createVtap(type, defaultVtapCriterionBuilder.build());
-            if (vTap != null) {
-                print("Created OpenstackVtap with id { %s }", vTap.id().toString());
+            OpenstackVtap vtap = vtapService.createVtap(type, vtapCriterionBuilder.build());
+            if (vtap != null) {
+                print("Created OpenstackVtap with id { %s }", vtap.id().toString());
             } else {
                 print("Failed to create OpenstackVtap");
             }
         }
     }
 
-    private boolean makeCriterion(DefaultOpenstackVtapCriterion.Builder vTapCriterionBuilder) {
+    private boolean makeCriterion(DefaultOpenstackVtapCriterion.Builder vtapCriterionBuilder) {
         try {
-            vTapCriterionBuilder.srcIpPrefix(IpPrefix.valueOf(srcIp));
-            vTapCriterionBuilder.dstIpPrefix(IpPrefix.valueOf(dstIp));
+            vtapCriterionBuilder.srcIpPrefix(IpPrefix.valueOf(srcIp));
+            vtapCriterionBuilder.dstIpPrefix(IpPrefix.valueOf(dstIp));
         } catch (Exception e) {
             print("Inputted valid source IP & destination IP in CIDR (e.g., \"10.1.0.4/32\")");
             return false;
         }
 
-        vTapCriterionBuilder.ipProtocol(getProtocolTypeFromString(ipProto.toLowerCase()));
+        vtapCriterionBuilder.ipProtocol(getProtocolTypeFromString(ipProto.toLowerCase()));
 
-        vTapCriterionBuilder.srcTpPort(TpPort.tpPort(srcTpPort));
-        vTapCriterionBuilder.dstTpPort(TpPort.tpPort(dstTpPort));
+        vtapCriterionBuilder.srcTpPort(TpPort.tpPort(srcTpPort));
+        vtapCriterionBuilder.dstTpPort(TpPort.tpPort(dstTpPort));
 
         return true;
     }
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapDeleteCommand.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapDeleteCommand.java
index e4a167b..e54f6ac 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapDeleteCommand.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapDeleteCommand.java
@@ -22,25 +22,25 @@
 import org.onosproject.openstackvtap.api.OpenstackVtapId;
 
 /**
- * Command line interface for removing openstack vTap rule.
+ * Delete a openstack vtap rule from the existing vtaps.
  */
 @Command(scope = "onos", name = "openstack-vtap-del",
         description = "OpenstackVtap deactivate")
 public class OpenstackVtapDeleteCommand extends AbstractShellCommand {
 
-    private final OpenstackVtapAdminService vTapService = get(OpenstackVtapAdminService.class);
+    private final OpenstackVtapAdminService vtapService = get(OpenstackVtapAdminService.class);
 
-    @Argument(index = 0, name = "id", description = "vTap ID",
+    @Argument(index = 0, name = "id", description = "vtap ID",
             required = true, multiValued = false)
-    String vTapId = "";
+    String vtapId = "";
 
     @Override
     protected void execute() {
-        OpenstackVtap vTap = vTapService.removeVtap(OpenstackVtapId.vTapId(vTapId));
-        if (vTap != null) {
-            print("Removed OpenstackVtap with id { %s }", vTap.id().toString());
+        OpenstackVtap vtap = vtapService.removeVtap(OpenstackVtapId.vtapId(vtapId));
+        if (vtap != null) {
+            print("Removed OpenstackVtap with id { %s }", vtap.id().toString());
         } else {
-            print("Failed to remove OpenstackVtap with id { %s }", vTapId);
+            print("Failed to remove OpenstackVtap with id { %s }", vtapId);
         }
     }
 }
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapListCommand.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapListCommand.java
index afb9bbf..a0989b33d 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapListCommand.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapListCommand.java
@@ -15,46 +15,66 @@
  */
 package org.onosproject.openstackvtap.cli;
 
+import com.google.common.collect.ImmutableSet;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.onosproject.openstackvtap.api.OpenstackVtap;
 import org.onosproject.openstackvtap.api.OpenstackVtapService;
 
+import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
 
 /**
- * Command line interface for listing openstack vTap rules.
+ * Lists openstack vtap rules.
  */
 @Command(scope = "onos", name = "openstack-vtap-list",
         description = "OpenstackVtap list")
 public class OpenstackVtapListCommand extends AbstractShellCommand {
 
-    private final OpenstackVtapService vTapService = get(OpenstackVtapService.class);
+    private final OpenstackVtapService vtapService = get(OpenstackVtapService.class);
+    private final OpenstackNodeService osNodeService = get(OpenstackNodeService.class);
 
     @Argument(index = 0, name = "type",
-            description = "vTap type [all|tx|rx]",
+            description = "vtap type [any|all|rx|tx]",
             required = false, multiValued = false)
-    String vTapType = "none";
+    String vtapType = "any";
 
     private static final String FORMAT = "ID { %s }: type [%s], srcIP [%s], dstIP [%s]";
-    private static final String FORMAT_TX_DEVICES  = "   tx devices: %s";
-    private static final String FORMAT_RX_DEVICES  = "   rx devices: %s";
+    private static final String FORMAT_TX_NODES = "   tx openstack nodes: %s";
+    private static final String FORMAT_RX_NODES = "   rx openstack nodes: %s";
 
     @Override
     protected void execute() {
-        OpenstackVtap.Type type = getVtapTypeFromString(vTapType);
-        Set<OpenstackVtap> openstackVtaps = vTapService.getVtaps(type);
-        for (OpenstackVtap vTap : openstackVtaps) {
+        OpenstackVtap.Type type = getVtapTypeFromString(vtapType);
+        Set<OpenstackVtap> openstackVtaps = vtapService.getVtaps(type);
+        for (OpenstackVtap vtap : openstackVtaps) {
             print(FORMAT,
-                    vTap.id().toString(),
-                    vTap.type().toString(),
-                    vTap.vTapCriterion().srcIpPrefix().toString(),
-                    vTap.vTapCriterion().dstIpPrefix().toString());
-            print(FORMAT_TX_DEVICES, vTap.txDeviceIds());
-            print(FORMAT_RX_DEVICES, vTap.rxDeviceIds());
+                    vtap.id().toString(),
+                    vtap.type().toString(),
+                    vtap.vtapCriterion().srcIpPrefix().toString(),
+                    vtap.vtapCriterion().dstIpPrefix().toString());
+            print(FORMAT_TX_NODES, osNodeNames(vtap.txDeviceIds()));
+            print(FORMAT_RX_NODES, osNodeNames(vtap.rxDeviceIds()));
         }
     }
+
+    private Set<String> osNodeNames(Set<DeviceId> deviceIds) {
+        if (deviceIds == null) {
+            return ImmutableSet.of();
+        } else {
+            return deviceIds.parallelStream()
+                    .map(osNodeService::node)
+                    .filter(Objects::nonNull)
+                    .map(OpenstackNode::hostname)
+                    .collect(Collectors.toSet());
+        }
+    }
+
 }
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapNetworkListCommand.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapNetworkListCommand.java
new file mode 100644
index 0000000..68a94f8
--- /dev/null
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapNetworkListCommand.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackvtap.cli;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
+import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
+import org.onosproject.openstackvtap.api.OpenstackVtapNetwork;
+
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Lists openstack vtap networks.
+ */
+@Command(scope = "onos", name = "openstack-vtap-network-list",
+        description = "OpenstackVtap network list")
+public class OpenstackVtapNetworkListCommand extends AbstractShellCommand {
+
+    private final OpenstackVtapAdminService osVtapAdminService = get(OpenstackVtapAdminService.class);
+    private final OpenstackNodeService osNodeService = get(OpenstackNodeService.class);
+
+    private static final String FORMAT = "mode [%s], networkId [%d], serverIp [%s]";
+    private static final String FORMAT_NODES = "   openstack nodes: %s";
+
+    @Override
+    protected void execute() {
+        OpenstackVtapNetwork vtapNetwork = osVtapAdminService.getVtapNetwork();
+        if (vtapNetwork != null) {
+            print(FORMAT,
+                    vtapNetwork.mode().toString(),
+                    vtapNetwork.networkId() != null ? vtapNetwork.networkId() : "N/A",
+                    vtapNetwork.serverIp().toString());
+            print(FORMAT_NODES, osNodeNames(osVtapAdminService.getVtapNetworkDevices()));
+        }
+    }
+
+    private Set<String> osNodeNames(Set<DeviceId> deviceIds) {
+        if (deviceIds == null) {
+            return ImmutableSet.of();
+        } else {
+            return deviceIds.parallelStream()
+                    .map(osNodeService::node)
+                    .filter(Objects::nonNull)
+                    .map(OpenstackNode::hostname)
+                    .collect(Collectors.toSet());
+        }
+    }
+
+}
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapOutputCommand.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapOutputCommand.java
deleted file mode 100644
index 257cb9a..0000000
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/OpenstackVtapOutputCommand.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.openstackvtap.cli;
-
-import org.apache.karaf.shell.commands.Argument;
-import org.apache.karaf.shell.commands.Command;
-import org.onlab.packet.VlanId;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.openstackvtap.api.OpenstackVtap;
-import org.onosproject.openstackvtap.api.OpenstackVtapAdminService;
-
-import static org.onlab.packet.VlanId.UNTAGGED;
-import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
-
-/**
- * Command line interface for set openstack vTap output.
- */
-@Command(scope = "onos", name = "openstack-vtap-output",
-        description = "OpenstackVtap output setup")
-public class OpenstackVtapOutputCommand extends AbstractShellCommand {
-
-    private final DeviceService deviceService = get(DeviceService.class);
-    private final OpenstackVtapAdminService vTapAdminService =
-                                            get(OpenstackVtapAdminService.class);
-
-    @Argument(index = 0, name = "deviceId", description = "device id",
-            required = true, multiValued = false)
-    String id = "";
-
-    @Argument(index = 1, name = "port", description = "output port number",
-            required = true, multiValued = false)
-    int port = 0;
-
-    @Argument(index = 2, name = "vlan", description = "vlan id",
-            required = false, multiValued = false)
-    int vlan = UNTAGGED;
-
-    @Argument(index = 3, name = "type", description = "vTap type [all|tx|rx]",
-            required = false, multiValued = false)
-    String vTapTypeStr = "all";
-
-    @Override
-    protected void execute() {
-        try {
-            Device device = deviceService.getDevice(DeviceId.deviceId(id));
-            if (device != null) {
-                OpenstackVtap.Type type = getVtapTypeFromString(vTapTypeStr);
-
-                vTapAdminService.setVtapOutput(device.id(), type,
-                        PortNumber.portNumber(port), VlanId.vlanId((short) vlan));
-                print("Set OpenstackVtap output deviceId { %s }, port=%s, vlan=%s",
-                        device.id().toString(),
-                        PortNumber.portNumber(port).toString(),
-                        VlanId.vlanId((short) vlan).toString());
-            } else {
-                print("Invalid device id");
-            }
-        } catch (Exception e) {
-            print("Invalid parameter: %s", e.toString());
-        }
-    }
-}
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/ProtocolTypeCompleter.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/ProtocolTypeCompleter.java
index 3d0f747..3bfcf2b 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/ProtocolTypeCompleter.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/ProtocolTypeCompleter.java
@@ -28,10 +28,10 @@
     @Override
     protected List<String> choices() {
         List<String> strings = Lists.newArrayList();
+        strings.add("any");
         strings.add("tcp");
         strings.add("udp");
         strings.add("icmp");
-        strings.add("none");
         return strings;
     }
 }
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/VtapIdCompleter.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/VtapIdCompleter.java
index c53098d..dad6e8e 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/VtapIdCompleter.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/VtapIdCompleter.java
@@ -27,11 +27,11 @@
 import static org.onosproject.openstackvtap.util.OpenstackVtapUtil.getVtapTypeFromString;
 
 /**
- * vTap ID completer.
+ * Vtap ID completer.
  */
 public class VtapIdCompleter implements Completer {
 
-    private static final String VTAP_TYPE = "none";
+    private static final String VTAP_TYPE = "any";
 
     @Override
     public int complete(String buffer, int cursor, List<String> candidates) {
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/VtapTypeCompleter.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/VtapTypeCompleter.java
index 2784833..c77c913 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/VtapTypeCompleter.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/VtapTypeCompleter.java
@@ -21,16 +21,17 @@
 import java.util.List;
 
 /**
- * vTap type completer.
+ * Vtap type completer.
  */
 public class VtapTypeCompleter extends AbstractChoicesCompleter {
 
     @Override
     protected List<String> choices() {
         List<String> strings = Lists.newArrayList();
-        strings.add("tx");
-        strings.add("rx");
         strings.add("all");
+        strings.add("rx");
+        strings.add("tx");
+        strings.add("any");
         return strings;
     }
 }
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/package-info.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/package-info.java
index 772bbc8..3b3dec1 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/package-info.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/cli/package-info.java
@@ -15,6 +15,6 @@
  */
 
 /**
- * Console commands for OpenStack vtap.
+ * Console commands for openstack vtap.
  */
 package org.onosproject.openstackvtap.cli;
\ No newline at end of file