Add initial nemo-tools structure and sandbox implementation. 85/31885/1
authorZhigang Ji <jizhigang@huawei.com>
Sat, 26 Dec 2015 05:36:42 +0000 (13:36 +0800)
committerZhigang Ji <jizhigang@huawei.com>
Sat, 26 Dec 2015 05:39:03 +0000 (13:39 +0800)
Change-Id: Icfbe6b99d80ca75d574140c11f091fa123177349
Signed-off-by: Zhigang Ji <jizhigang@huawei.com>
35 files changed:
nemo-tools/pom.xml [new file with mode: 0644]
nemo-tools/sandbox/build.sh [new file with mode: 0644]
nemo-tools/sandbox/conf/Network [new file with mode: 0644]
nemo-tools/sandbox/conf/log4j.properties [new file with mode: 0644]
nemo-tools/sandbox/conf/sandbox.properties [new file with mode: 0644]
nemo-tools/sandbox/pom.xml [new file with mode: 0644]
nemo-tools/sandbox/run.sh [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/Cli.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/CmdExecutor.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/EasyCli.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/ISandboxManager.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/Main.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/SandBoxManager.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Cache.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Connector.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Firewall.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Host.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Link.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Network.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Node.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/NodeType.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Router.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Switch.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/VirtualMachine.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/CreateRequest.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/ExecuteRequest.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/RestServer.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/SandboxNorthbound.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/Config.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/FileUtils.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/HexString.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/PropertyLoader.java [new file with mode: 0644]
nemo-tools/sandbox/src/main/resources/Network [new file with mode: 0644]
nemo-tools/sandbox/src/main/resources/log4j.properties [new file with mode: 0644]
nemo-tools/sandbox/src/main/resources/sandbox.properties [new file with mode: 0644]

diff --git a/nemo-tools/pom.xml b/nemo-tools/pom.xml
new file mode 100644 (file)
index 0000000..aaa27e2
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Huawei, Inc and others. All rights reserved.
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.nemo</groupId>
+    <artifactId>nemo.project</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.opendaylight.nemo</groupId>
+  <artifactId>nemo-tools</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <name>${project.artifactId}</name>
+
+  <modules>
+    <module>sandbox</module>
+  </modules>
+
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</developerConnection>
+    <url>https://wiki.opendaylight.org/view/NEMO:Main</url>
+    <tag>HEAD</tag>
+  </scm>
+</project>
\ No newline at end of file
diff --git a/nemo-tools/sandbox/build.sh b/nemo-tools/sandbox/build.sh
new file mode 100644 (file)
index 0000000..3d1dffe
--- /dev/null
@@ -0,0 +1,2 @@
+mvn clean install -DskipTests
+mvn dependency:copy-dependencies -DstripVersion -DskipTests
\ No newline at end of file
diff --git a/nemo-tools/sandbox/conf/Network b/nemo-tools/sandbox/conf/Network
new file mode 100644 (file)
index 0000000..1a8c196
--- /dev/null
@@ -0,0 +1,9 @@
+#switch:TYPE,NAME,DATA-PATH-ID
+#host:TYPE,NAME,UUID,Inde:IPV4,...
+#Link:TYPE,leftName,lPortId,rightName,rPortId
+
+Switch,sw1,1
+Router,sw2,2
+Firewall,firewall,1ab3cd4ef,1:192.168.1.1/16
+Link,sw1,1,sw2,1
+Link,sw1,2,firewall,1
\ No newline at end of file
diff --git a/nemo-tools/sandbox/conf/log4j.properties b/nemo-tools/sandbox/conf/log4j.properties
new file mode 100644 (file)
index 0000000..9120cd8
--- /dev/null
@@ -0,0 +1,6 @@
+log4j.rootLogger=ERROR, stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
+
+log4j.logger.com.huawei.nemo=INFO
\ No newline at end of file
diff --git a/nemo-tools/sandbox/conf/sandbox.properties b/nemo-tools/sandbox/conf/sandbox.properties
new file mode 100644 (file)
index 0000000..af4a357
--- /dev/null
@@ -0,0 +1,11 @@
+host.name = 191.4.3.30
+host.user = root
+host.password = 123456
+controller-socket = 191.4.3.25:6633
+north.port = 10081
+config.path = /home/hj/configs
+config.hosts-file-name = host-resource.json
+config.externals-file-name = external-resource.json
+config.nodes-file-name = node-resource.json
+config.links-file-name = link-resource.json
+
diff --git a/nemo-tools/sandbox/pom.xml b/nemo-tools/sandbox/pom.xml
new file mode 100644 (file)
index 0000000..e8adf01
--- /dev/null
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Huawei, Inc and others. All rights reserved.
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.nemo</groupId>
+    <artifactId>nemo-tools</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.opendaylight.nemo</groupId>
+  <artifactId>sandbox</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+
+  <properties>
+    <log4j.version>1.7.7</log4j.version>
+    <junit.version>4.11</junit.version>
+    <jersey.version>2.11</jersey.version>
+    <enunciate.version>1.26.2</enunciate.version>
+    <cli.version>1.2</cli.version>
+    <cliche.version>1.0-SNAPSHOT</cliche.version>
+    <ssh.version>262</ssh.version>
+    <json.version>20090211</json.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>${log4j.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+      <version>${cli.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.googlecode.cliche</groupId>
+      <artifactId>cliche</artifactId>
+      <version>${cliche.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>ch.ethz.ganymed</groupId>
+      <artifactId>ganymed-ssh2</artifactId>
+      <version>${ssh.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.json</groupId>
+      <artifactId>json</artifactId>
+      <version>${json.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.jersey.containers</groupId>
+      <artifactId>jersey-container-grizzly2-http</artifactId>
+      <version>${jersey.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.jersey.media</groupId>
+      <artifactId>jersey-media-moxy</artifactId>
+      <version>${jersey.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.enunciate</groupId>
+      <artifactId>enunciate-core-annotations</artifactId>
+      <version>${enunciate.version}</version>
+    </dependency>
+  </dependencies>
+
+  <repositories>
+    <repository>
+      <id>cliche</id>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+    </repository>
+  </repositories>
+
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/nemo.git</developerConnection>
+    <url>https://wiki.opendaylight.org/view/NEMO:Main</url>
+    <tag>HEAD</tag>
+  </scm>
+</project>
\ No newline at end of file
diff --git a/nemo-tools/sandbox/run.sh b/nemo-tools/sandbox/run.sh
new file mode 100644 (file)
index 0000000..d767e5a
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh -x
+
+CONFDIR="./conf"
+parse_args() {
+    while test $# -gt 0; do
+        case "$1" in
+            "--confdir" ) shift; CONFDIR=$1 ;;
+            "-c" ) shift; CONFDIR=$1 ;;
+        esac
+        shift
+    done
+}
+
+parse_args $@
+
+# Set paths
+CTRL_HOME=`pwd`/`dirname $0`
+LAUNCHER_PATH="${CTRL_HOME}"
+LAUNCHER_MAIN="org.opendaylight.nemo.tool.sandbox.Main"
+
+# Set JVM options
+JVM_OPTS=""
+#JVM_OPTS="$JVM_OPTS -server -d64"
+#JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
+#JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+#JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
+#JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8"
+#JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
+
+CLASSPATH="$CONFDIR:.:$LAUNCHER_PATH/target/classes:$LAUNCHER_PATH/target/dependency/*"
+java ${JVM_OPTS} -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n -cp $CLASSPATH $LAUNCHER_MAIN $@
\ No newline at end of file
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/Cli.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/Cli.java
new file mode 100644 (file)
index 0000000..5914e28
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox;
+
+import asg.cliche.Command;
+import asg.cliche.Shell;
+import asg.cliche.ShellDependent;
+
+/**
+ * Created by hj on 12/9/15.
+ */
+public class Cli implements ShellDependent {
+    private Shell shell;
+
+    public Cli() {
+
+    }
+
+    @Override
+    public void cliSetShell(Shell shell) {
+        this.shell = shell;
+    }
+
+    @Command
+    public void install() {
+        SandBoxManager.getInstance().createNetwork();
+    }
+
+    @Command
+    public void uninstall() {
+        SandBoxManager.getInstance().destroyNetwork();
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/CmdExecutor.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/CmdExecutor.java
new file mode 100644 (file)
index 0000000..592c82b
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox;
+
+import ch.ethz.ssh2.Connection;
+import ch.ethz.ssh2.Session;
+import ch.ethz.ssh2.StreamGobbler;
+import org.opendaylight.nemo.tool.sandbox.utils.Config;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * Created by hj on 12/9/15.
+ */
+public class CmdExecutor {
+    private static Connection sshConnection;
+    private static String strHostName = Config.getHostName();
+    private static String strUserName = Config.getHostUser();
+    private static String strPassword = Config.getHostPassword();
+
+    public static boolean open() {
+        try {
+            sshConnection = new Connection(strHostName);
+            sshConnection.connect();
+            if (false == sshConnection.authenticateWithPassword(strUserName, strPassword)) {
+                throw new IOException("Authentication failed!");
+            } else {
+                return true;
+            }
+        } catch (IOException objException) {
+            objException.printStackTrace();
+            if (null != sshConnection) {
+                sshConnection.close();
+                sshConnection = null;
+            }
+        }
+        return false;
+    }
+
+    public static void close() {
+        if (null != sshConnection) {
+            sshConnection.close();
+            sshConnection = null;
+        }
+    }
+
+    public static String sshExecute(String command) {
+        Session session = null;
+        try {
+            session = sshConnection.openSession();
+            if (!"root".equals(Config.getHostName())) {
+                command = "sudo " + command;
+            }
+            session.execCommand(command);
+            InputStream stdout = new StreamGobbler(session.getStdout());
+            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stdout));
+            String result = "";
+            while (true) {
+                String line = bufferedReader.readLine();
+                if (line != null)
+                    result += "\r\n" + line;
+                else
+                    break;
+            }
+            session.close();
+            return result;
+
+        } catch (IOException objException) {
+            objException.printStackTrace();
+        } finally {
+            if (null != session) {
+                session.close();
+            }
+        }
+        return null;
+    }
+
+    public static String queryInterfaceMac(String name) {
+        String result = sshExecute("ifconfig " + name);
+        return getMacFromResult(result);
+    }
+
+    public static String queryInterfaceMac(String name, String namespce) {
+        String result = sshExecute("ip netns exec " + namespce + " ifconfig " + name);
+        return getMacFromResult(result);
+    }
+
+    private static String getMacFromResult(String result) {
+        String args[] = result.split("\r\n");
+        for (int i = 0; i < args.length; i++) {
+            String arg = args[i].trim();
+            if (arg.contains("HWaddr")) {
+                String s[] = arg.split(" ");
+                return s[s.length - 1];
+            }
+        }
+        return null;
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/EasyCli.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/EasyCli.java
new file mode 100644 (file)
index 0000000..54ada93
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox;
+
+import asg.cliche.Shell;
+import asg.cliche.ShellFactory;
+
+import java.io.IOException;
+
+/**
+ * Created by hj on 12/9/15.
+ */
+public class EasyCli {
+    private Shell shell;
+
+    public EasyCli(String prompt,String hint,Object handler){
+        shell = ShellFactory.createConsoleShell(prompt, hint, handler);
+    }
+
+    public void add(Object handler){
+        shell.addMainHandler(handler,"");
+    }
+
+    public void run(){
+        try {
+            shell.commandLoop();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/ISandboxManager.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/ISandboxManager.java
new file mode 100644 (file)
index 0000000..7b26102
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox;
+
+import java.util.List;
+
+/**
+ * Created by hj on 12/14/15.
+ */
+public interface ISandboxManager {
+    public boolean createNetwork(List<String> commands);
+
+    public boolean createNetwork();
+
+    public boolean destroyNetwork();
+
+    public String getHosts();
+
+    public String getSwitches();
+
+    public String getLinks();
+
+    public String getExternals();
+
+    public String execute(String name, String command);
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/Main.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/Main.java
new file mode 100644 (file)
index 0000000..7b70936
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox;
+
+import org.opendaylight.nemo.tool.sandbox.northbound.RestServer;
+import org.opendaylight.nemo.tool.sandbox.utils.PropertyLoader;
+
+/**
+ * Created by hj on 12/9/15.
+ */
+public class Main {
+    public static void main(String []args){
+        PropertyLoader.loadProperties("/sandbox.properties", "sandbox.properties does not exist.");
+        int northboundPort = Integer.parseInt(System.getProperty("north.port","10081"));
+        String socketAddress = "http://0.0.0.0:"+northboundPort+"/";
+        RestServer.start(socketAddress);
+        EasyCli easyCli = new EasyCli("sandbox","Authorized by Ip tech, Huawei",new Cli());
+        easyCli.run();
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/SandBoxManager.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/SandBoxManager.java
new file mode 100644 (file)
index 0000000..78fc33b
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox;
+
+import org.json.JSONObject;
+import org.opendaylight.nemo.tool.sandbox.models.*;
+import org.opendaylight.nemo.tool.sandbox.utils.PropertyLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by hj on 12/9/15.
+ */
+public class SandBoxManager implements ISandboxManager {
+    private static Logger log = LoggerFactory.getLogger(SandBoxManager.class);
+    private static SandBoxManager sandBoxManager = new SandBoxManager();
+
+    public static SandBoxManager getInstance() {
+        return sandBoxManager;
+    }
+
+    private Network network = null;
+
+    private SandBoxManager() {
+        List<String> list = PropertyLoader.readLines("/Network", "Network file does not exist.");
+        network = generateNetwork(list);
+    }
+
+    @Override
+    public boolean createNetwork(List<String> list) {
+        if (CmdExecutor.open()) {
+            if (network != null && CmdExecutor.open()) {
+                network.uninstall();
+                CmdExecutor.close();
+            }
+            network = generateNetwork(list);
+            return createNetwork();
+        } else {
+            System.out.println("Can not open ssh.");
+        }
+        return false;
+
+    }
+
+    @Override
+    public boolean createNetwork() {
+        if (network != null && CmdExecutor.open()) {
+            network.install();
+            network.echoConfig();
+            CmdExecutor.close();
+            System.out.println("Network have been installed.");
+            return true;
+        } else {
+            System.out.println("Network is null or can not open ssh,Network: " + network);
+        }
+        return false;
+    }
+
+    @Override
+    public String getHosts() {
+        if (network != null && CmdExecutor.open()) {
+            JSONObject jsonObject = network.hostJsonNode();
+            CmdExecutor.close();
+            if (jsonObject != null) {
+                return jsonObject.toString();
+            }
+        } else {
+            System.out.println("Network is null or can not open ssh,Network: " + network);
+        }
+        return null;
+    }
+
+    @Override
+    public String getExternals() {
+        if (network != null && CmdExecutor.open()) {
+            JSONObject jsonObject = network.externalJsonNode();
+            CmdExecutor.close();
+            if (jsonObject != null) {
+                return jsonObject.toString();
+            }
+        } else {
+            System.out.println("Network is null or can not open ssh,Network: " + network);
+        }
+        return null;
+    }
+
+    @Override
+    public String getSwitches() {
+        if (network != null) {
+            JSONObject jsonObject = network.nodeJsonNode();
+            if (jsonObject != null) {
+                return jsonObject.toString();
+            }
+        } else {
+            System.out.println("Network is null.");
+        }
+        return null;
+    }
+
+    @Override
+    public String getLinks() {
+        if (network != null) {
+            JSONObject jsonObject = network.innerLinkJsonNode();
+            if (jsonObject != null) {
+                return jsonObject.toString();
+            }
+        } else {
+            System.out.println("Network is null.");
+        }
+        return null;
+    }
+
+    @Override
+    public boolean destroyNetwork() {
+        if (network != null && CmdExecutor.open()) {
+            network.uninstall();
+            network = null;
+            CmdExecutor.close();
+        }
+        return true;
+    }
+
+    @Override
+    public String execute(String name, String command) {
+        return network.execute(name,command);
+    }
+
+    private Network generateNetwork(List<String> list) {
+        Network network = new Network();
+        Map<String/*node name*/, List<Connector>> connectorMap = new HashMap<String, List<Connector>>();
+        List<String> nodes = new ArrayList<String>();
+        for (String line : list) {
+            if (line.startsWith("Link")) {
+                Link link = handleLink(line);
+                if (link != null) {
+                    network.addLink(link);
+                    saveConnector(link.getSrcConnector(), connectorMap);
+                    saveConnector(link.getDstConnector(), connectorMap);
+                }
+            } else {
+                nodes.add(line);
+            }
+        }
+        for (String line : nodes) {
+            NodeType nodeType = getNodeType(line);
+            switch (nodeType) {
+                case SWITCH:
+                case ROUTER:
+                    Switch aSwitch = handleSwitch(line, connectorMap);
+                    if (aSwitch != null) {
+                        network.addSwitch(aSwitch);
+                    }
+                    break;
+                case VM:
+                    VirtualMachine virtualMachine = handleVirtualMachine(line, connectorMap);
+                    if (virtualMachine != null) {
+                        network.addHost(virtualMachine);
+                    }
+                    break;
+                case CACHE:
+                    Cache cache = handleCache(line, connectorMap);
+                    if (cache != null) {
+                        network.addHost(cache);
+                    }
+                    break;
+                case FIREWALL:
+                    Firewall firewall = handleFirewall(line, connectorMap);
+                    if (firewall != null) {
+                        network.addHost(firewall);
+                    }
+                    break;
+                default:
+                    log.warn("Ignore line : {}.", line);
+            }
+        }
+        return network;
+    }
+
+    private Switch handleSwitch(String line, Map<String, List<Connector>> connectorMap) {
+        line = line.trim();
+        String args[] = line.split(",");
+        if (args.length == 3) {
+            Switch sw = null;
+            if (line.startsWith("Router"))
+                sw = new Router(args[1].trim(), Long.parseLong(args[2]));
+            else
+                sw = new Switch(args[1].trim(), Long.parseLong(args[2]));
+            List<Connector> connectors = connectorMap.get(sw.getName());
+            if (connectors != null) {
+                for (Connector connector : connectors) {
+                    sw.addConnectors(connector);
+                }
+            }
+            return sw;
+        }
+        return null;
+    }
+
+    private VirtualMachine handleVirtualMachine(String line, Map<String, List<Connector>> connectorMap) {
+        line = line.trim();
+        String args[] = line.split(",");
+        if (args.length >= 4) {
+            VirtualMachine virtualMachine = new VirtualMachine(args[1].trim(),args[2].trim());
+            parserHost(args, connectorMap, virtualMachine);
+            return virtualMachine;
+        }
+        return null;
+    }
+
+    private Cache handleCache(String line, Map<String, List<Connector>> connectorMap) {
+        line = line.trim();
+        String args[] = line.split(",");
+        if (args.length >= 4) {
+            Cache cache = new Cache(args[1].trim(),args[2].trim());
+            parserHost(args, connectorMap, cache);
+            return cache;
+        }
+        return null;
+    }
+
+    private Firewall handleFirewall(String line, Map<String, List<Connector>> connectorMap) {
+        line = line.trim();
+        String args[] = line.split(",");
+        if (args.length >= 4) {
+            Firewall firewall = new Firewall(args[1].trim(),args[2].trim());
+            parserHost(args, connectorMap, firewall);
+            return firewall;
+        }
+        return null;
+    }
+
+    private void parserHost(String[] args, Map<String, List<Connector>> connectorMap, Host host) {
+        List<Connector> connectors = connectorMap.get(host.getName());
+        if (connectors != null) {
+            for (Connector connector : connectors) {
+                host.addConnectors(connector);
+            }
+        }
+        for (int i = 3; i < args.length; i++) {
+            String[] array = args[i].trim().split(":");
+            if (array.length == 2) {
+                int order = Integer.parseInt(array[0]);
+                host.putConnectorIpv4(order, array[1]);
+            }
+        }
+
+    }
+
+    private void saveConnector(Connector connector, Map<String, List<Connector>> connectorMap) {
+        String nodeName = connector.getNodeName();
+        if (!connectorMap.containsKey(nodeName)) {
+            connectorMap.put(nodeName, new ArrayList<Connector>());
+        }
+        connectorMap.get(nodeName).add(connector);
+    }
+
+    private Link handleLink(String link) {
+        link = link.trim();
+        String args[] = link.split(",");
+        if (args.length == 5) {
+            Connector lConnector = new Connector(args[1].trim(), Integer.parseInt(args[2].trim()));
+            Connector rConnector = new Connector(args[3].trim(), Integer.parseInt(args[4].trim()));
+            return new Link(lConnector, rConnector);
+        }
+        return null;
+    }
+
+    private NodeType getNodeType(String line) {
+        if (line.startsWith("Switch"))
+            return NodeType.SWITCH;
+        if (line.startsWith("Router")) {
+            return NodeType.ROUTER;
+        }
+        if (line.startsWith("Cache")) {
+            return NodeType.CACHE;
+        }
+        if (line.startsWith("Firewall")) {
+            return NodeType.FIREWALL;
+        }
+        if (line.startsWith("Vm")) {
+            return NodeType.VM;
+        }
+        return NodeType.UNKNOWN;
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Cache.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Cache.java
new file mode 100644 (file)
index 0000000..6f4709d
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+import org.opendaylight.nemo.tool.sandbox.CmdExecutor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public class Cache extends Host {
+    public Cache(String name,String uuId) {
+        super(NodeType.CACHE,name, uuId);
+    }
+
+    @Override
+    protected List<String> generateCommands() {
+        List<String> commands = new ArrayList<String>(generateHost());
+        //TODO: host script.
+        //open route flag
+        commands.add("ip netns exec "+getName()+"echo 1 > /proc/sys/net/ipv4/ip_forward");
+        //add default route
+        if(connectors.size()>0) {
+            commands.add("ip netns exec route add default dev "+ connectors.get(0));
+        }
+        return commands;
+    }
+
+    @Override
+    public void uninstall(){
+        try {
+            CmdExecutor.sshExecute("ip netns del " + getName());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Connector.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Connector.java
new file mode 100644 (file)
index 0000000..2ea538f
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public class Connector implements Comparable<Connector> {
+    private final int order;
+    private final String nodeName;
+
+    public Connector(String nodeName, int order) {
+        this.order = order;
+        this.nodeName = nodeName;
+    }
+
+    public String getConnectorName() {
+        return  nodeName + "-" + order;
+    }
+
+    public int getOrder() {
+        return order;
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Connector that = (Connector) o;
+
+        if (order != that.order) return false;
+        if (nodeName != null ? !nodeName.equals(that.nodeName) : that.nodeName != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = order;
+        result = 31 * result + (nodeName != null ? nodeName.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "SwitchInterface{" +
+                "order=" + order +
+                ", nodeName='" + nodeName + '\'' +
+                '}';
+    }
+
+    @Override
+    public int compareTo(Connector o) {
+        return order - o.order;
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Firewall.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Firewall.java
new file mode 100644 (file)
index 0000000..0baadf5
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+import org.opendaylight.nemo.tool.sandbox.CmdExecutor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public class Firewall extends Host {
+    public Firewall(String name,String uuId) {
+        super(NodeType.FIREWALL, name,uuId);
+    }
+
+    @Override
+    protected List<String> generateCommands() {
+        List<String> commands = new ArrayList<String>(generateHost());
+        //TODO: host script.
+        //open route flag
+        commands.add("ip netns exec "+getName()+"echo 1 > /proc/sys/net/ipv4/ip_forward");
+        //add default route
+        if(connectors.size()>0) {
+            commands.add("ip netns exec route add default dev "+ connectors.get(0));
+        }
+        return commands;
+    }
+
+    @Override
+    public void uninstall(){
+        try {
+            CmdExecutor.sshExecute("ip netns del " + getName());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Host.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Host.java
new file mode 100644 (file)
index 0000000..17ab7a2
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+* Created by hj on 12/8/15.
+*/
+abstract public class Host extends Node {
+    private HashMap<Integer/*connector name*/, String/*Ipv4*/> connectorIpv4Map;
+    private final String uuid;
+
+    protected Host(NodeType nodeType, String name,String uuid) {
+        super(nodeType, name);
+        this.uuid = uuid;
+        connectorIpv4Map = new HashMap<Integer, String>();
+    }
+
+    public void putConnectorIpv4(int order, String ipv4) {
+        connectorIpv4Map.put(order, ipv4);
+    }
+
+    public String getUuid(){
+        return uuid;
+    }
+
+    public String getIpv4(int order){
+        return connectorIpv4Map.get(order);
+    }
+
+    abstract void uninstall();
+
+    protected List<String> generateHost() {
+        List<String> hostCreateCommands = new ArrayList<String>();
+        hostCreateCommands.add("ip netns add " + getName());
+        for (Connector connector : connectors) {
+            hostCreateCommands.add("ip link set " + connector.getConnectorName() + " netns " + getName());
+        }
+
+        for (Connector connector : connectors) {
+            String ipv4 = connectorIpv4Map.get(connector.getOrder());
+            if (ipv4 != null) {
+                hostCreateCommands.add("ip netns exec " + getName() + " ifconfig " + connector.getConnectorName() + " " + ipv4 + " up");
+            }
+        }
+        return hostCreateCommands;
+    }
+
+    @Override
+    public String toString() {
+        return "Host{" +
+                "name=" + getName() + '\'' +
+                "type=" + getNodeType() + '\'' +
+                "connectors='" + connectors + '\'' +
+                ", ipv4Map='" + connectorIpv4Map + '\'' +
+                '}';
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Link.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Link.java
new file mode 100644 (file)
index 0000000..774df91
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+import org.opendaylight.nemo.tool.sandbox.CmdExecutor;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public class Link {
+    private final Connector srcInterface;
+    private final Connector dstInterface;
+
+    public Link(Connector srcInterface, Connector dstInterface) {
+        this.srcInterface = srcInterface;
+        this.dstInterface = dstInterface;
+    }
+
+    public Connector getSrcConnector() {
+        return srcInterface;
+    }
+
+    public Connector getDstConnector() {
+        return dstInterface;
+    }
+
+    public void install() {
+        String linkAddCmd = "ip link add name " + srcInterface.getConnectorName() + " type veth peer name " + dstInterface.getConnectorName();
+        try {
+            CmdExecutor.sshExecute(linkAddCmd);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void uninstall() {
+        String linkDelCmd = "ip link del " + srcInterface.getConnectorName();
+        try {
+            CmdExecutor.sshExecute(linkDelCmd);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Link link = (Link) o;
+
+        if (dstInterface != null ? !dstInterface.equals(link.dstInterface) : link.dstInterface != null) return false;
+        if (srcInterface != null ? !srcInterface.equals(link.srcInterface) : link.srcInterface != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = srcInterface != null ? srcInterface.hashCode() : 0;
+        result = 31 * result + (dstInterface != null ? dstInterface.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Link{" +
+                "srcInterface=" + srcInterface +
+                ", dstInterface=" + dstInterface +
+                '}';
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Network.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Network.java
new file mode 100644 (file)
index 0000000..9149268
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.opendaylight.nemo.tool.sandbox.CmdExecutor;
+import org.opendaylight.nemo.tool.sandbox.utils.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by hj on 12/9/15.
+ */
+public class Network {
+    private static Logger log = LoggerFactory.getLogger(Network.class);
+    private Map<String/*name*/, Host> hostMap;
+    private Map<String/*name*/, Switch> switchMap;
+    private Map<Connector/*External connector*/, Connector/*Connector on host*/> externalConnectorMap;
+    private List<Link> internalLinks;
+    private List<Link> links;
+
+    public Network() {
+        hostMap = new HashMap<String, Host>();
+        switchMap = new HashMap<String, Switch>();
+        links = new ArrayList<Link>();
+
+        externalConnectorMap = new HashMap<Connector, Connector>();
+        internalLinks = new ArrayList<Link>();
+    }
+
+    public void addHost(Host host) {
+        hostMap.put(host.getName(), host);
+    }
+
+    public void addSwitch(Switch sw) {
+        switchMap.put(sw.getName(), sw);
+    }
+
+    public void addLink(Link link) {
+        links.add(link);
+    }
+
+    public String execute(String name, String command) {
+        Host host = hostMap.get(name);
+        if (host != null) {
+            if (CmdExecutor.open()) {
+                String result = CmdExecutor.sshExecute("ip netns exec " + name + " " + command);
+                CmdExecutor.close();
+                return result;
+            } else {
+                return "Can not open ssh right now,please try again.";
+            }
+        }
+        return name + " " + "is not a firewall,can not execute " + command;
+    }
+
+    public void install() {
+        traversal();
+
+        for (Link link : links) {
+            link.install();
+        }
+
+        for (Node node : switchMap.values()) {
+            node.install();
+        }
+
+        for (Node node : hostMap.values()) {
+            node.install();
+        }
+    }
+
+    public void uninstall() {
+        for (Link link : links) {
+            link.uninstall();
+        }
+
+        pKill();
+
+        for (Host host : hostMap.values()) {
+            host.uninstall();
+        }
+    }
+
+    private void pKill() {
+        try {
+            CmdExecutor.sshExecute("pkill -9 ofdatapath");
+            CmdExecutor.sshExecute("pkill -9 ofprotocol");
+
+            CmdExecutor.sshExecute("pkill -9 fail-ofdatapath");
+            CmdExecutor.sshExecute("pkill -9 fail-ofprotocol");
+
+            CmdExecutor.sshExecute("pkill -9 ext-ofdatapath");
+            CmdExecutor.sshExecute("pkill -9 ext-ofprotocol");
+        } catch (Exception e) {
+
+        }
+    }
+
+    public void echoConfig() {
+        CmdExecutor.sshExecute("mkdir -p " + Config.getConfigPath());
+
+        String hosts = hostJsonNode().toString().replaceAll("\"", "\\\\\"").replaceAll("\\{", "\\\\{");
+        String hostsPath = Config.getConfigPath() + "/" + Config.getConfigHostsFileName();
+        CmdExecutor.sshExecute("echo " + hosts + " > " + hostsPath);
+//        FileUtils.write(hostsPath, hosts);
+
+        String externals = externalJsonNode().toString().replaceAll("\"", "\\\\\"").replaceAll("\\{", "\\\\{");
+        String externalsPath = Config.getConfigPath() + "/" + Config.getConfigExternalsFileName();
+        CmdExecutor.sshExecute("echo " + externals + " > " + externalsPath);
+//        FileUtils.write(externalsPath, externals);
+
+        String nodes = nodeJsonNode().toString().replaceAll("\"", "\\\\\"").replaceAll("\\{", "\\\\{");
+        String nodesPath = Config.getConfigPath() + "/" + Config.getConfigNodesFileName();
+        CmdExecutor.sshExecute("echo " + nodes + " > " + nodesPath);
+//        FileUtils.write(nodesPath, nodes);
+
+        String links = externalJsonNode().toString().replaceAll("\"", "\\\\\"").replaceAll("\\{", "\\\\{");
+        String linksPath = Config.getConfigPath() + "/" + Config.getConfigLinksFileName();
+        CmdExecutor.sshExecute("echo " + links + " > " + linksPath);
+//        FileUtils.write(linksPath,links);
+    }
+
+    private void traversal() {
+        externalConnectorMap.clear();
+        internalLinks.clear();
+
+        for (Link link : links) {
+            String leftNode = link.getSrcConnector().getNodeName();
+            String rightNode = link.getDstConnector().getNodeName();
+            if (hostMap.containsKey(leftNode) && switchMap.containsKey(rightNode)) {
+                externalConnectorMap.put(link.getDstConnector(), link.getSrcConnector());
+            } else if (hostMap.containsKey(rightNode) && switchMap.containsKey(leftNode)) {
+                externalConnectorMap.put(link.getSrcConnector(), link.getDstConnector());
+            } else if (switchMap.containsKey(leftNode) && switchMap.containsKey(rightNode)) {
+                internalLinks.add(link);
+            } else {
+                log.error("Illegal link: {}.", link);
+            }
+        }
+    }
+
+    public JSONObject nodeJsonNode() {
+        JSONObject root = new JSONObject();
+        JSONArray nodeArray = new JSONArray();
+        int index = 0;
+        try {
+            for (Switch sw : switchMap.values()) {
+                JSONObject nodeJson = buildNodeJson(sw);
+                if (nodeJson != null) {
+                    nodeArray.put(index, nodeJson);
+                    index++;
+                }
+            }
+            root.put("node", nodeArray);
+            return root;
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private JSONObject buildNodeJson(Switch sw) {
+        JSONObject nodeJson = new JSONObject();
+        try {
+            String nodeId = "openflow:" + sw.getDataPathId();
+            String type = sw instanceof Router ? "router" : "switch";
+            JSONArray attributes = defaultNodeAttributes(nodeId);
+            JSONArray ports = new JSONArray();
+            int index = 0;
+            List<Connector> connectors = sw.getConnectors();
+            for (Connector connector : connectors) {
+                JSONObject portJson = new JSONObject();
+                String portId = nodeId + ":" + connector.getOrder();
+                String portType = externalConnectorMap.containsKey(connector) ? "external" : "internal";
+                JSONArray portAttributes = defaultPortAttributes(portId);
+                portJson.put("port-id", portId);
+                portJson.put("port-type", portType);
+                portJson.put("attribute", portAttributes);
+                ports.put(index, portJson);
+                index++;
+            }
+            nodeJson.put("node-id", nodeId);
+            nodeJson.put("node-type", type);
+            nodeJson.put("attribute", attributes);
+            nodeJson.put("port", ports);
+            return nodeJson;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private JSONArray defaultNodeAttributes(String nodeId) throws JSONException {
+        JSONArray jsonArray = new JSONArray();
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("name", "location");
+        jsonObject.put("value", nodeId);
+        jsonArray.put(0, jsonObject);
+        return jsonArray;
+    }
+
+    private JSONArray defaultPortAttributes(String portId) throws JSONException {
+        JSONArray jsonArray = new JSONArray();
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("name", "location");
+        jsonObject.put("value", portId);
+        jsonArray.put(0, jsonObject);
+        return jsonArray;
+    }
+
+    public JSONObject externalJsonNode() {
+        JSONObject root = new JSONObject();
+        JSONArray externalMacs = new JSONArray();
+        int index = 0;
+        try {
+            for (Connector exCon : externalConnectorMap.keySet()) {
+                Connector hostCon = externalConnectorMap.get(exCon);
+                String hostMac = CmdExecutor.queryInterfaceMac(hostCon.getConnectorName(), hostCon.getNodeName());
+                Switch sw = switchMap.get(exCon.getNodeName());
+                if (hostMac != null && sw != null) {
+                    JSONObject exNode = new JSONObject();
+                    String nodeId = "openflow:" + sw.getDataPathId();
+                    String portId = nodeId + ":" + exCon.getOrder();
+
+                    exNode.put("node-id", nodeId);
+                    exNode.put("port-id", portId);
+                    exNode.put("mac-address", hostMac);
+                    externalMacs.put(index, exNode);
+                    index++;
+                }
+            }
+            root.put("external-network-mac", externalMacs);
+            return root;
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public JSONObject hostJsonNode() {
+        JSONObject root = new JSONObject();
+        JSONArray hostArray = new JSONArray();
+        int index = 0;
+        try {
+            for (Connector exCon : externalConnectorMap.keySet()) {
+                Connector hostCon = externalConnectorMap.get(exCon);
+                String exConMac = CmdExecutor.queryInterfaceMac(exCon.getConnectorName());
+                Switch sw = switchMap.get(exCon.getNodeName());
+
+                JSONObject hostJson = new JSONObject();
+                String hostName = hostCon.getNodeName();
+                Host host = hostMap.get(hostName);
+                if ( exConMac != null && sw != null && host != null) {
+                    JSONArray ipv4Array = ipAddress(hostCon);
+                    String nodeId = "openflow:" + sw.getDataPathId();
+                    String connectorId = nodeId + ":" + exCon.getOrder();
+                    hostJson.put("name", hostName);
+                    hostJson.put("id", host.getUuid());
+                    hostJson.put("type", host.getNodeType());
+                    hostJson.put("ip-addresses", ipv4Array);
+                    hostJson.put("mac-address", exConMac);
+                    hostJson.put("node-id", nodeId);
+                    hostJson.put("connector-id", connectorId);
+                    hostArray.put(index, hostJson);
+                    index++;
+                } else {
+                    log.error("Can not put host [{}] to configuration file,exMac:{}  sw:{} id:{}.", hostName, sw);
+                }
+            }
+            root.put("host", hostArray);
+            return root;
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private JSONArray ipAddress(Connector connector) throws JSONException {
+        JSONArray jsonArray = new JSONArray();
+        Host host = hostMap.get(connector.getNodeName());
+        if (host != null) {
+            String ipv4 = host.getIpv4(connector.getOrder());
+            if (ipv4 != null) {
+                ipv4 = ipv4 + "/";
+                ipv4 = ipv4.substring(0, ipv4.indexOf("/"));
+                JSONObject jsonObject = new JSONObject();
+                jsonObject.put("ip-address", ipv4);
+                jsonArray.put(0, jsonObject);
+                return jsonArray;
+            }
+        }
+        return null;
+    }
+
+    public JSONObject innerLinkJsonNode() {
+        JSONObject root = new JSONObject();
+        JSONArray linkArray = new JSONArray();
+        int index = 0;
+        try {
+            for (Link link : internalLinks) {
+                JSONObject srcLinkNode = buildLinkNode(link.getSrcConnector());
+                if (srcLinkNode != null) {
+                    linkArray.put(index, srcLinkNode);
+                    index++;
+                }
+                JSONObject dstLinkNode = buildLinkNode(link.getDstConnector());
+                if (srcLinkNode != null) {
+                    linkArray.put(index, dstLinkNode);
+                    index++;
+                }
+            }
+            root.put("link", linkArray);
+        } catch (JSONException e) {
+            e.printStackTrace();
+            return null;
+        }
+        return root;
+    }
+
+    private JSONObject buildLinkNode(Connector connector) {
+        Switch sw = switchMap.get(connector.getNodeName());
+        if (sw != null) {
+            JSONObject linkNode = new JSONObject();
+            String nodeId = "openflow:" + sw.getDataPathId();
+            String linkId = nodeId + ":" + connector.getOrder();
+            try {
+                linkNode.put("link-id", linkId);
+                linkNode.put("metric", "1");
+                linkNode.put("delay", "");
+                linkNode.put("loss-rate", "");
+                return linkNode;
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Node.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Node.java
new file mode 100644 (file)
index 0000000..1749354
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+import org.opendaylight.nemo.tool.sandbox.CmdExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+abstract public class Node {
+    private static Logger log = LoggerFactory.getLogger(Node.class);
+    private final String name;
+    private final NodeType nodeType;
+    protected List<Connector> connectors;
+
+    public Node(NodeType nodeType, String name) {
+        this.nodeType = nodeType;
+        this.name = name;
+        this.connectors = new ArrayList<Connector>();
+    }
+
+    public NodeType getNodeType() {
+        return nodeType;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void addConnectors(Connector connector) {
+        connectors.add(connector);
+    }
+
+    public List<Connector> getConnectors() {
+        return connectors;
+    }
+
+    public void install() {
+        List<String> commands = generateCommands();
+        if (commands == null) {
+            log.error("Commands should not be null.");
+            return;
+        }
+        for (String command : commands) {
+            try {
+                CmdExecutor.sshExecute(command);
+            } catch (Exception e) {
+                log.error("Error while execute [{}].", command, name, nodeType);
+                e.printStackTrace();
+            }
+        }
+    }
+
+    abstract protected List<String> generateCommands();
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Node node = (Node) o;
+
+        if (name != null ? !name.equals(node.name) : node.name != null) return false;
+        if (nodeType != node.nodeType) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (nodeType != null ? nodeType.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/NodeType.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/NodeType.java
new file mode 100644 (file)
index 0000000..67e565d
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public enum NodeType {
+    SWITCH,ROUTER, VM,FIREWALL,CACHE,UNKNOWN
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Router.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Router.java
new file mode 100644 (file)
index 0000000..dd1ca15
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public class Router extends Switch {
+    public Router(String name, long dataPathId) {
+        super(name, dataPathId);
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Switch.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/Switch.java
new file mode 100644 (file)
index 0000000..c852068
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+import org.opendaylight.nemo.tool.sandbox.utils.Config;
+import org.opendaylight.nemo.tool.sandbox.utils.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public class Switch extends Node {
+    private static Logger log = LoggerFactory.getLogger(Switch.class);
+    private final long dataPathId;
+    private final String mac;
+
+    public Switch(String name, long dataPathId) {
+        super(NodeType.SWITCH, name);
+        this.dataPathId = dataPathId;
+
+        this.mac = HexString.toHexString(dataPathId);
+    }
+
+    public long getDataPathId() {
+        return dataPathId;
+    }
+
+    @Override
+    protected List<String> generateCommands() {
+        List<String> commands = new ArrayList<String>();
+
+        String controllerSocket = Config.getControllerSocket();
+        String strInterface = "";
+        Collections.sort(connectors);
+        for (Connector connector : this.connectors) {
+            strInterface += ("," + connector.getConnectorName());
+        }
+        if (this.connectors.isEmpty()) {
+            log.warn("Switch {} does not have ports.");
+            strInterface = "";
+        } else {
+            strInterface = strInterface.substring(1);
+        }
+        String ofDataPathCreate = "ofdatapath";
+        if (!strInterface.equals("")) {
+            ofDataPathCreate += (" -i " + strInterface);
+        }
+        ofDataPathCreate += (" punix:/tmp/sw" + dataPathId + " -d " + mac + " 1> /tmp/sw" + dataPathId + "-ofd.log 2> /tmp/sw" + dataPathId + "-ofd.log &");
+        commands.add(ofDataPathCreate);
+
+        String ofProtocol = "ofprotocol unix:/tmp/sw" + dataPathId + " tcp:" + controllerSocket + " --fail=closed  1> /tmp/sw" + dataPathId + "-ofp.log 2>/tmp/sw" + dataPathId + "-ofp.log &";
+        commands.add(ofProtocol);
+        String lldp = "dpctl unix:/tmp/sw" + dataPathId + " flow-mod cmd=add,table=0 eth_type=0x88cc  apply:output=ctrl:0xff";
+        commands.add(lldp);
+        String arp = "dpctl unix:/tmp/sw" + dataPathId + " flow-mod cmd=add,table=0 eth_type=0x0806  apply:output=ctrl:0xff";
+        commands.add(arp);
+
+        return commands;
+    }
+
+    @Override
+    public String toString() {
+        return "Switch{" +
+                "name=" + getName() +
+                ", dataPathId=" + dataPathId +
+                ", mac='" + mac + '\'' +
+                ", connectors=" + connectors +
+                '}';
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/VirtualMachine.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/models/VirtualMachine.java
new file mode 100644 (file)
index 0000000..8dc1647
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.models;
+
+import org.opendaylight.nemo.tool.sandbox.CmdExecutor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public class VirtualMachine extends Host {
+    public VirtualMachine(String name,String uuId) {
+        super(NodeType.VM, name,uuId);
+    }
+
+    @Override
+    protected List<String> generateCommands() {
+        List<String> commands = new ArrayList<String>(generateHost());
+        //TODO: host script.
+        //open route flag
+        commands.add("ip netns exec "+getName()+"echo 1 > /proc/sys/net/ipv4/ip_forward");
+        //add default route
+        if(connectors.size()>0) {
+            commands.add("ip netns exec route add default dev "+ connectors.get(0));
+        }
+        return commands;
+    }
+
+    @Override
+    public void uninstall(){
+        try {
+            CmdExecutor.sshExecute("ip netns del " + getName());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/CreateRequest.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/CreateRequest.java
new file mode 100644 (file)
index 0000000..2581454
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.northbound;
+
+/**
+ * Created by hj on 12/12/15.
+ */
+public class CreateRequest {
+    public CreateRequest(){
+
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/ExecuteRequest.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/ExecuteRequest.java
new file mode 100644 (file)
index 0000000..ab7092a
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.northbound;
+
+/**
+ * Created by hj on 12/14/15.
+ */
+public class ExecuteRequest {
+    private String hostName;
+    private String command;
+
+    public ExecuteRequest(){
+
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public void setHostName(String hostName) {
+        this.hostName = hostName;
+    }
+
+    public String getCommand() {
+        return command;
+    }
+
+    public void setCommand(String command) {
+        this.command = command;
+    }
+
+    @Override
+    public String toString() {
+        return "ExecuteRequest{" +
+                "hostName='" + hostName + '\'' +
+                ", command='" + command + '\'' +
+                '}';
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/RestServer.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/RestServer.java
new file mode 100644 (file)
index 0000000..1b0cb8d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.northbound;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+
+import java.net.URI;
+
+public class RestServer {
+    // Base URI the Grizzly HTTP server will listen on
+    private static HttpServer server;
+
+    /**
+     * Starts Grizzly HTTP server exposing JAX-RS resources defined inN this application.
+     *
+     * @return Grizzly HTTP server.
+     */
+    public static void start(String socket) {
+        // create a resource config that scans for JAX-RS resources and providers
+        // in com.example package
+        final ResourceConfig rc = new ResourceConfig().packages("com.huawei.nemo.sandbox.northbound");
+
+        // create and start a new instance of grizzly http serverssss
+        // exposing the Jersey application at BASE_URI
+        server = GrizzlyHttpServerFactory.createHttpServer(URI.create(socket), rc);
+    }
+
+    public static void stop() {
+        if (server != null) {
+            server.shutdown();
+            server = null;
+        }
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/SandboxNorthbound.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/northbound/SandboxNorthbound.java
new file mode 100644 (file)
index 0000000..ba8e2c8
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.northbound;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.codehaus.enunciate.jaxrs.TypeHint;
+import org.opendaylight.nemo.tool.sandbox.SandBoxManager;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by hj on 12/12/15.
+ */
+/**
+ * Root resource (exposed at "myresource" path)
+ */
+@Path("/nemo/sandbox")
+public class SandboxNorthbound {
+    @Path("/create")
+    @POST
+    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Produces({MediaType.TEXT_PLAIN})
+    @StatusCodes
+            ({
+                    @ResponseCode(code = 201, condition = "???"),
+                    @ResponseCode(code = 409, condition = "")
+            })
+    public String create(
+            @Context UriInfo uriInfo,
+            String request) {
+        List<String> formattedCommands = format(request);
+        return "" + SandBoxManager.getInstance().createNetwork(formattedCommands);
+    }
+
+    private List<String> format(String request) {
+        String[] arrays = request.split("\n");
+        List<String> list = new ArrayList<String>();
+        for (String command : arrays) {
+            if (!command.trim().equals("")) {
+                list.add(command);
+            }
+        }
+        return list;
+    }
+
+//    @Path("/create")
+//    @POST
+//    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+//    @Produces({MediaType.TEXT_PLAIN})
+//    @StatusCodes
+//            ({
+//                    @ResponseCode(code = 201, condition = "???"),
+//                    @ResponseCode(code = 409, condition = "")
+//            })
+//    public Response create(
+//            @Context UriInfo uriInfo,
+//            @TypeHint(CreateRequest.class) CreateRequest request) {
+//        //TODO:Generate List<String> by the request.
+//
+//        return Response.created(uriInfo.getRequestUri()).status(409).build();
+//    }
+
+    @Path("/execute")
+    @POST
+    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Produces({MediaType.TEXT_PLAIN})
+    @StatusCodes
+            ({
+                    @ResponseCode(code = 201, condition = "???"),
+                    @ResponseCode(code = 409, condition = "")
+            })
+    public String create(
+            @Context UriInfo uriInfo,
+            @TypeHint(ExecuteRequest.class) ExecuteRequest executeRequest) {
+        String result = SandBoxManager.getInstance().execute(executeRequest.getHostName(), executeRequest.getCommand());
+
+        return result;
+    }
+
+    @Path("/destroy")
+    @POST
+    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Produces({MediaType.TEXT_PLAIN})
+    @StatusCodes
+            ({
+                    @ResponseCode(code = 201, condition = "???"),
+                    @ResponseCode(code = 409, condition = "")
+            })
+    public String destroy(@Context UriInfo uriInfo) {
+        //TODO:Generate List<String> by the request.
+        return SandBoxManager.getInstance().destroyNetwork() + "";
+    }
+
+    @Path("/crossdomain.xml")
+    @GET
+    @Produces({MediaType.TEXT_XML})
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful")})
+    public String getXml() {
+        System.out.println("getHosts running");
+        return "<?xml version=\"1.0\"?> <cross-domain-policy><allow-access-from domain=\"*\"/>" +
+                "<allow-http-request-headers-from domain=\"*\" headers=\"*\"/></cross-domain-policy>";
+    }
+
+    @Path("/hosts")
+    @GET
+    @Produces({MediaType.APPLICATION_JSON})
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful")})
+    public String getHosts() {
+        return SandBoxManager.getInstance().getHosts();
+    }
+
+    @Path("/switches")
+    @GET
+    @Produces({MediaType.APPLICATION_JSON})
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful")})
+    public String getSwitches() {
+        return SandBoxManager.getInstance().getSwitches();
+    }
+
+    @Path("/links")
+    @GET
+    @Produces({MediaType.APPLICATION_JSON})
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful")})
+    public String getLinks() {
+        return SandBoxManager.getInstance().getLinks();
+    }
+
+    @Path("/externals")
+    @GET
+    @Produces({MediaType.APPLICATION_JSON})
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful")})
+    public String getExternals() {
+        return SandBoxManager.getInstance().getExternals();
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/Config.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/Config.java
new file mode 100644 (file)
index 0000000..5039f7e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.utils;
+
+/**
+ * Created by hj on 12/8/15.
+ */
+public class Config {
+    private static String controllerSocket;
+    private static boolean printProcess;
+    private static String hostName;
+    private static String hostUser;
+    private static String hostPassword;
+
+    private static String configPath;
+    private static String configHostsFileName;
+    private static String configExternalsFileName;
+    private static String configLinksFileName;
+    private static String configNodesFileName;
+
+    static {
+        controllerSocket = System.getProperty("controller-socket","localhost:6633");
+        printProcess = Boolean.valueOf(System.getProperty("print-process","false"));
+        hostName = System.getProperty("host.name","localhost");
+        hostUser = System.getProperty("host.user","root");
+        hostPassword = System.getProperty("host.password","123456");
+        configPath = System.getProperty("config.path","/root");
+        configHostsFileName = System.getProperty("config.hosts-file-name","host-resource.json");
+        configExternalsFileName = System.getProperty("config.externals-file-name","external-resource.json");
+        configLinksFileName = System.getProperty("config.links-file-name","link-resource.json");
+        configNodesFileName = System.getProperty("config.nodes-file-name","node-resource.json");
+    }
+
+    public static String getControllerSocket(){
+        return controllerSocket;
+    }
+
+    public static boolean isPrintProcess(){
+        return printProcess;
+    }
+
+    public static String getHostName(){
+        return hostName;
+    }
+
+    public static String getHostUser(){
+        return hostUser;
+    }
+
+    public static String getHostPassword(){
+        return hostPassword;
+    }
+
+    public static String getConfigPath() {
+        return configPath;
+    }
+
+    public static String getConfigHostsFileName() {
+        return configHostsFileName;
+    }
+
+    public static String getConfigExternalsFileName() {
+        return configExternalsFileName;
+    }
+
+    public static String getConfigLinksFileName() {
+        return configLinksFileName;
+    }
+
+    public static String getConfigNodesFileName() {
+        return configNodesFileName;
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/FileUtils.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/FileUtils.java
new file mode 100644 (file)
index 0000000..270d064
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.utils;
+
+import java.io.*;
+
+/**
+ * Created by hj on 12/11/15.
+ */
+public class FileUtils {
+    public static void write(String path, String content) {
+        try {
+            File f = new File(path);
+            if (!f.exists()) {
+                if (!f.createNewFile()) {
+                    System.out.println("Can not create new file " + path);
+                }
+            }
+            BufferedWriter output = new BufferedWriter(new FileWriter(f));
+            output.write(content);
+            output.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/HexString.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/HexString.java
new file mode 100644 (file)
index 0000000..e54b30c
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.utils;
+
+import java.math.BigInteger;
+
+public class HexString {
+    public static String toHexString(long val, int padTo) {
+        char arr[] = Long.toHexString(val).toCharArray();
+        String ret = "";
+        // prepend the right number of leading zeros
+        int i = 0;
+        for (; i < (padTo * 2 - arr.length); i++) {
+            ret += "0";
+//            if ((i % 2) != 0)
+//                ret += ":";
+        }
+        for (int j = 0; j < arr.length; j++) {
+            ret += arr[j];
+//            if ((((i + j) % 2) != 0) && (j < (arr.length - 1)))
+//                ret += ":";
+        }
+        return ret;
+    }
+
+    public static String toHexString(long val) {
+        return toHexString(val, 6);
+    }
+
+    /**
+     * Convert a string of hex values into a string of bytes
+     *
+     * @param values "0f:ca:fe:de:ad:be:ef"
+     * @return [15, 5 ,2, 5, 17]
+     * @throws NumberFormatException If the string can not be parsed
+     */
+    public static byte[] fromHexString(String values) throws NumberFormatException {
+        String[] octets = values.split(":");
+        byte[] ret = new byte[octets.length];
+
+        for (int i = 0; i < octets.length; i++) {
+            if (octets[i].length() > 2)
+                throw new NumberFormatException("Invalid octet length");
+            ret[i] = Integer.valueOf(octets[i], 16).byteValue();
+        }
+        return ret;
+    }
+
+    public static long toLong(String values) throws NumberFormatException {
+        // Long.parseLong() can't handle HexStrings with MSB set. Sigh. 
+        BigInteger bi = new BigInteger(values.replaceAll(":", ""), 16);
+        if (bi.bitLength() > 64)
+            throw new NumberFormatException("Input string too big to fit in long: " + values);
+        return bi.longValue();
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/PropertyLoader.java b/nemo-tools/sandbox/src/main/java/org/opendaylight/nemo/tool/sandbox/utils/PropertyLoader.java
new file mode 100644 (file)
index 0000000..2574d2f
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.nemo.tool.sandbox.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by hj on 9/7/15.
+ */
+public class PropertyLoader {
+    public static void loadProperties(String filePath, String noExistWarn) {
+        try {
+            InputStream propFileStream = PropertyLoader.class.getClass().getResourceAsStream(filePath);
+            if (propFileStream != null)
+                System.getProperties().load(propFileStream);
+            else {
+                System.out.println(noExistWarn);
+            }
+        } catch (IOException e) {
+            System.out.println("Read properties file error:" + e.getMessage() + "!");
+        }
+    }
+
+    public static List<String> readLines(String filePath, String noExistWarn) {
+        List<String> lines = new ArrayList<String>();
+
+        try {
+            InputStream inputStream = PropertyLoader.class.getClass().getResourceAsStream(filePath);
+            if (inputStream != null) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+                String line = null;
+                while ((line = bufferedReader.readLine()) != null) {
+                    lines.add(line);
+                }
+            }else {
+                System.out.println(noExistWarn);
+            }
+        } catch (Exception e) {
+            System.out.println("Read lines error:" + e.getMessage() + "!");
+        }
+        return lines;
+    }
+}
diff --git a/nemo-tools/sandbox/src/main/resources/Network b/nemo-tools/sandbox/src/main/resources/Network
new file mode 100644 (file)
index 0000000..1a8c196
--- /dev/null
@@ -0,0 +1,9 @@
+#switch:TYPE,NAME,DATA-PATH-ID
+#host:TYPE,NAME,UUID,Inde:IPV4,...
+#Link:TYPE,leftName,lPortId,rightName,rPortId
+
+Switch,sw1,1
+Router,sw2,2
+Firewall,firewall,1ab3cd4ef,1:192.168.1.1/16
+Link,sw1,1,sw2,1
+Link,sw1,2,firewall,1
\ No newline at end of file
diff --git a/nemo-tools/sandbox/src/main/resources/log4j.properties b/nemo-tools/sandbox/src/main/resources/log4j.properties
new file mode 100644 (file)
index 0000000..9120cd8
--- /dev/null
@@ -0,0 +1,6 @@
+log4j.rootLogger=ERROR, stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
+
+log4j.logger.com.huawei.nemo=INFO
\ No newline at end of file
diff --git a/nemo-tools/sandbox/src/main/resources/sandbox.properties b/nemo-tools/sandbox/src/main/resources/sandbox.properties
new file mode 100644 (file)
index 0000000..0d0469e
--- /dev/null
@@ -0,0 +1,11 @@
+host.name = 191.4.3.30
+host.user = root
+host.password = 123456
+controller-socket = 191.4.55.100:6633
+north.port = 10081
+config.path = /home/hj/configs
+config.hosts-file-name = nemo-openflow-render-host-resource.json
+config.externals-file-name = nemo-openflow-render-external-resource.json
+config.nodes-file-name = nemo-openflow-render-node-resource.json
+config.links-file-name = nemo-openflow-render-link-resource.json
+