Adding Gluon App code to support EVPN

Change-Id: I24aee104482a166e412e5e7b42ea1dbf518d51c6
diff --git a/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/GluonServerCommand.java b/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/GluonServerCommand.java
new file mode 100755
index 0000000..6dec71f
--- /dev/null
+++ b/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/GluonServerCommand.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2017-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.gluon.rsc.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.gluon.rsc.GluonServer;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.onosproject.gluon.manager.GluonManager.createServer;
+import static org.onosproject.gluon.rsc.GluonConstants.GLUON_DEFAULT_PORT;
+import static org.onosproject.gluon.rsc.GluonConstants.GLUON_HTTP;
+import static org.onosproject.gluon.rsc.GluonConstants.INVALID_MODE;
+import static org.onosproject.gluon.rsc.GluonConstants.INVALID_RANGE;
+import static org.onosproject.gluon.rsc.GluonConstants.KEY_TYPE;
+import static org.onosproject.gluon.rsc.GluonConstants.MODE_START;
+import static org.onosproject.gluon.rsc.GluonConstants.MODE_STOP;
+import static org.onosproject.gluon.rsc.GluonConstants.NO_SERVER_AVAIL;
+import static org.onosproject.gluon.rsc.GluonConstants.NO_SERVER_AVAIL_ON_PORT;
+import static org.onosproject.gluon.rsc.GluonConstants.PROTON_KEY_SUPPORT;
+import static org.onosproject.gluon.rsc.GluonConstants.WRONG_INPUT;
+import static org.onosproject.gluon.rsc.GluonConstants.WRONG_INPUT_TYPE;
+import static org.onosproject.gluon.rsc.GluonConstants.WRONG_IP_FORMAT;
+
+
+/**
+ * To monitor Gluon etcd server.
+ */
+@Command(scope = "onos", name = "gluon",
+        description = "Support for reading Gluon data via etcd client")
+public class GluonServerCommand extends AbstractShellCommand {
+
+    @Option(name = "-m", aliases = "--mode",
+            description = "Gluon server monitoring mode: start; stop",
+            required = false, multiValued = false)
+    String mode = MODE_START;
+
+    @Option(name = "-i", aliases = "--server-ip",
+            description = "Gluon server ip address",
+            required = true, multiValued = false)
+    String ipAddress = null;
+
+    @Option(name = "-p", aliases = "--port", description = "Gluon server port",
+            required = false, multiValued = false)
+    String port = GLUON_DEFAULT_PORT;
+
+    @Option(name = "-k", aliases = "--key",
+            description = "Proton key : net-l3vpn",
+            required = false, multiValued = false)
+    String protonKey = KEY_TYPE;
+
+    public String version = null;
+
+    @Override
+    public void execute() {
+        try {
+            if (ipAddress != null && isValidIP(ipAddress) && isValidPort(port)
+                    && isValidMode(mode) && isValidProtonKey(protonKey)
+                    && isSeverReachable()) {
+                String url = GLUON_HTTP + ipAddress + ":" + port;
+                if (isEtcdSeverAvailable()) {
+                    //Gets gluon server running version
+                    version = gluonServerVersion();
+                    createServer(url, protonKey, mode, version);
+                } else {
+                    log.info(NO_SERVER_AVAIL_ON_PORT);
+                    return;
+                }
+            } else {
+                log.info(WRONG_INPUT);
+            }
+        } catch (Exception e) {
+            print(null, e.getMessage());
+        }
+    }
+
+    /**
+     * Returns boolean if given IP format is valid.
+     *
+     * @param ipAddr Ip Address
+     * @return boolean
+     */
+    public boolean isValidIP(String ipAddr) {
+        boolean isIPaddrValid;
+        Pattern pattern = Pattern.compile("^(\\d{1,3})\\" +
+                                                  ".(\\d{1,3})\\" +
+                                                  ".(\\d{1,3})\\.(\\d{1,3})$");
+        Matcher matcher = pattern.matcher(ipAddr);
+        if (matcher.find()) {
+            isIPaddrValid = true;
+        } else {
+            print(WRONG_IP_FORMAT);
+            isIPaddrValid = false;
+        }
+        return isIPaddrValid;
+    }
+
+    /**
+     * Returns boolean if given port value is valid.
+     *
+     * @param portValue port number
+     * @return boolean
+     */
+    public boolean isValidPort(String portValue) {
+        boolean isPortValid = false;
+        try {
+            Integer portNum = Integer.parseInt(portValue);
+            if (portNum >= 0 && portNum <= 65535) {
+                isPortValid = true;
+            } else {
+                print(INVALID_RANGE);
+                isPortValid = false;
+            }
+        } catch (NumberFormatException nfe) {
+            print(WRONG_INPUT_TYPE);
+        }
+        return isPortValid;
+    }
+
+    /**
+     * Returns boolean if given mode is valid.
+     *
+     * @param mode server mode
+     * @return boolean
+     */
+    public boolean isValidMode(String mode) {
+        boolean isValidMode;
+        if (mode.equalsIgnoreCase(MODE_START) ||
+                mode.equalsIgnoreCase(MODE_STOP)) {
+            isValidMode = true;
+        } else {
+            print(INVALID_MODE);
+            isValidMode = false;
+        }
+        return isValidMode;
+    }
+
+    /**
+     * Returns boolean if given mode is valid.
+     *
+     * @param key key
+     * @return boolean
+     */
+    public boolean isValidProtonKey(String key) {
+        boolean isValidProtonKey = true;
+        if (!KEY_TYPE.equalsIgnoreCase(key)) {
+            print(PROTON_KEY_SUPPORT);
+            isValidProtonKey = false;
+        }
+        return isValidProtonKey;
+    }
+
+    /**
+     * Returns version of gluon server.
+     *
+     * @return String
+     */
+
+    public String gluonServerVersion() {
+        String serverUrl = GLUON_HTTP + this.ipAddress + ":" +
+                this.port + "/version";
+        GluonServer gluonServer = new GluonServer();
+        String gluonversion = gluonServer.getGluonServerVersion(serverUrl);
+        String[] versionArray = gluonversion.split("\\.");
+        version = versionArray[0];
+        return version;
+    }
+
+    /**
+     * Returns reachability of Gluon server.
+     *
+     * @return isSeverReachable
+     */
+    public boolean isSeverReachable() {
+        boolean isSeverReachable = false;
+        try {
+            InetAddress inet = InetAddress.getByName(ipAddress);
+            if (inet.isReachable(5000)) {
+                isSeverReachable = true;
+            } else {
+                isSeverReachable = false;
+                print(NO_SERVER_AVAIL);
+            }
+        } catch (IOException e) {
+            isSeverReachable = false;
+            log.error("Check server process is failed with {} ",
+                      e.getMessage());
+        }
+        return isSeverReachable;
+    }
+
+    /**
+     * Returns availability of Gluon server.
+     *
+     * @return isServerAvailable
+     */
+    public boolean isEtcdSeverAvailable() {
+        String serverUrl = GLUON_HTTP + ipAddress + ":" + port;
+        boolean isServerAvailable;
+        try {
+            URL url = new URL(serverUrl);
+            URLConnection connection = url.openConnection();
+            connection.connect();
+            isServerAvailable = true;
+        } catch (IOException e) {
+            print(NO_SERVER_AVAIL_ON_PORT);
+            isServerAvailable = false;
+        }
+        return isServerAvailable;
+    }
+}
diff --git a/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/GluonServerListCommand.java b/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/GluonServerListCommand.java
new file mode 100755
index 0000000..3ef4a43
--- /dev/null
+++ b/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/GluonServerListCommand.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2017-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.gluon.rsc.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.gluon.manager.GluonManager;
+import org.onosproject.gluon.rsc.GluonServer;
+
+import java.util.Map;
+
+import static org.onosproject.gluon.manager.GluonManager.getAllServersIP;
+import static org.onosproject.gluon.rsc.GluonConstants.ACTIVE_SERVER;
+import static org.onosproject.gluon.rsc.GluonConstants.GLUON_DEFAULT_PORT;
+import static org.onosproject.gluon.rsc.GluonConstants.GLUON_HTTP;
+import static org.onosproject.gluon.rsc.GluonConstants.SERVER_POOL;
+
+/**
+ * Supports for querying Gluon Servers list and statistics.
+ */
+@Command(scope = "onos", name = "gluon-server-list",
+        description = "Gluon server list")
+public class GluonServerListCommand extends AbstractShellCommand {
+
+    @Option(name = "-i", aliases = "--server-ip",
+            description = "Supports for querying Gluon server statistics",
+            required = false, multiValued = false)
+    String ipAddress = null;
+
+    @Option(name = "-p", aliases = "--port", description = "Gluon server port",
+            required = false, multiValued = false)
+    String port = GLUON_DEFAULT_PORT;
+
+    protected Map<String, GluonServer> serverMap = getAllServersIP();
+
+    private static final String SERVER_STATISTICS =
+            "Server %s details:\nVersion: %s\nPort: %s\nReal time data:\n" +
+                    "\tSet Statistics   : %s\n\tDelete Statistics: %s\n" +
+                    "Batch data:\n\tGet Statistics   : %s";
+
+
+    @Override
+    public void execute() {
+        try {
+            String serverUrl = GLUON_HTTP + ipAddress + ":" + port;
+            if (ipAddress != null && checkServerPool(serverUrl)) {
+                for (Map.Entry<String,
+                        GluonServer> server : serverMap.entrySet()) {
+
+                    if (serverUrl.equals(server.getKey())) {
+                        //Gets Etcd object reference
+                        GluonServer gluonServer = server.getValue();
+                        //Gets Etcd version from server list
+                        print(SERVER_STATISTICS, ipAddress, gluonServer.version,
+                              port, gluonServer.getSetCount(),
+                              gluonServer.getDelCount(),
+                              gluonServer.getGetCount());
+                    }
+                }
+            } else {
+                int totalServers = GluonManager.getTotalServers();
+                log.info(ACTIVE_SERVER, totalServers);
+                print("Number of active servers: " + totalServers);
+                printServersIP();
+            }
+        } catch (Exception e) {
+            print(null, e.getMessage());
+        }
+    }
+
+    /**
+     * Prints all servers IPs in table format.
+     */
+    protected void printServersIP() {
+        int countServer = 1;
+        for (Map.Entry<String, GluonServer> server : serverMap.entrySet()) {
+            String serverUrl = server.getKey();
+            String[] serverIP = serverUrl.split("//");
+            print("Server %d: %s", countServer, serverIP[1]);
+            countServer++;
+        }
+    }
+
+    /**
+     * Returns boolean if given IP available in server pool.
+     *
+     * @param ipAddr Ip Address
+     * @return boolean
+     */
+    protected boolean checkServerPool(String ipAddr) {
+        boolean isServerAvailable;
+        if (serverMap.containsKey(ipAddr)) {
+            isServerAvailable = true;
+        } else {
+            print(SERVER_POOL);
+            isServerAvailable = false;
+        }
+        return isServerAvailable;
+    }
+}
diff --git a/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/package-info.java b/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/package-info.java
new file mode 100755
index 0000000..274ff4d
--- /dev/null
+++ b/apps/gluon/src/main/java/org/onosproject/gluon/rsc/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Gluon Shim Application Command line interface package.
+ */
+package org.onosproject.gluon.rsc.cli;
\ No newline at end of file