Added CLI and REST support for auxLocations

Change-Id: I04e78f766dcbb18bce4a2f9160d3740ec2fbd846
(cherry picked from commit eb5bd4998289bf78862db927d58b76cb12979459)
diff --git a/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java b/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
index 3d19003..6e546a8 100644
--- a/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
@@ -36,6 +36,7 @@
 
     private static final String IPS = "ips";
     private static final String LOCATIONS = "locations";
+    private static final String AUX_LOCATIONS = "auxLocations";
     private static final String INNER_VLAN = "innerVlan";
     private static final String OUTER_TPID = "outerTpid";
     private static final String DASH = "-";
@@ -56,8 +57,9 @@
                               EthType.EtherType.VLAN.ethType().toShort());
         this.locations();
         this.ipAddresses();
+        this.auxLocations();
         return hasOnlyFields(ALLOWED, NAME, LOC_TYPE, LATITUDE, LONGITUDE, ROLES,
-                             GRID_X, GRID_Y, UI_TYPE, RACK_ADDRESS, OWNER, IPS, LOCATIONS,
+                             GRID_X, GRID_Y, UI_TYPE, RACK_ADDRESS, OWNER, IPS, LOCATIONS, AUX_LOCATIONS,
                              INNER_VLAN, OUTER_TPID);
     }
 
@@ -102,6 +104,29 @@
     }
 
     /**
+     * Returns the auxLocations of the host.
+     *
+     * @return auxLocations of the host or null if none specified
+     * @throws IllegalArgumentException if auxLocations are set but empty or not
+     *                                  specified with correct format
+     */
+    public Set<HostLocation> auxLocations() {
+        if (!object.has(AUX_LOCATIONS)) {
+            return null; //no auxLocations are specified
+        }
+
+        ImmutableSet.Builder<HostLocation> auxLocationsSetBuilder = ImmutableSet.<HostLocation>builder();
+
+        ArrayNode auxLocationNodes = (ArrayNode) object.path(AUX_LOCATIONS);
+        auxLocationNodes.forEach(n -> {
+            ConnectPoint cp = ConnectPoint.deviceConnectPoint((n.asText()));
+            auxLocationsSetBuilder.add(new HostLocation(cp, 0));
+        });
+
+        return auxLocationsSetBuilder.build();
+    }
+
+    /**
      * Sets the location of the host.
      *
      * @param locations location of the host or null to unset
@@ -112,6 +137,17 @@
     }
 
     /**
+     * Sets the auxLocations of the host.
+     *
+     * @param auxLocations auxLocations of the host or null to unset
+     * @return the config of the host
+     */
+    public BasicHostConfig setAuxLocations(Set<HostLocation> auxLocations) {
+        return (BasicHostConfig) setOrClear(AUX_LOCATIONS, auxLocations);
+    }
+
+
+    /**
      * Returns IP addresses of the host.
      *
      * @return IP addresses of the host or null if not set
diff --git a/core/api/src/test/java/org/onosproject/net/config/basics/BasicHostConfigTest.java b/core/api/src/test/java/org/onosproject/net/config/basics/BasicHostConfigTest.java
index dab2c9d..34b53f0 100644
--- a/core/api/src/test/java/org/onosproject/net/config/basics/BasicHostConfigTest.java
+++ b/core/api/src/test/java/org/onosproject/net/config/basics/BasicHostConfigTest.java
@@ -55,6 +55,11 @@
         HostLocation loc2 = new HostLocation(
                 NetTestTools.connectPoint("d2", 2), System.currentTimeMillis());
         Set<HostLocation> locs = ImmutableSet.of(loc1, loc2);
+        HostLocation loc3 = new HostLocation(
+                NetTestTools.connectPoint("d3", 1), System.currentTimeMillis());
+        HostLocation loc4 = new HostLocation(
+                NetTestTools.connectPoint("d4", 2), System.currentTimeMillis());
+        Set<HostLocation> auxLocations = ImmutableSet.of(loc3, loc4);
         VlanId vlanId = VlanId.vlanId((short) 10);
         EthType ethType = EthType.EtherType.lookup((short) 0x88a8).ethType();
 
@@ -62,6 +67,7 @@
 
         config.setIps(ips)
               .setLocations(locs)
+              .setAuxLocations(auxLocations)
               .setInnerVlan(vlanId)
               .setOuterTpid(ethType);
 
@@ -71,6 +77,8 @@
         assertThat(config.ipAddresses(), hasItems(ip1, ip2, ip3));
         assertThat(config.locations(), hasSize(2));
         assertThat(config.locations(), hasItems(loc1, loc2));
+        assertThat(config.auxLocations(), hasSize(2));
+        assertThat(config.auxLocations(), hasItems(loc3, loc4));
         assertThat(config.innerVlan(), is(vlanId));
         assertThat(config.outerTpid(), is(ethType));
     }
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 5f8ca9d..d2890a4 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
@@ -56,6 +56,14 @@
         }
         result.set("locations", jsonLocations);
 
+        if (host.auxLocations() != null) {
+            final ArrayNode jsonAuxLocations = result.putArray("auxLocations");
+            for (final HostLocation auxLocation : host.auxLocations()) {
+                jsonAuxLocations.add(locationCodec.encode(auxLocation, context));
+            }
+            result.set("auxLocations", jsonAuxLocations);
+        }
+
         return annotate(result, host, context);
     }
 
diff --git a/core/net/src/main/java/org/onosproject/net/host/impl/BasicHostOperator.java b/core/net/src/main/java/org/onosproject/net/host/impl/BasicHostOperator.java
index b196737..26bfdeb 100644
--- a/core/net/src/main/java/org/onosproject/net/host/impl/BasicHostOperator.java
+++ b/core/net/src/main/java/org/onosproject/net/host/impl/BasicHostOperator.java
@@ -61,6 +61,14 @@
                     .collect(Collectors.toSet());
         }
 
+        Set<HostLocation> auxLocations = descr.auxLocations();
+        Set<HostLocation> cfgAuxLocations = cfg.auxLocations();
+        if (cfgAuxLocations != null) {
+            auxLocations = cfgAuxLocations.stream()
+                    .map(hostLocation -> new HostLocation(hostLocation, System.currentTimeMillis()))
+                    .collect(Collectors.toSet());
+        }
+
         Set<IpAddress> ipAddresses = descr.ipAddress();
         Set<IpAddress> cfgIpAddresses = cfg.ipAddresses();
         if (cfgIpAddresses != null) {
@@ -69,7 +77,7 @@
 
         SparseAnnotations sa = combine(cfg, descr.annotations());
         return new DefaultHostDescription(descr.hwAddress(), descr.vlan(),
-                                          locations, ipAddresses, descr.innerVlan(),
+                                          locations, auxLocations, ipAddresses, descr.innerVlan(),
                                           descr.tpid(), descr.configured(), sa);
     }