Some improvements on cordvtn

- Removed unnecessary CordVtnNodeConfig class
- Don't allow local and host management IP range overlapping
- Check node init state saved in the store instead of really check when a
  VM is detected or vanished since it's too slow

Change-Id: I076780bdc3946b2000176cb05805003ba7c8724d
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfig.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfig.java
index ec83432..a44ec21 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfig.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfig.java
@@ -18,6 +18,7 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+import org.onlab.packet.Ip4Address;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.TpPort;
@@ -29,7 +30,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -45,11 +45,12 @@
     public static final String GATEWAY_MAC = "gatewayMac";
     public static final String LOCAL_MANAGEMENT_IP = "localManagementIp";
     public static final String OVSDB_PORT = "ovsdbPort";
+
     public static final String SSH_PORT = "sshPort";
     public static final String SSH_USER = "sshUser";
     public static final String SSH_KEY_FILE = "sshKeyFile";
-    public static final String CORDVTN_NODES = "nodes";
 
+    public static final String CORDVTN_NODES = "nodes";
     public static final String HOSTNAME = "hostname";
     public static final String HOST_MANAGEMENT_IP = "hostManagementIp";
     public static final String DATA_PLANE_IP = "dataPlaneIp";
@@ -61,31 +62,70 @@
      *
      * @return set of CordVtnNodeConfig or null
      */
