CORD-339 Network config host provider

* Implement new application org.onosproject.netcfghost
* Implement BasicHostConfig to include IP and location information
    - Update network-cfg.json to add host config example
    - Add network-cfg-2x2-leaf-spine.json for 2x2 leaf-spine network in SegmentRouting
* Update Segment Rounting
    - Punt ARP packets
      (which is done by HostLocationProvider previously)
    - Check existing hosts when device connected or configured

Change-Id: I03986ddc8203d740b5bf26903e3dbf866d4d4600
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 2fe2b2c..9294631 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
@@ -15,13 +15,83 @@
  */
 package org.onosproject.net.config.basics;
 
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.HostId;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Basic configuration for network end-station hosts.
  */
 public class BasicHostConfig extends BasicElementConfig<HostId> {
+    private static final String IPS = "ips";
+    private static final String LOCATION = "location";
 
-    // TODO: determine what aspects of configuration to add for hosts
+    @Override
+    public boolean isValid() {
+        return hasOnlyFields(IPS, LOCATION) &&
+                this.location() != null &&
+                this.ipAddresses() != null;
+    }
 
+    /**
+     * Gets location of the host.
+     *
+     * @return location of the host. Or null if not specified with correct format.
+     */
+    public ConnectPoint location() {
+        String location = get(LOCATION, null);
+
+        if (location != null) {
+            try {
+                return ConnectPoint.deviceConnectPoint(location);
+            } catch (Exception e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Sets the location of the host.
+     *
+     * @param location location of the host.
+     * @return the config of the host.
+     */
+    public BasicHostConfig setLocation(String location) {
+        return (BasicHostConfig) setOrClear(LOCATION, location);
+    }
+
+    /**
+     * Gets IP addresses of the host.
+     *
+     * @return IP addresses of the host. Or null if not specified with correct format.
+     */
+    public Set<IpAddress> ipAddresses() {
+        HashSet<IpAddress> ipAddresses = new HashSet<>();
+        if (object.has(IPS)) {
+            ArrayNode ipNodes = (ArrayNode) object.path(IPS);
+            try {
+                ipNodes.forEach(ipNode -> {
+                    ipAddresses.add(IpAddress.valueOf(ipNode.asText()));
+                });
+                return ipAddresses;
+            } catch (Exception e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Sets the IP addresses of the host.
+     *
+     * @param ipAddresses IP addresses of the host.
+     * @return the config of the host.
+     */
+    public BasicHostConfig setIps(Set<IpAddress> ipAddresses) {
+        return (BasicHostConfig) setOrClear(IPS, ipAddresses);
+    }
 }