Extend host structures to store multiple locations

Also update host location format in CLI and REST API

Change-Id: I0fbd655f642627dd3eb8a2925f83a3ee016fe4aa
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/HostCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/HostCodec.java
index b5f9b02..233d61d 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/HostCodec.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/HostCodec.java
@@ -47,7 +47,12 @@
             jsonIpAddresses.add(ipAddress.toString());
         }
         result.set("ipAddresses", jsonIpAddresses);
-        result.set("location", locationCodec.encode(host.location(), context));
+
+        final ArrayNode jsonLocations = result.putArray("locations");
+        for (final HostLocation location : host.locations()) {
+            jsonLocations.add(locationCodec.encode(location, context));
+        }
+        result.set("locations", jsonLocations);
 
         return annotate(result, host, context);
     }
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/VirtualHostCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/VirtualHostCodec.java
index 05ce81e..d6a7c80 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/VirtualHostCodec.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/VirtualHostCodec.java
@@ -49,7 +49,7 @@
     static final String MAC_ADDRESS = "mac";
     static final String VLAN = "vlan";
     static final String IP_ADDRESSES = "ipAddresses";
-    static final String HOST_LOCATION = "location";
+    static final String HOST_LOCATION = "locations";
 
     private static final String NULL_OBJECT_MSG = "VirtualHost cannot be null";
     private static final String MISSING_MEMBER_MSG = " member is required in VirtualHost";
@@ -71,7 +71,12 @@
             jsonIpAddresses.add(ipAddress.toString());
         }
         result.set(IP_ADDRESSES, jsonIpAddresses);
-        result.set(HOST_LOCATION, locationCodec.encode(vHost.location(), context));
+
+        final ArrayNode jsonLocations = result.putArray("locations");
+        for (final HostLocation location : vHost.locations()) {
+            jsonLocations.add(locationCodec.encode(location, context));
+        }
+        result.set("locations", jsonLocations);
 
         return result;
     }
@@ -85,10 +90,15 @@
         NetworkId nId = NetworkId.networkId(Long.parseLong(extractMember(NETWORK_ID, json)));
         MacAddress mac = MacAddress.valueOf(json.get("mac").asText());
         VlanId vlanId = VlanId.vlanId((short) json.get("vlan").asInt(VlanId.UNTAGGED));
-        JsonNode locationNode = json.get("location");
-        PortNumber portNumber = PortNumber.portNumber(locationNode.get("port").asText());
-        DeviceId deviceId = DeviceId.deviceId(locationNode.get("elementId").asText());
-        HostLocation hostLocation = new HostLocation(deviceId, portNumber, 0);
+
+        Set<HostLocation> locations = new HashSet<>();
+        JsonNode locationNodes = json.get("locations");
+        locationNodes.forEach(locationNode -> {
+            PortNumber portNumber = PortNumber.portNumber(locationNode.get("port").asText());
+            DeviceId deviceId = DeviceId.deviceId(locationNode.get("elementId").asText());
+            locations.add(new HostLocation(deviceId, portNumber, 0));
+        });
+
         HostId id = HostId.hostId(mac, vlanId);
 
         Iterator<JsonNode> ipStrings = json.get("ipAddresses").elements();
@@ -97,7 +107,7 @@
             ips.add(IpAddress.valueOf(ipStrings.next().asText()));
         }
 
-        return new DefaultVirtualHost(nId, id, mac, vlanId, hostLocation, ips);
+        return new DefaultVirtualHost(nId, id, mac, vlanId, locations, ips);
     }
 
     /**