-    public Set<CordVtnNodeConfig> cordVtnNodes() {
-        Set<CordVtnNodeConfig> nodes = Sets.newHashSet();
+    public Set<CordVtnNode> cordVtnNodes() {
 
+        Set<CordVtnNode> nodes = Sets.newHashSet();
         JsonNode jsonNodes = object.get(CORDVTN_NODES);
         if (jsonNodes == null) {
+            log.debug("No CORD VTN nodes found");
             return null;
         }
 
-        jsonNodes.forEach(jsonNode -> {
+        for (JsonNode jsonNode : jsonNodes) {
             try {
-                nodes.add(new CordVtnNodeConfig(
-                        jsonNode.path(HOSTNAME).asText(),
-                        NetworkAddress.valueOf(jsonNode.path(HOST_MANAGEMENT_IP).asText()),
-                        NetworkAddress.valueOf(jsonNode.path(DATA_PLANE_IP).asText()),
-                        jsonNode.path(DATA_PLANE_INTF).asText(),
-                        DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText())));
+                NetworkAddress hostMgmt = NetworkAddress.valueOf(getConfig(jsonNode, HOST_MANAGEMENT_IP));
+                NetworkAddress localMgmt = NetworkAddress.valueOf(getConfig(object, LOCAL_MANAGEMENT_IP));
+                if (hostMgmt.prefix().contains(localMgmt.prefix()) ||
+                        localMgmt.prefix().contains(hostMgmt.prefix())) {
+                    log.error("hostMamt and localMgmt cannot be overlapped, skip this node");
+                    continue;
+                }
+
+                Ip4Address hostMgmtIp = hostMgmt.ip().getIp4Address();
+                SshAccessInfo sshInfo = new SshAccessInfo(
+                        hostMgmtIp,
+                        TpPort.tpPort(Integer.parseInt(getConfig(object, SSH_PORT))),
+                        getConfig(object, SSH_USER), getConfig(object, SSH_KEY_FILE));
+
+                String hostname = getConfig(jsonNode, HOSTNAME);
+                CordVtnNode newNode = new CordVtnNode(
+                        hostname, hostMgmt, localMgmt,
+                        NetworkAddress.valueOf(getConfig(jsonNode, DATA_PLANE_IP)),
+                        TpPort.tpPort(Integer.parseInt(getConfig(object, OVSDB_PORT))),
+                        sshInfo,
+                        DeviceId.deviceId(getConfig(jsonNode, BRIDGE_ID)),
+                        getConfig(jsonNode, DATA_PLANE_INTF));
+
+                log.info("Successfully read {} from the config", hostname);
+                nodes.add(newNode);
             } catch (IllegalArgumentException | NullPointerException e) {
-                log.error("Failed to read {}", e.toString());
+                log.error("{}", e.toString());
             }
-        });
+        }
 
         return nodes;
     }
 
     /**
+     * Returns value of a given path. If the path is missing, show log and return
+     * null.
+     *
+     * @param path path
+     * @return value or null
+     */
+    private String getConfig(JsonNode jsonNode, String path) {
+        jsonNode = jsonNode.path(path);
+
+        if (jsonNode.isMissingNode()) {
+            log.error("{} is not configured", path);
+            return null;
+        } else {
+            log.debug("{} : {}", path, jsonNode.asText());
+            return jsonNode.asText();
+        }
+    }
+
+    /**
      * Returns private network gateway MAC address.
      *
      * @return mac address, or null
@@ -112,7 +152,7 @@
     public Map<IpAddress, MacAddress> publicGateways() {
         JsonNode jsonNodes = object.get(PUBLIC_GATEWAYS);
         if (jsonNodes == null) {
-            return null;
+            return Maps.newHashMap();
         }
 
         Map<IpAddress, MacAddress> publicGateways = Maps.newHashMap();
@@ -128,155 +168,5 @@
 
         return publicGateways;
     }
-
-    /**
-     * Returns local management network address.
-     *
-     * @return network address
-     */
-    public NetworkAddress localMgmtIp() {
-        JsonNode jsonNode = object.get(LOCAL_MANAGEMENT_IP);
-        if (jsonNode == null) {
-            return null;
-        }
-
-        try {
-            return NetworkAddress.valueOf(jsonNode.asText());
-        } catch (IllegalArgumentException e) {
-            log.error("Wrong address format {}", jsonNode.asText());
-            return null;
-        }
-    }
-
-    /**
-     * Returns the port number used for OVSDB connection.
-     *
-     * @return port number, or null
-     */
-    public TpPort ovsdbPort() {
-        JsonNode jsonNode = object.get(OVSDB_PORT);
-        if (jsonNode == null) {
-            return null;
-        }
-
-        try {
-            return TpPort.tpPort(jsonNode.asInt());
-        } catch (IllegalArgumentException e) {
-            log.error("Wrong TCP port format {}", jsonNode.asText());
-            return null;
-        }
-    }
-
-    /**
-     * Returns the port number used for SSH connection.
-     *
-     * @return port number, or null
-     */
-    public TpPort sshPort() {
-        JsonNode jsonNode = object.get(SSH_PORT);
-        if (jsonNode == null) {
-            return null;
-        }
-
-        try {
-            return TpPort.tpPort(jsonNode.asInt());
-        } catch (IllegalArgumentException e) {
-            log.error("Wrong TCP port format {}", jsonNode.asText());
-            return null;
-        }
-    }
-
-    /**
-     * Returns the user name for SSH connection.
-     *
-     * @return user name, or null
-     */
-    public String sshUser() {
-        JsonNode jsonNode = object.get(SSH_USER);
-        if (jsonNode == null) {
-            return null;
-        }
-
-        return jsonNode.asText();
-    }
-
-    /**
-     * Returns the private key file for SSH connection.
-     *
-     * @return file path, or null
-     */
-    public String sshKeyFile() {
-        JsonNode jsonNode = object.get(SSH_KEY_FILE);
-        if (jsonNode == null) {
-            return null;
-        }
-
-        return jsonNode.asText();
-    }
-
-    /**
-     * Configuration for CordVtn node.
-     */
-    public static class CordVtnNodeConfig {
-
-        private final String hostname;
-        private final NetworkAddress hostMgmtIp;
-        private final NetworkAddress dpIp;
-        private final String dpIntf;
-        private final DeviceId bridgeId;
-
-        public CordVtnNodeConfig(String hostname, NetworkAddress hostMgmtIp, NetworkAddress dpIp,
-                                 String dpIntf, DeviceId bridgeId) {
-            this.hostname = checkNotNull(hostname);
-            this.hostMgmtIp = checkNotNull(hostMgmtIp);
-            this.dpIp = checkNotNull(dpIp);
-            this.dpIntf = checkNotNull(dpIntf);
-            this.bridgeId = checkNotNull(bridgeId);
-        }
-
-        /**
-         * Returns hostname of the node.
-         *
-         * @return hostname
-         */
-        public String hostname() {
-            return this.hostname;
-        }
-
-        /**
-         * Returns the host management network address of the node.
-         *
-         * @return management network address
-         */
-        public NetworkAddress hostMgmtIp() {
-            return this.hostMgmtIp;
-        }
-
-        /**
-         * Returns the data plane network address.
-         *
-         * @return network address
-         */
-        public NetworkAddress dpIp() {
-            return this.dpIp;
-        }
-
-        /**
-         * Returns the data plane interface name.
-         *
-         * @return interface name
-         */
-        public String dpIntf() {
-            return this.dpIntf;
-        }
-
-        /**
-         * Returns integration bridge id of the node.
-         *
-         * @return device id
-         */
-        public DeviceId bridgeId() {
-            return this.bridgeId;
-        }
-    }
 }
+