Merge pull request #3 from OPENNETWORKINGLAB/master
Merge with Main
diff --git a/README.md b/README.md
index 6e65f51..495a2ed 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,92 @@
ONOS
====
-Open Networking Operating System
\ No newline at end of file
+Open Networking Operating System
+
+BELOW TO BE WRITTEN IN DETAIL
+
+
+Building ONOS
+-------------
+
+0. Install custom jars and dependencies (Only need to be run only once)
+
+ $ ./setup-local-maven.sh
+
+1. Cleanly Build ONOS
+
+ $ mvn clean
+ $ mvn compile
+
+ NOTE: installing maven for the first time may switch java version from 1.7 to 1.6 causing cassandra to not run
+
+Dependencies
+------------
+1. Zookeeper
+ Download and install apache-zookeeper-3.4.5: http://zookeeper.apache.org/releases.html
+2. Cassandra
+ Download and install apache-cassandra-1.2.2: http://cassandra.apache.org/download/
+
+Running ONOS
+------------
+
+1. Start zookeeper
+
+ $ cd (ONOS-INSTALL-DIR)/
+
+ $ ./start-zk.sh
+
+2. Start cassandra
+
+ $ cd (ONOS-INSTALL-DIR)/
+
+ $ ./start-cassandra.sh start
+
+ 1. Confirm cassandra is running
+
+ $ ./start-cassandra.sh status
+
+3. Start ONOS instance
+
+ $ cd (ONOS-INSTALL-DIR)/
+
+ $ ./start-onos.sh start
+
+4. Start ONOS rest apis
+
+ $ ./start-rest.sh start
+
+Running ONOS with Cassandra embedded (Optional)
+-----------------------------------------------
+
+1. Start Zookeeper
+
+ $ cd (ONOS-INSTALL-DIR)/
+
+ $ ./zkServer.sh start
+
+2. Start ONOS and Cassandra embedded
+
+ $ cd (ONOS-INSTALL_DIR)/
+
+ $ ./start-onos-embedded.sh start
+
+3. Start ONOS rest apis
+
+ $ ./start-rest.sh start
+
+
+Running in offline mode (Optional)
+----------------------------------
+
+Maven is used to build and run ONOS.
+By default, maven tries to reach the repositories.
+To suppress this behavior '-o' option should be given to `mvn` command.
+
+To give additional option to `mvn` commands used in ONOS,
+use the MVN environment variable.
+
+* Example: Running in offline mode
+
+ $ env MVN="mvn -o" ./start-onos.sh start
+
diff --git a/build.xml b/build.xml
deleted file mode 100644
index c7b6449..0000000
--- a/build.xml
+++ /dev/null
@@ -1,315 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-
- <!--
- Copyright 2011, Big Switch Networks, Inc.
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.
--->
-
-<!--
- The build uses pregenerated Thrift code by default to reduce build
- dependencies. To generate it locally run the gen-thrift target.
- If you change the Thrift files be sure to also commit the updated
- generated code.
--->
-
-<project default="jar" name="Floodlight">
- <property name="target" location="target"/>
- <property name="build" location="${target}/bin"/>
- <property name="build-test" location="${target}/bin-test"/>
- <property name="build-coverage" location="${target}/bin-coverage"/>
- <property name="test-output" location="${target}/test"/>
- <property name="coverage-output" location="${target}/coverage"/>
- <property name="source" location="src/main/java"/>
- <property name="resources" location="src/main/resources/"/>
- <property name="source-test" location="src/test/java"/>
- <property name="python-src" location="src/main/python"/>
- <property name="docs" location="${target}/docs"/>
- <property name="main-class" value="net.floodlightcontroller.core.Main"/>
- <property name="floodlight-jar" location="${target}/floodlight.jar"/>
- <property name="floodlight-test-jar" location="${target}/floodlight-test.jar"/>
- <property name="floodlight-only-jar" location="${target}/floodlight-only.jar"/>
- <property name="thrift.dir" value="${basedir}/src/main/thrift"/>
- <property name="thrift.out.dir" value="lib/gen-java"/>
- <property name="thrift.package" value="net/floodlightcontroller/packetstreamer/thrift"/>
- <property name="ant.build.javac.source" value="1.6"/>
- <property name="ant.build.javac.target" value="1.6"/>
- <property name="lib" location="lib"/>
- <property name="titanlib" location="lib/titan/"/>
-
- <patternset id="lib">
- <include name="logback-classic-1.0.0.jar"/>
- <include name="logback-core-1.0.0.jar"/>
- <include name="jackson-core-asl-1.9.11.jar"/>
- <include name="jackson-mapper-asl-1.9.11.jar"/>
- <include name="slf4j-api-1.6.4.jar"/>
- <include name="org.restlet-2.1-RC1.jar"/>
- <include name="org.restlet.ext.jackson-2.1-RC1.jar"/>
- <include name="org.restlet.ext.simple-2.1-RC1.jar"/>
- <include name="org.restlet.ext.slf4j-2.1-RC1.jar"/>
- <include name="simple-4.1.21.jar"/>
- <include name="netty-3.2.6.Final.jar"/>
- <include name="args4j-2.0.16.jar"/>
- <include name="concurrentlinkedhashmap-lru-1.3.jar"/>
- <include name="jython-2.5.2.jar"/>
- <include name="libthrift-0.7.0.jar"/>
- <include name="curator-client-1.3.5-SNAPSHOT.jar"/>
- <include name="curator-framework-1.3.5-SNAPSHOT.jar"/>
- <include name="curator-recipes-1.3.5-SNAPSHOT.jar"/>
- <include name="curator-x-discovery-1.3.5-SNAPSHOT.jar"/>
- <include name="zookeeper-3.4.5.jar"/>
- <include name="ezmorph-1.0.6.jar"/>
- <include name="json-lib-2.4-jdk15.jar"/>
- </patternset>
-
- <patternset id="titanlib">
- <include name="**/*.jar"/>
- </patternset>
-
- <path id="classpath">
- <fileset dir="${lib}">
- <patternset refid="lib"/>
- </fileset>
- <fileset dir="${titanlib}">
- <patternset refid="titanlib"/>
- </fileset>
- </path>
-
- <patternset id="lib-cobertura">
- <include name="cobertura-1.9.4.1.jar"/>
- <include name="asm-3.0.jar"/>
- <include name="asm-tree-3.0.jar"/>
- <include name="oro/jakarta-oro-2.0.8.jar"/>
- <include name="log4j-1.2.9.jar"/>
- </patternset>
- <path id="classpath-cobertura">
- <fileset dir="${lib}">
- <patternset refid="lib-cobertura"/>
- </fileset>
- </path>
-
- <patternset id="lib-test">
- <include name="junit-4.8.2.jar"/>
- <include name="org.easymock-3.1.jar"/>
- <include name="objenesis-1.2.jar"/> <!-- required by easymock to mock classes -->
- <include name="cglib-nodep-2.2.2.jar"/> <!-- required by easymock to mock classes -->
- </patternset>
- <path id="classpath-test">
- <fileset dir="${lib}">
- <patternset refid="lib-test"/>
- <patternset refid="lib-cobertura"/>
- <patternset refid="lib"/>
- <patternset refid="titanlib"/>
- </fileset>
- </path>
-
- <target name="init">
- <mkdir dir="${build}"/>
- <mkdir dir="${build-test}"/>
- <mkdir dir="${target}/lib"/>
- <mkdir dir="${thrift.out.dir}"/>
- <mkdir dir="${test-output}"/>
- </target>
-
- <target name="compile" depends="init">
- <javac includeAntRuntime="false"
- classpathref="classpath"
- debug="true"
- srcdir="${source}:${thrift.out.dir}"
- destdir="${build}">
- <compilerarg value="-Xlint:unchecked"/>
- </javac>
- </target>
-
- <target name="compile-tests" depends="compile-test"/>
- <target name="compile-test" depends="compile">
- <fileset dir="${resources}"/>
- <javac includeAntRuntime="false" debug="true"
- srcdir="${source-test}"
- classpath="${build}"
- classpathref="classpath-test"
- destdir="${build-test}"/>
- </target>
-
- <!-- Thrift build based on http://www.flester.com/blog/2009/04/26/using-thrift-from-ant -->
- <fileset id="thrift.files" dir="${thrift.dir}">
- <include name="**/*.thrift"/>
- </fileset>
-
- <target name="gen-thrift" depends="init">
- <pathconvert property="thrift.file.list" refid="thrift.files"
- pathsep=" " dirsep="/">
- </pathconvert>
- <echo message="Running thrift generator on ${thrift.file.list}"/>
- <exec executable="thrift" dir="${basedir}" failonerror="true">
- <arg line="--strict -v --gen java -o ${thrift.out.dir}/.. ${thrift.file.list}"/>
- </exec>
- <!-- Get rid of annoying warnings in thrift java: at annotations -->
- <echo message="Adding @SuppressWarning annotations"/>
- <replaceregexp byline="true">
- <regexp pattern="^public "/>
- <substitution expression='@SuppressWarnings("all") public '/>
- <fileset id="thrift.output.files" dir="${thrift.out.dir}/..">
- <include name="**/*.java"/>
- </fileset>
- </replaceregexp>
- </target>
-
- <target name="clean">
- <delete dir="${target}"/>
- </target>
-
- <target name="run" depends="dist">
- <java fork="true" jar="${floodlight-jar}" classpathref="classpath">
- <jvmarg value="-server"/>
- <jvmarg value="-Xms1024M"/>
- <jvmarg value="-Xmx1024M"/>
- </java>
- </target>
-
- <target name="tests" depends="test"/>
- <target name="test" depends="compile-test">
- <junit fork="true" forkmode="once"
- failureproperty="junit.failure"
- printsummary="on">
- <sysproperty key="net.sourceforge.cobertura.datafile"
- file="${target}/cobertura.ser" />
- <classpath>
- <pathelement location="${build-coverage}"/>
- <pathelement location="${build}"/>
- <pathelement location="${build-test}"/>
- <pathelement location="${floodlight-jar}"/>
- <path refid="classpath-test"/>
- </classpath>
- <formatter type="brief" usefile="true" />
- <batchtest todir="${test-output}">
- <fileset dir="${source-test}">
- <exclude name="**/storage/tests/StorageTest.java"/>
- <include name="**/*Test*.java"/>
- <exclude name="**/core/test/**"/>
- <exclude name="**/core/module/**"/>
- </fileset>
- </batchtest>
- </junit>
- <fail if="junit.failure" message="Unit test(s) failed. See reports!"/>
- </target>
-
- <taskdef classpathref="classpath-cobertura" resource="tasks.properties"/>
- <target name="clean-instrument">
- <delete file="${target}/cobertura.ser"/>
- <delete dir="${build-coverage}"/>
- </target>
- <target name="instrument" depends="compile,compile-test,clean-instrument">
- <cobertura-instrument datafile="${target}/cobertura.ser"
- todir="${build-coverage}"
- classpathref="classpath-cobertura">
- <fileset dir="${build}">
- <include name="**/*.class"/>
- </fileset>
- </cobertura-instrument>
- </target>
- <target name="coverage-report">
- <cobertura-report format="html"
- datafile="${target}/cobertura.ser"
- destdir="${coverage-output}"
- srcdir="${source}"/>
- <cobertura-report format="xml"
- datafile="${target}/cobertura.ser"
- destdir="${coverage-output}"
- srcdir="${source}"/>
- </target>
- <target name="coverage" depends="instrument,test,coverage-report"/>
-
- <target name="jar" depends="compile">
- <jar destfile="${floodlight-only-jar}">
- <fileset dir="${build}"/>
- <fileset dir="${resources}"/>
- <fileset dir="${python-src}">
- <include name="**/*.py"/>
- </fileset>
- </jar>
- </target>
-
- <target name="dist" depends="compile,compile-test">
- <jar destfile="${floodlight-jar}" filesetmanifest="mergewithoutmain">
- <manifest>
- <attribute name="Main-Class" value="${main-class}"/>
- <attribute name="Class-Path" value="."/>
- </manifest>
- <fileset dir="${build}"/>
- <fileset dir="${resources}"/>
- <fileset dir="${python-src}">
- <include name="**/*.py"/>
- </fileset>
- <zipgroupfileset dir="${titanlib}">
- <patternset refid="titanlib"/>
- </zipgroupfileset>
- <zipgroupfileset dir="${lib}">
- <patternset refid="lib"/>
- </zipgroupfileset>
- </jar>
- <jar destfile="${floodlight-test-jar}" filesetmanifest="mergewithoutmain">
- <manifest>
- <attribute name="Class-Path" value="."/>
- </manifest>
- <fileset dir="${build-test}"/>
- <fileset dir="${resources}"/>
- <zipgroupfileset dir="${lib}">
- <patternset refid="lib-test"/>
- <patternset refid="lib-cobertura"/>
- </zipgroupfileset>
- <zipgroupfileset dir="${titanlib}">
- <patternset refid="titanlib"/>
- </zipgroupfileset>
- </jar>
- </target>
-
- <target name="javadoc">
- <javadoc access="protected"
- author="true"
- classpathref="classpath"
- destdir="${docs}"
- doctitle="Floodlight"
- nodeprecated="false"
- nodeprecatedlist="false"
- noindex="false"
- nonavbar="false"
- notree="false"
- source="1.6"
- sourcepath="${source}"
- splitindex="true"
- use="true"
- version="true"/>
- </target>
-
- <target name="eclipse" depends="init">
- <pathconvert property="eclipse-lib">
- <map from="${basedir}/" to=""/>
- <fileset dir="${lib}">
- <patternset refid="lib"/>
- <patternset refid="lib-test"/>
- </fileset>
- <fileset dir="${titanlib}">
- <patternset refid="titanlib"/>
- </fileset>
- </pathconvert>
- <exec executable="${basedir}/setup-eclipse.sh">
- <arg value="${main-class}"/>
- <arg value="${eclipse-lib}"/>
- </exec>
- </target>
-
-</project>
diff --git a/cluster-mgmt/bin/bootup.sh b/cluster-mgmt/bin/bootup.sh
index e58e802..ca86f7e 100755
--- a/cluster-mgmt/bin/bootup.sh
+++ b/cluster-mgmt/bin/bootup.sh
@@ -1,5 +1,5 @@
#! /bin/bash
-. $HOME/bin/func.sh
+. `dirname $0`/func.sh
onos stop
cassandra cleandb
diff --git a/cluster-mgmt/bin/cassandra b/cluster-mgmt/bin/cassandra
index 262c936..b2033ad 100755
--- a/cluster-mgmt/bin/cassandra
+++ b/cluster-mgmt/bin/cassandra
@@ -1,5 +1,5 @@
#! /bin/bash
-. ${HOME}/bin/func.sh
+. `dirname $0`/func.sh
#$0 $1 $2
`basename $0` $1 $2
diff --git a/cluster-mgmt/bin/cmd b/cluster-mgmt/bin/cmd
index 262c936..b2033ad 100755
--- a/cluster-mgmt/bin/cmd
+++ b/cluster-mgmt/bin/cmd
@@ -1,5 +1,5 @@
#! /bin/bash
-. ${HOME}/bin/func.sh
+. `dirname $0`/func.sh
#$0 $1 $2
`basename $0` $1 $2
diff --git a/cluster-mgmt/bin/config.sh b/cluster-mgmt/bin/config.sh
index 5baf2e0..19bfbf2 100755
--- a/cluster-mgmt/bin/config.sh
+++ b/cluster-mgmt/bin/config.sh
@@ -1,6 +1,6 @@
#! /bin/sh
-. ${HOME}/bin/func.sh
+. `dirname $0`/func.sh
basename=$ONOS_CLUSTER_BASENAME
nr_nodes=$ONOS_CLUSTER_NR_NODES
diff --git a/cluster-mgmt/bin/func.sh b/cluster-mgmt/bin/func.sh
index 9785e66..b42ead1 100755
--- a/cluster-mgmt/bin/func.sh
+++ b/cluster-mgmt/bin/func.sh
@@ -1,7 +1,7 @@
-USERNAME=ubuntu
-CASSANDRA_DIR='/home/ubuntu/apache-cassandra-1.1.4'
-ZK_DIR='/home/ubuntu/zookeeper-3.4.5'
-ONOS_DIR='/home/ubuntu/ONOS'
+CASSANDRA_DIR='${HOME}/apache-cassandra-1.1.4'
+ZK_DIR='${HOME}/zookeeper-3.4.5'
+ONOS_DIR='${HOME}/ONOS'
+
ZK_LIB='/var/lib/zookeeper'
CASSANDRA_LIB='/var/lib/cassandra'
@@ -29,9 +29,11 @@
case "$1" in
start)
echo "Starting ZK.."
- dsh -g $basename "$ZK_DIR/bin/zkServer.sh start"
+# dsh -g $basename "$ZK_DIR/bin/zkServer.sh start"
+ dsh -g $basename 'cd ONOS; ./start-zk.sh start'
while [ 1 ]; do
- nup=`dsh -g $basename "$ZK_DIR/bin/zkServer.sh status" | grep "Mode" | egrep "leader|follower" | wc -l`
+# nup=`dsh -g $basename "$ZK_DIR/bin/zkServer.sh status" | grep "Mode" | egrep "leader|follower" | wc -l`
+ nup=`dsh -g $basename "cd ONOS; ./start-zk.sh status" | grep "Mode" | egrep "leader|follower|standalone" | wc -l`
if [ $nup == $nr_nodes ]; then
echo "everybody's up: $nup up of of $nr_nodes"
echo "ZK started"
@@ -75,6 +77,32 @@
sleep 1
done
;;
+ bootup)
+ echo "Removing old Cassandra data and logs"
+ dsh -g ${basename} "rm -rf /var/lib/cassandra/*"
+ dsh -g ${basename} "rm -rf /var/log/cassandra/*"
+
+ echo "Starting Cassandra nodes one by one..."
+ for (( c=1; c<=$nr_nodes; c++ ))
+ do
+ echo "Starting node ${basename}${c}"
+ dsh -g ${basename} -w ${basename}${c} "cd $ONOS_DIR; ./start-cassandra.sh start"
+
+ #Wait until it's up
+ while [ 1 ]; do
+ echo $$
+ dsh -w ${basename}1 "cd $ONOS_DIR; ./start-cassandra.sh status" > .cassandra_check.$$
+ cat .cassandra_check.$$
+ nup=`cat .cassandra_check.$$ | grep Normal |grep Up| wc -l`
+ if [ $nup == $c ]; then
+ echo "New node up: $nup up of of $nr_nodes"
+ break;
+ fi
+ echo "Waiting for new node to come up: $nup up of of $nr_nodes"
+ sleep 5
+ done
+ done
+ ;;
stop)
echo "Stopping Cassandra.."
dsh -g ${basename} "cd $ONOS_DIR; ./start-cassandra.sh stop"
@@ -99,7 +127,9 @@
start)
if [ x$2 == "x" -o x$2 == "xall" ]; then
echo "Starting ONOS on all nodes"
- dsh -g ${basename} "cd $ONOS_DIR; ./start-onos.sh start"
+ dsh -w ${basename}1 "cd $ONOS_DIR; ./start-onos.sh start"
+ sleep 3
+ dsh -g ${basename} -x ${basename}1 "cd $ONOS_DIR; ./start-onos.sh start"
dsh -g ${basename} "cd $ONOS_DIR; ./start-rest.sh start"
else
echo "Starting ONOS on ${basename}$2"
diff --git a/cluster-mgmt/bin/onos b/cluster-mgmt/bin/onos
index 262c936..b2033ad 100755
--- a/cluster-mgmt/bin/onos
+++ b/cluster-mgmt/bin/onos
@@ -1,5 +1,5 @@
#! /bin/bash
-. ${HOME}/bin/func.sh
+. `dirname $0`/func.sh
#$0 $1 $2
`basename $0` $1 $2
diff --git a/cluster-mgmt/bin/zk b/cluster-mgmt/bin/zk
index 262c936..b2033ad 100755
--- a/cluster-mgmt/bin/zk
+++ b/cluster-mgmt/bin/zk
@@ -1,5 +1,5 @@
#! /bin/bash
-. ${HOME}/bin/func.sh
+. `dirname $0`/func.sh
#$0 $1 $2
`basename $0` $1 $2
diff --git a/cluster-mgmt/common/onos.properties b/cluster-mgmt/common/onos.properties
index 1828db7..13fca75 100644
--- a/cluster-mgmt/common/onos.properties
+++ b/cluster-mgmt/common/onos.properties
@@ -8,11 +8,11 @@
net.floodlightcontroller.counter.CounterStore,\
net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.ui.web.StaticWebRoutable,\
-net.floodlightcontroller.onoslistener.OnosPublisher, \
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
net.onrc.onos.registry.controller.ZookeeperRegistry
net.floodlightcontroller.restserver.RestApiServer.port = 8080
net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
net.floodlightcontroller.jython.JythonDebugInterface.port = 6655
net.floodlightcontroller.forwarding.Forwarding.idletimeout = 5
net.floodlightcontroller.forwarding.Forwarding.hardtimeout = 0
-net.floodlightcontroller.onoslistener.OnosPublisher.dbconf = /tmp/cassandra.titan
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/cassandra.titan
diff --git a/cluster-mgmt/make-mininet.sh b/cluster-mgmt/make-mininet.sh
index 8571ce0..207b89e 100755
--- a/cluster-mgmt/make-mininet.sh
+++ b/cluster-mgmt/make-mininet.sh
@@ -8,6 +8,9 @@
fi
basename=$ONOS_CLUSTER_BASENAME
+## Shell Var can't handle "-" so replace it with "_"
+basename_var=`echo $ONOS_CLUSTER_BASENAME | sed 's/\-/_/g'`
+
NR_NODES=$ONOS_CLUSTER_NR_NODES
hosts_file=$1
@@ -21,14 +24,16 @@
done
cp template/onsdemo_core.py ${basename}1/onsdemo.py
-cat $hosts_file | awk '{printf("%s=%s\n",$2,$1)}' > .tmp
+## Shell var can't handle "-" so replace it with "_"
+cat $hosts_file | sed 's/\-/\_/g' | awk '{printf("%s=%s\n",$2,$1)}' > .tmp
+
for n in `seq 2 $NR_NODES`; do
cat template/tunnel_onsdemo_edge_template.sh | awk '{if(NR==2){system("cat .tmp")}else{print $0}}' |\
sed "s/__NWID__/$n/g" |\
- sed "s/__TUNNEL__/TUNNEL\=\(\"1 $n ${basename}1\"\)/g" > ${basename}${n}/tunnel_onsdemo.sh
+ sed "s/__TUNNEL__/TUNNEL\=\(\"1 $n ${basename_var}1\"\)/g" > ${basename}${n}/tunnel_onsdemo.sh
chmod 755 ${basename}${n}/tunnel_onsdemo.sh
done
cat template/tunnel_onsdemo_core_template.sh | awk '{if(NR==2){system("cat .tmp")}else{print $0}}' |\
- sed "s/__basename__/$basename/g" > ${basename}1/tunnel_onsdemo.sh
+ sed "s/__basename__/${basename_var}/g" > ${basename}1/tunnel_onsdemo.sh
chmod 755 ${basename}1/tunnel_onsdemo.sh
diff --git a/cluster-mgmt/template/onsdemo_core.py b/cluster-mgmt/template/onsdemo_core.py
index 61d2dcc..a0e184e 100755
--- a/cluster-mgmt/template/onsdemo_core.py
+++ b/cluster-mgmt/template/onsdemo_core.py
@@ -65,14 +65,6 @@
host5 = self.addHost( 'host5' )
host6 = self.addHost( 'host6' )
- root1 = self.addHost( 'root1', inNamespace=False )
- root2 = self.addHost( 'root2', inNamespace=False )
- root3 = self.addHost( 'root3', inNamespace=False )
- root4 = self.addHost( 'root4', inNamespace=False )
- root5 = self.addHost( 'root5', inNamespace=False )
- root6 = self.addHost( 'root6', inNamespace=False )
-
-
self.addLink( host1, sw1 )
self.addLink( host2, sw2 )
self.addLink( host3, sw3 )
@@ -80,7 +72,6 @@
self.addLink( host5, sw5 )
self.addLink( host6, sw6 )
-
self.addLink( sw1, sw2 )
self.addLink( sw1, sw6 )
self.addLink( sw2, sw3 )
@@ -90,13 +81,6 @@
self.addLink( sw5, sw6 )
self.addLink( sw4, sw6 )
- self.addLink( root1, host1 )
- self.addLink( root2, host2 )
- self.addLink( root3, host3 )
- self.addLink( root4, host4 )
- self.addLink( root5, host5 )
- self.addLink( root6, host6 )
-
def startsshd( host ):
"Start sshd on host"
info( '*** Starting sshd\n' )
@@ -154,25 +138,6 @@
host5.defaultIntf().setIP('192.168.100.145/16')
host6.defaultIntf().setIP('192.168.100.146/16')
- root1, root2, root3, root4, root5, root6 = net.get( 'root1', 'root2', 'root3', 'root4', 'root5', 'root6' )
- host1.intf('host1-eth1').setIP('1.1.1.1/24')
- root1.intf('root1-eth0').setIP('1.1.1.2/24')
-
- host2.intf('host2-eth1') .setIP('1.1.2.1/24')
- root2.intf('root2-eth0').setIP('1.1.2.2/24')
-
- host3.intf('host3-eth1') .setIP('1.1.3.1/24')
- root3.intf('root3-eth0').setIP('1.1.3.2/24')
-
- host4.intf('host4-eth1') .setIP('1.1.4.1/24')
- root4.intf('root4-eth0').setIP('1.1.4.2/24')
-
- host5.intf('host5-eth1') .setIP('1.1.5.1/24')
- root5.intf('root5-eth0').setIP('1.1.5.2/24')
-
- host6.intf('host6-eth1') .setIP('1.1.6.1/24')
- root6.intf('root6-eth0').setIP('1.1.6.2/24')
-
hosts = [ host1, host2, host3, host4, host5, host6 ]
stopsshd ()
startsshds ( hosts )
diff --git a/cluster-mgmt/template/onsdemo_core.py.devA b/cluster-mgmt/template/onsdemo_core.py.devA
new file mode 100755
index 0000000..ad74e4b
--- /dev/null
+++ b/cluster-mgmt/template/onsdemo_core.py.devA
@@ -0,0 +1,158 @@
+#!/usr/bin/python
+
+"""
+Start up a Simple topology
+"""
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController
+from mininet.log import setLogLevel, info, error, warn, debug
+from mininet.cli import CLI
+from mininet.topo import Topo
+from mininet.util import quietRun
+from mininet.moduledeps import pathCheck
+from mininet.link import Link, TCLink
+
+from sys import exit
+import os.path
+from subprocess import Popen, STDOUT, PIPE
+
+import sys
+
+
+#import argparse
+
+class MyController( Controller ):
+ def __init__( self, name, ip='127.0.0.1', port=6633, **kwargs):
+ """Init.
+ name: name to give controller
+ ip: the IP address where the remote controller is
+ listening
+ port: the port where the remote controller is listening"""
+ Controller.__init__( self, name, ip=ip, port=port, **kwargs )
+
+ def start( self ):
+ "Overridden to do nothing."
+ return
+
+ def stop( self ):
+ "Overridden to do nothing."
+ return
+
+ def checkListening( self ):
+ "Warn if remote controller is not accessible"
+ listening = self.cmd( "echo A | telnet -e A %s %d" %
+ ( self.ip, self.port ) )
+ if 'Unable' in listening:
+ warn( "Unable to contact the remote controller"
+ " at %s:%d\n" % ( self.ip, self.port ) )
+
+class SDNTopo( Topo ):
+ "SDN Topology"
+
+ def __init__( self, *args, **kwargs ):
+ Topo.__init__( self, *args, **kwargs )
+
+ sw5 = self.addSwitch('sw5', dpid='00000000ba5eba13')
+ sw2 = self.addSwitch('sw2', dpid='00000000ba5eba11')
+ sw3 = self.addSwitch('sw3', dpid='00000008a208f901')
+ sw4 = self.addSwitch('sw4', dpid='000000000000ba12')
+ sw6 = self.addSwitch('sw6', dpid='0000204e7f518a35')
+ sw1 = self.addSwitch('sw1', dpid='0000001697089a46')
+
+ host1 = self.addHost( 'host1' )
+ host2 = self.addHost( 'host2' )
+ host3 = self.addHost( 'host3' )
+ host4 = self.addHost( 'host4' )
+ host5 = self.addHost( 'host5' )
+ host6 = self.addHost( 'host6' )
+
+ self.addLink( host1, sw1 )
+ self.addLink( host2, sw2 )
+ self.addLink( host3, sw3 )
+ self.addLink( host4, sw4 )
+ self.addLink( host5, sw5 )
+ self.addLink( host6, sw6 )
+
+ self.addLink( sw1, sw2 )
+ self.addLink( sw1, sw6 )
+ self.addLink( sw2, sw3 )
+ self.addLink( sw3, sw4 )
+ self.addLink( sw3, sw6 )
+ self.addLink( sw4, sw5 )
+ self.addLink( sw5, sw6 )
+ self.addLink( sw4, sw6 )
+
+def startsshd( host ):
+ "Start sshd on host"
+ info( '*** Starting sshd\n' )
+ name, intf, ip = host.name, host.defaultIntf(), host.IP()
+ banner = '/tmp/%s.banner' % name
+ host.cmd( 'echo "Welcome to %s at %s" > %s' % ( name, ip, banner ) )
+ host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
+ info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
+
+def startsshds ( hosts ):
+ for h in hosts:
+ startsshd( h )
+
+def stopsshd( ):
+ "Stop *all* sshd processes with a custom banner"
+ info( '*** Shutting down stale sshd/Banner processes ',
+ quietRun( "pkill -9 -f Banner" ), '\n' )
+
+def sdnnet(opt):
+# os.system('/home/ubuntu/openflow/controller/controller ptcp: &')
+# os.system('/home/ubuntu/openflow/controller/controller ptcp:7000 &')
+
+ topo = SDNTopo()
+ info( '*** Creating network\n' )
+# net = Mininet( topo=topo, controller=RemoteController )
+ net = Mininet( topo=topo, controller=MyController, link=TCLink)
+# dc = DebugController('c3', ip='127.0.0.1', port=7000)
+# net.addController(dc)
+# net.addController(controller=RemoteController)
+
+ host1, host2, host3, host4, host5, host6 = net.get( 'host1', 'host2', 'host3', 'host4', 'host5', 'host6')
+
+ ## Adding 2nd, 3rd and 4th interface to host1 connected to sw1 (for another BGP peering)
+ sw1 = net.get('sw1')
+ sw2 = net.get('sw2')
+ sw3 = net.get('sw3')
+ sw4 = net.get('sw4')
+ sw5 = net.get('sw5')
+ sw6 = net.get('sw6')
+
+ net.start()
+
+ sw2.attach('tap01_2')
+ sw3.attach('tap01_3')
+ sw4.attach('tap01_4')
+ sw4.attach('tap01_5')
+ sw5.attach('tap01_6')
+ sw6.attach('tap01_7')
+ sw1.attach('tap01_8')
+
+ host1.defaultIntf().setIP('192.168.100.141/16')
+ host2.defaultIntf().setIP('192.168.100.142/16')
+ host3.defaultIntf().setIP('192.168.100.143/16')
+ host4.defaultIntf().setIP('192.168.100.144/16')
+ host5.defaultIntf().setIP('192.168.100.145/16')
+ host6.defaultIntf().setIP('192.168.100.146/16')
+
+ hosts = [ host1, host2, host3, host4, host5, host6 ]
+ stopsshd ()
+ startsshds ( hosts )
+
+ if opt=="cli":
+ CLI(net)
+ stopsshd()
+ net.stop()
+
+if __name__ == '__main__':
+ setLogLevel( 'info' )
+ if len(sys.argv) == 1:
+ sdnnet("cli")
+ elif len(sys.argv) == 2 and sys.argv[1] == "-n":
+ sdnnet("nocli")
+ else:
+ print "%s [-n]" % sys.argv[0]
diff --git a/cluster-mgmt/template/onsdemo_edge_template.py b/cluster-mgmt/template/onsdemo_edge_template.py
index 1f746f3..e340f38 100755
--- a/cluster-mgmt/template/onsdemo_edge_template.py
+++ b/cluster-mgmt/template/onsdemo_edge_template.py
@@ -56,7 +56,6 @@
switch = []
host = []
- root = []
for i in range (NR_NODES):
name_suffix = '%02d' % NWID + "." + '%02d' % (int(i)+1)
@@ -67,7 +66,6 @@
for i in range (NR_NODES):
host.append(self.addHost( 'host%d' % (int(i)+1) ))
- root.append(self.addHost( 'root%d' % (int(i)+1), inNamespace=False ))
for i in range (NR_NODES):
self.addLink(host[i], switch[i])
@@ -75,9 +73,6 @@
for i in range (1, NR_NODES):
self.addLink(switch[0], switch[i])
- for i in range (NR_NODES):
- self.addLink(root[i], host[i])
-
def startsshd( host ):
"Start sshd on host"
info( '*** Starting sshd\n' )
@@ -139,14 +134,6 @@
for h in range (25):
host[i].setARP('192.168.%d.%d' % (n, (int(h)+1)), '00:00:%02x:%02x:%02x:%02x' % (192,168,n,(int(h)+1)))
- root = []
- for i in range (NR_NODES):
- root.append(net.get( 'root%d' % (int(i)+1) ))
-
- for i in range (NR_NODES):
- host[i].intf('host%d-eth1' % (int(i)+1)).setIP('1.1.%d.1/24' % (int(i)+1))
- root[i].intf('root%d-eth0' % (int(i)+1)).setIP('1.1.%d.2/24' % (int(i)+1))
-
stopsshd ()
# stopiperf ()
startsshds ( host )
diff --git a/conf/README b/conf/README
new file mode 100644
index 0000000..f43d67b
--- /dev/null
+++ b/conf/README
@@ -0,0 +1 @@
+Please use onos-embedded.properties to start onos with embedded cassandra.
diff --git a/cassandra.titan b/conf/cassandra.titan
similarity index 100%
rename from cassandra.titan
rename to conf/cassandra.titan
diff --git a/cassandra.titan.nothrift b/conf/cassandra.titan.nothrift
similarity index 100%
rename from cassandra.titan.nothrift
rename to conf/cassandra.titan.nothrift
diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml
new file mode 100644
index 0000000..277f03a
--- /dev/null
+++ b/conf/cassandra.yaml
@@ -0,0 +1,643 @@
+# Cassandra storage config YAML
+
+# NOTE:
+# See http://wiki.apache.org/cassandra/StorageConfiguration for
+# full explanations of configuration directives
+# /NOTE
+
+# The name of the cluster. This is mainly used to prevent machines in
+# one logical cluster from joining another.
+cluster_name: 'Test Cluster'
+
+# This defines the number of tokens randomly assigned to this node on the ring
+# The more tokens, relative to other nodes, the larger the proportion of data
+# that this node will store. You probably want all nodes to have the same number
+# of tokens assuming they have equal hardware capability.
+#
+# If you leave this unspecified, Cassandra will use the default of 1 token for legacy compatibility,
+# and will use the initial_token as described below.
+#
+# Specifying initial_token will override this setting.
+#
+# If you already have a cluster with 1 token per node, and wish to migrate to
+# multiple tokens per node, see http://wiki.apache.org/cassandra/Operations
+# num_tokens: 256
+
+# If you haven't specified num_tokens, or have set it to the default of 1 then
+# you should always specify InitialToken when setting up a production
+# cluster for the first time, and often when adding capacity later.
+# The principle is that each node should be given an equal slice of
+# the token ring; see http://wiki.apache.org/cassandra/Operations
+# for more details.
+#
+# If blank, Cassandra will request a token bisecting the range of
+# the heaviest-loaded existing node. If there is no load information
+# available, such as is the case with a new cluster, it will pick
+# a random token, which will lead to hot spots.
+initial_token:
+
+# See http://wiki.apache.org/cassandra/HintedHandoff
+hinted_handoff_enabled: true
+# this defines the maximum amount of time a dead host will have hints
+# generated. After it has been dead this long, hints will be dropped.
+max_hint_window_in_ms: 10800000 # 3 hours
+# throttle in KB's per second, per delivery thread
+hinted_handoff_throttle_in_kb: 1024
+# Number of threads with which to deliver hints;
+# Consider increasing this number when you have multi-dc deployments, since
+# cross-dc handoff tends to be slower
+max_hints_delivery_threads: 2
+
+# The following setting populates the page cache on memtable flush and compaction
+# WARNING: Enable this setting only when the whole node's data fits in memory.
+# Defaults to: false
+# populate_io_cache_on_flush: false
+
+# authentication backend, implementing IAuthenticator; used to identify users
+authenticator: org.apache.cassandra.auth.AllowAllAuthenticator
+
+# authorization backend, implementing IAuthorizer; used to limit access/provide permissions
+authorizer: org.apache.cassandra.auth.AllowAllAuthorizer
+
+# The partitioner is responsible for distributing rows (by key) across
+# nodes in the cluster. Any IPartitioner may be used, including your
+# own as long as it is on the classpath. Out of the box, Cassandra
+# provides org.apache.cassandra.dht.{Murmur3Partitioner, RandomPartitioner
+# ByteOrderedPartitioner, OrderPreservingPartitioner (deprecated)}.
+#
+# - RandomPartitioner distributes rows across the cluster evenly by md5.
+# This is the default prior to 1.2 and is retained for compatibility.
+# - Murmur3Partitioner is similar to RandomPartioner but uses Murmur3_128
+# Hash Function instead of md5. When in doubt, this is the best option.
+# - ByteOrderedPartitioner orders rows lexically by key bytes. BOP allows
+# scanning rows in key order, but the ordering can generate hot spots
+# for sequential insertion workloads.
+# - OrderPreservingPartitioner is an obsolete form of BOP, that stores
+# - keys in a less-efficient format and only works with keys that are
+# UTF8-encoded Strings.
+# - CollatingOPP colates according to EN,US rules rather than lexical byte
+# ordering. Use this as an example if you need custom collation.
+#
+# See http://wiki.apache.org/cassandra/Operations for more on
+# partitioners and token selection.
+partitioner: org.apache.cassandra.dht.RandomPartitioner
+
+# directories where Cassandra should store data on disk.
+data_file_directories:
+ - /tmp/cassandra/data
+
+# commit log
+commitlog_directory: /tmp/cassandra/commitlog
+
+# policy for data disk failures:
+# stop: shut down gossip and Thrift, leaving the node effectively dead, but
+# still inspectable via JMX.
+# best_effort: stop using the failed disk and respond to requests based on
+# remaining available sstables. This means you WILL see obsolete
+# data at CL.ONE!
+# ignore: ignore fatal errors and let requests fail, as in pre-1.2 Cassandra
+disk_failure_policy: stop
+
+# Maximum size of the key cache in memory.
+#
+# Each key cache hit saves 1 seek and each row cache hit saves 2 seeks at the
+# minimum, sometimes more. The key cache is fairly tiny for the amount of
+# time it saves, so it's worthwhile to use it at large numbers.
+# The row cache saves even more time, but must store the whole values of
+# its rows, so it is extremely space-intensive. It's best to only use the
+# row cache if you have hot rows or static rows.
+#
+# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup.
+#
+# Default value is empty to make it "auto" (min(5% of Heap (in MB), 100MB)). Set to 0 to disable key cache.
+key_cache_size_in_mb:
+
+# Duration in seconds after which Cassandra should
+# safe the keys cache. Caches are saved to saved_caches_directory as
+# specified in this configuration file.
+#
+# Saved caches greatly improve cold-start speeds, and is relatively cheap in
+# terms of I/O for the key cache. Row cache saving is much more expensive and
+# has limited use.
+#
+# Default is 14400 or 4 hours.
+key_cache_save_period: 14400
+
+# Number of keys from the key cache to save
+# Disabled by default, meaning all keys are going to be saved
+# key_cache_keys_to_save: 100
+
+# Maximum size of the row cache in memory.
+# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup.
+#
+# Default value is 0, to disable row caching.
+row_cache_size_in_mb: 0
+
+# Duration in seconds after which Cassandra should
+# safe the row cache. Caches are saved to saved_caches_directory as specified
+# in this configuration file.
+#
+# Saved caches greatly improve cold-start speeds, and is relatively cheap in
+# terms of I/O for the key cache. Row cache saving is much more expensive and
+# has limited use.
+#
+# Default is 0 to disable saving the row cache.
+row_cache_save_period: 0
+
+# Number of keys from the row cache to save
+# Disabled by default, meaning all keys are going to be saved
+# row_cache_keys_to_save: 100
+
+# The provider for the row cache to use.
+#
+# Supported values are: ConcurrentLinkedHashCacheProvider, SerializingCacheProvider
+#
+# SerializingCacheProvider serialises the contents of the row and stores
+# it in native memory, i.e., off the JVM Heap. Serialized rows take
+# significantly less memory than "live" rows in the JVM, so you can cache
+# more rows in a given memory footprint. And storing the cache off-heap
+# means you can use smaller heap sizes, reducing the impact of GC pauses.
+#
+# It is also valid to specify the fully-qualified class name to a class
+# that implements org.apache.cassandra.cache.IRowCacheProvider.
+#
+# Defaults to SerializingCacheProvider
+row_cache_provider: SerializingCacheProvider
+
+# saved caches
+saved_caches_directory: /tmp/cassandra/saved_caches
+
+# commitlog_sync may be either "periodic" or "batch."
+# When in batch mode, Cassandra won't ack writes until the commit log
+# has been fsynced to disk. It will wait up to
+# commitlog_sync_batch_window_in_ms milliseconds for other writes, before
+# performing the sync.
+#
+# commitlog_sync: batch
+# commitlog_sync_batch_window_in_ms: 50
+#
+# the other option is "periodic" where writes may be acked immediately
+# and the CommitLog is simply synced every commitlog_sync_period_in_ms
+# milliseconds.
+commitlog_sync: periodic
+commitlog_sync_period_in_ms: 10000
+
+# The size of the individual commitlog file segments. A commitlog
+# segment may be archived, deleted, or recycled once all the data
+# in it (potentally from each columnfamily in the system) has been
+# flushed to sstables.
+#
+# The default size is 32, which is almost always fine, but if you are
+# archiving commitlog segments (see commitlog_archiving.properties),
+# then you probably want a finer granularity of archiving; 8 or 16 MB
+# is reasonable.
+commitlog_segment_size_in_mb: 32
+
+# any class that implements the SeedProvider interface and has a
+# constructor that takes a Map<String, String> of parameters will do.
+seed_provider:
+ # Addresses of hosts that are deemed contact points.
+ # Cassandra nodes use this list of hosts to find each other and learn
+ # the topology of the ring. You must change this if you are running
+ # multiple nodes!
+ - class_name: org.apache.cassandra.locator.SimpleSeedProvider
+ parameters:
+ # seeds is actually a comma-delimited list of addresses.
+ # Ex: "<ip1>,<ip2>,<ip3>"
+ - seeds: "127.0.0.1"
+
+# emergency pressure valve: each time heap usage after a full (CMS)
+# garbage collection is above this fraction of the max, Cassandra will
+# flush the largest memtables.
+#
+# Set to 1.0 to disable. Setting this lower than
+# CMSInitiatingOccupancyFraction is not likely to be useful.
+#
+# RELYING ON THIS AS YOUR PRIMARY TUNING MECHANISM WILL WORK POORLY:
+# it is most effective under light to moderate load, or read-heavy
+# workloads; under truly massive write load, it will often be too
+# little, too late.
+flush_largest_memtables_at: 0.75
+
+# emergency pressure valve #2: the first time heap usage after a full
+# (CMS) garbage collection is above this fraction of the max,
+# Cassandra will reduce cache maximum _capacity_ to the given fraction
+# of the current _size_. Should usually be set substantially above
+# flush_largest_memtables_at, since that will have less long-term
+# impact on the system.
+#
+# Set to 1.0 to disable. Setting this lower than
+# CMSInitiatingOccupancyFraction is not likely to be useful.
+reduce_cache_sizes_at: 0.85
+reduce_cache_capacity_to: 0.6
+
+# For workloads with more data than can fit in memory, Cassandra's
+# bottleneck will be reads that need to fetch data from
+# disk. "concurrent_reads" should be set to (16 * number_of_drives) in
+# order to allow the operations to enqueue low enough in the stack
+# that the OS and drives can reorder them.
+#
+# On the other hand, since writes are almost never IO bound, the ideal
+# number of "concurrent_writes" is dependent on the number of cores in
+# your system; (8 * number_of_cores) is a good rule of thumb.
+concurrent_reads: 32
+concurrent_writes: 32
+
+# Total memory to use for memtables. Cassandra will flush the largest
+# memtable when this much memory is used.
+# If omitted, Cassandra will set it to 1/3 of the heap.
+# memtable_total_space_in_mb: 2048
+
+# Total space to use for commitlogs. Since commitlog segments are
+# mmapped, and hence use up address space, the default size is 32
+# on 32-bit JVMs, and 1024 on 64-bit JVMs.
+#
+# If space gets above this value (it will round up to the next nearest
+# segment multiple), Cassandra will flush every dirty CF in the oldest
+# segment and remove it. So a small total commitlog space will tend
+# to cause more flush activity on less-active columnfamilies.
+# commitlog_total_space_in_mb: 4096
+
+# This sets the amount of memtable flush writer threads. These will
+# be blocked by disk io, and each one will hold a memtable in memory
+# while blocked. If you have a large heap and many data directories,
+# you can increase this value for better flush performance.
+# By default this will be set to the amount of data directories defined.
+#memtable_flush_writers: 1
+
+# the number of full memtables to allow pending flush, that is,
+# waiting for a writer thread. At a minimum, this should be set to
+# the maximum number of secondary indexes created on a single CF.
+memtable_flush_queue_size: 4
+
+# Whether to, when doing sequential writing, fsync() at intervals in
+# order to force the operating system to flush the dirty
+# buffers. Enable this to avoid sudden dirty buffer flushing from
+# impacting read latencies. Almost always a good idea on SSD:s; not
+# necessarily on platters.
+trickle_fsync: false
+trickle_fsync_interval_in_kb: 10240
+
+# TCP port, for commands and data
+storage_port: 7000
+
+# SSL port, for encrypted communication. Unused unless enabled in
+# encryption_options
+ssl_storage_port: 7001
+
+# Address to bind to and tell other Cassandra nodes to connect to. You
+# _must_ change this if you want multiple nodes to be able to
+# communicate!
+#
+# Leaving it blank leaves it up to InetAddress.getLocalHost(). This
+# will always do the Right Thing *if* the node is properly configured
+# (hostname, name resolution, etc), and the Right Thing is to use the
+# address associated with the hostname (it might not be).
+#
+# Setting this to 0.0.0.0 is always wrong.
+listen_address: localhost
+
+# Address to broadcast to other Cassandra nodes
+# Leaving this blank will set it to the same value as listen_address
+# broadcast_address: 1.2.3.4
+
+
+# Whether to start the native transport server.
+# Currently, only the thrift server is started by default because the native
+# transport is considered beta.
+# Please note that the address on which the native transport is bound is the
+# same as the rpc_address. The port however is different and specified below.
+start_native_transport: false
+# port for the CQL native transport to listen for clients on
+native_transport_port: 9042
+# The minimum and maximum threads for handling requests when the native
+# transport is used. The meaning is those is similar to the one of
+# rpc_min_threads and rpc_max_threads, though the default differ slightly and
+# are the ones below:
+# native_transport_min_threads: 16
+# native_transport_max_threads: 128
+
+
+# Whether to start the thrift rpc server.
+start_rpc: true
+# The address to bind the Thrift RPC service to -- clients connect
+# here. Unlike ListenAddress above, you *can* specify 0.0.0.0 here if
+# you want Thrift to listen on all interfaces.
+#
+# Leaving this blank has the same effect it does for ListenAddress,
+# (i.e. it will be based on the configured hostname of the node).
+rpc_address: localhost
+# port for Thrift to listen for clients on
+rpc_port: 9160
+
+# enable or disable keepalive on rpc connections
+rpc_keepalive: true
+
+# Cassandra provides three out-of-the-box options for the RPC Server:
+#
+# sync -> One thread per thrift connection. For a very large number of clients, memory
+# will be your limiting factor. On a 64 bit JVM, 128KB is the minimum stack size
+# per thread, and that will correspond to your use of virtual memory (but physical memory
+# may be limited depending on use of stack space).
+#
+# hsha -> Stands for "half synchronous, half asynchronous." All thrift clients are handled
+# asynchronously using a small number of threads that does not vary with the amount
+# of thrift clients (and thus scales well to many clients). The rpc requests are still
+# synchronous (one thread per active request).
+#
+# The default is sync because on Windows hsha is about 30% slower. On Linux,
+# sync/hsha performance is about the same, with hsha of course using less memory.
+#
+# Alternatively, can provide your own RPC server by providing the fully-qualified class name
+# of an o.a.c.t.TServerFactory that can create an instance of it.
+rpc_server_type: sync
+
+# Uncomment rpc_min|max_thread to set request pool size limits.
+#
+# Regardless of your choice of RPC server (see above), the number of maximum requests in the
+# RPC thread pool dictates how many concurrent requests are possible (but if you are using the sync
+# RPC server, it also dictates the number of clients that can be connected at all).
+#
+# The default is unlimited and thus provide no protection against clients overwhelming the server. You are
+# encouraged to set a maximum that makes sense for you in production, but do keep in mind that
+# rpc_max_threads represents the maximum number of client requests this server may execute concurrently.
+#
+# rpc_min_threads: 16
+# rpc_max_threads: 2048
+
+# uncomment to set socket buffer sizes on rpc connections
+# rpc_send_buff_size_in_bytes:
+# rpc_recv_buff_size_in_bytes:
+
+# Frame size for thrift (maximum field length).
+thrift_framed_transport_size_in_mb: 15
+
+# The max length of a thrift message, including all fields and
+# internal thrift overhead.
+thrift_max_message_length_in_mb: 16
+
+# Set to true to have Cassandra create a hard link to each sstable
+# flushed or streamed locally in a backups/ subdirectory of the
+# Keyspace data. Removing these links is the operator's
+# responsibility.
+incremental_backups: false
+
+# Whether or not to take a snapshot before each compaction. Be
+# careful using this option, since Cassandra won't clean up the
+# snapshots for you. Mostly useful if you're paranoid when there
+# is a data format change.
+snapshot_before_compaction: false
+
+# Whether or not a snapshot is taken of the data before keyspace truncation
+# or dropping of column families. The STRONGLY advised default of true
+# should be used to provide data safety. If you set this flag to false, you will
+# lose data on truncation or drop.
+auto_snapshot: true
+
+# Add column indexes to a row after its contents reach this size.
+# Increase if your column values are large, or if you have a very large
+# number of columns. The competing causes are, Cassandra has to
+# deserialize this much of the row to read a single column, so you want
+# it to be small - at least if you do many partial-row reads - but all
+# the index data is read for each access, so you don't want to generate
+# that wastefully either.
+column_index_size_in_kb: 64
+
+# Size limit for rows being compacted in memory. Larger rows will spill
+# over to disk and use a slower two-pass compaction process. A message
+# will be logged specifying the row key.
+in_memory_compaction_limit_in_mb: 64
+
+# Number of simultaneous compactions to allow, NOT including
+# validation "compactions" for anti-entropy repair. Simultaneous
+# compactions can help preserve read performance in a mixed read/write
+# workload, by mitigating the tendency of small sstables to accumulate
+# during a single long running compactions. The default is usually
+# fine and if you experience problems with compaction running too
+# slowly or too fast, you should look at
+# compaction_throughput_mb_per_sec first.
+#
+# concurrent_compactors defaults to the number of cores.
+# Uncomment to make compaction mono-threaded, the pre-0.8 default.
+#concurrent_compactors: 1
+
+# Multi-threaded compaction. When enabled, each compaction will use
+# up to one thread per core, plus one thread per sstable being merged.
+# This is usually only useful for SSD-based hardware: otherwise,
+# your concern is usually to get compaction to do LESS i/o (see:
+# compaction_throughput_mb_per_sec), not more.
+multithreaded_compaction: false
+
+# Throttles compaction to the given total throughput across the entire
+# system. The faster you insert data, the faster you need to compact in
+# order to keep the sstable count down, but in general, setting this to
+# 16 to 32 times the rate you are inserting data is more than sufficient.
+# Setting this to 0 disables throttling. Note that this account for all types
+# of compaction, including validation compaction.
+compaction_throughput_mb_per_sec: 16
+
+# Track cached row keys during compaction, and re-cache their new
+# positions in the compacted sstable. Disable if you use really large
+# key caches.
+compaction_preheat_key_cache: true
+
+# Throttles all outbound streaming file transfers on this node to the
+# given total throughput in Mbps. This is necessary because Cassandra does
+# mostly sequential IO when streaming data during bootstrap or repair, which
+# can lead to saturating the network connection and degrading rpc performance.
+# When unset, the default is 400 Mbps or 50 MB/s.
+# stream_throughput_outbound_megabits_per_sec: 400
+
+# How long the coordinator should wait for read operations to complete
+read_request_timeout_in_ms: 10000
+# How long the coordinator should wait for seq or index scans to complete
+range_request_timeout_in_ms: 10000
+# How long the coordinator should wait for writes to complete
+write_request_timeout_in_ms: 10000
+# How long the coordinator should wait for truncates to complete
+# (This can be much longer, because unless auto_snapshot is disabled
+# we need to flush first so we can snapshot before removing the data.)
+truncate_request_timeout_in_ms: 60000
+# The default timeout for other, miscellaneous operations
+request_timeout_in_ms: 10000
+
+# Enable operation timeout information exchange between nodes to accurately
+# measure request timeouts, If disabled cassandra will assuming the request
+# was forwarded to the replica instantly by the coordinator
+#
+# Warning: before enabling this property make sure to ntp is installed
+# and the times are synchronized between the nodes.
+cross_node_timeout: false
+
+# Enable socket timeout for streaming operation.
+# When a timeout occurs during streaming, streaming is retried from the start
+# of the current file. This *can* involve re-streaming an important amount of
+# data, so you should avoid setting the value too low.
+# Default value is 0, which never timeout streams.
+# streaming_socket_timeout_in_ms: 0
+
+# phi value that must be reached for a host to be marked down.
+# most users should never need to adjust this.
+# phi_convict_threshold: 8
+
+# endpoint_snitch -- Set this to a class that implements
+# IEndpointSnitch. The snitch has two functions:
+# - it teaches Cassandra enough about your network topology to route
+# requests efficiently
+# - it allows Cassandra to spread replicas around your cluster to avoid
+# correlated failures. It does this by grouping machines into
+# "datacenters" and "racks." Cassandra will do its best not to have
+# more than one replica on the same "rack" (which may not actually
+# be a physical location)
+#
+# IF YOU CHANGE THE SNITCH AFTER DATA IS INSERTED INTO THE CLUSTER,
+# YOU MUST RUN A FULL REPAIR, SINCE THE SNITCH AFFECTS WHERE REPLICAS
+# ARE PLACED.
+#
+# Out of the box, Cassandra provides
+# - SimpleSnitch:
+# Treats Strategy order as proximity. This improves cache locality
+# when disabling read repair, which can further improve throughput.
+# Only appropriate for single-datacenter deployments.
+# - PropertyFileSnitch:
+# Proximity is determined by rack and data center, which are
+# explicitly configured in cassandra-topology.properties.
+# - GossipingPropertyFileSnitch
+# The rack and datacenter for the local node are defined in
+# cassandra-rackdc.properties and propagated to other nodes via gossip. If
+# cassandra-topology.properties exists, it is used as a fallback, allowing
+# migration from the PropertyFileSnitch.
+# - RackInferringSnitch:
+# Proximity is determined by rack and data center, which are
+# assumed to correspond to the 3rd and 2nd octet of each node's
+# IP address, respectively. Unless this happens to match your
+# deployment conventions (as it did Facebook's), this is best used
+# as an example of writing a custom Snitch class.
+# - Ec2Snitch:
+# Appropriate for EC2 deployments in a single Region. Loads Region
+# and Availability Zone information from the EC2 API. The Region is
+# treated as the Datacenter, and the Availability Zone as the rack.
+# Only private IPs are used, so this will not work across multiple
+# Regions.
+# - Ec2MultiRegionSnitch:
+# Uses public IPs as broadcast_address to allow cross-region
+# connectivity. (Thus, you should set seed addresses to the public
+# IP as well.) You will need to open the storage_port or
+# ssl_storage_port on the public IP firewall. (For intra-Region
+# traffic, Cassandra will switch to the private IP after
+# establishing a connection.)
+#
+# You can use a custom Snitch by setting this to the full class name
+# of the snitch, which will be assumed to be on your classpath.
+endpoint_snitch: SimpleSnitch
+
+# controls how often to perform the more expensive part of host score
+# calculation
+dynamic_snitch_update_interval_in_ms: 100
+# controls how often to reset all host scores, allowing a bad host to
+# possibly recover
+dynamic_snitch_reset_interval_in_ms: 600000
+# if set greater than zero and read_repair_chance is < 1.0, this will allow
+# 'pinning' of replicas to hosts in order to increase cache capacity.
+# The badness threshold will control how much worse the pinned host has to be
+# before the dynamic snitch will prefer other replicas over it. This is
+# expressed as a double which represents a percentage. Thus, a value of
+# 0.2 means Cassandra would continue to prefer the static snitch values
+# until the pinned host was 20% worse than the fastest.
+dynamic_snitch_badness_threshold: 0.1
+
+# request_scheduler -- Set this to a class that implements
+# RequestScheduler, which will schedule incoming client requests
+# according to the specific policy. This is useful for multi-tenancy
+# with a single Cassandra cluster.
+# NOTE: This is specifically for requests from the client and does
+# not affect inter node communication.
+# org.apache.cassandra.scheduler.NoScheduler - No scheduling takes place
+# org.apache.cassandra.scheduler.RoundRobinScheduler - Round robin of
+# client requests to a node with a separate queue for each
+# request_scheduler_id. The scheduler is further customized by
+# request_scheduler_options as described below.
+request_scheduler: org.apache.cassandra.scheduler.NoScheduler
+
+# Scheduler Options vary based on the type of scheduler
+# NoScheduler - Has no options
+# RoundRobin
+# - throttle_limit -- The throttle_limit is the number of in-flight
+# requests per client. Requests beyond
+# that limit are queued up until
+# running requests can complete.
+# The value of 80 here is twice the number of
+# concurrent_reads + concurrent_writes.
+# - default_weight -- default_weight is optional and allows for
+# overriding the default which is 1.
+# - weights -- Weights are optional and will default to 1 or the
+# overridden default_weight. The weight translates into how
+# many requests are handled during each turn of the
+# RoundRobin, based on the scheduler id.
+#
+# request_scheduler_options:
+# throttle_limit: 80
+# default_weight: 5
+# weights:
+# Keyspace1: 1
+# Keyspace2: 5
+
+# request_scheduler_id -- An identifer based on which to perform
+# the request scheduling. Currently the only valid option is keyspace.
+# request_scheduler_id: keyspace
+
+# index_interval controls the sampling of entries from the primrary
+# row index in terms of space versus time. The larger the interval,
+# the smaller and less effective the sampling will be. In technicial
+# terms, the interval coresponds to the number of index entries that
+# are skipped between taking each sample. All the sampled entries
+# must fit in memory. Generally, a value between 128 and 512 here
+# coupled with a large key cache size on CFs results in the best trade
+# offs. This value is not often changed, however if you have many
+# very small rows (many to an OS page), then increasing this will
+# often lower memory usage without a impact on performance.
+index_interval: 128
+
+# Enable or disable inter-node encryption
+# Default settings are TLS v1, RSA 1024-bit keys (it is imperative that
+# users generate their own keys) TLS_RSA_WITH_AES_128_CBC_SHA as the cipher
+# suite for authentication, key exchange and encryption of the actual data transfers.
+# NOTE: No custom encryption options are enabled at the moment
+# The available internode options are : all, none, dc, rack
+#
+# If set to dc cassandra will encrypt the traffic between the DCs
+# If set to rack cassandra will encrypt the traffic between the racks
+#
+# The passwords used in these options must match the passwords used when generating
+# the keystore and truststore. For instructions on generating these files, see:
+# http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore
+#
+server_encryption_options:
+ internode_encryption: none
+ keystore: conf/.keystore
+ keystore_password: cassandra
+ truststore: conf/.truststore
+ truststore_password: cassandra
+ # More advanced defaults below:
+ # protocol: TLS
+ # algorithm: SunX509
+ # store_type: JKS
+ # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA]
+
+# enable or disable client/server encryption.
+client_encryption_options:
+ enabled: false
+ keystore: conf/.keystore
+ keystore_password: cassandra
+ # More advanced defaults below:
+ # protocol: TLS
+ # algorithm: SunX509
+ # store_type: JKS
+ # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA]
+
+# internode_compression controls whether traffic between nodes is
+# compressed.
+# can be: all - all traffic is compressed
+# dc - traffic between different datacenters is compressed
+# none - nothing is compressed.
+internode_compression: all
diff --git a/conf/onos-embedded.properties b/conf/onos-embedded.properties
new file mode 100644
index 0000000..83e5ad3
--- /dev/null
+++ b/conf/onos-embedded.properties
@@ -0,0 +1,17 @@
+floodlight.modules = net.floodlightcontroller.storage.memory.MemoryStorageSource,\
+net.floodlightcontroller.core.FloodlightProvider,\
+net.floodlightcontroller.threadpool.ThreadPool,\
+net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
+net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
+net.floodlightcontroller.counter.CounterStore,\
+net.floodlightcontroller.perfmon.PktInProcessingTime,\
+net.floodlightcontroller.ui.web.StaticWebRoutable,\
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
+net.onrc.onos.registry.controller.ZookeeperRegistry
+net.floodlightcontroller.restserver.RestApiServer.port = 8080
+net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
+net.floodlightcontroller.core.FloodlightProvider.workerthreads = 48
+net.floodlightcontroller.forwarding.Forwarding.idletimeout = 5
+net.floodlightcontroller.forwarding.Forwarding.hardtimeout = 0
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = conf/titan-embedded.properties
+
diff --git a/conf/onos.properties b/conf/onos.properties
index 668da42..c1e2d27 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -6,13 +6,12 @@
net.floodlightcontroller.counter.CounterStore,\
net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.ui.web.StaticWebRoutable,\
-net.floodlightcontroller.onoslistener.OnosPublisher, \
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
net.onrc.onos.registry.controller.ZookeeperRegistry
net.floodlightcontroller.restserver.RestApiServer.port = 8080
net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
net.floodlightcontroller.core.FloodlightProvider.workerthreads = 16
-net.floodlightcontroller.jython.JythonDebugInterface.port = 6655
net.floodlightcontroller.forwarding.Forwarding.idletimeout = 5
net.floodlightcontroller.forwarding.Forwarding.hardtimeout = 0
-net.floodlightcontroller.onoslistener.OnosPublisher.dbconf = /tmp/cassandra.titan
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/cassandra.titan
diff --git a/conf/titan-embedded.properties b/conf/titan-embedded.properties
new file mode 100644
index 0000000..7a28afb
--- /dev/null
+++ b/conf/titan-embedded.properties
@@ -0,0 +1,6 @@
+storage.backend=embeddedcassandra
+storage.cassandra-config-dir=file:conf/cassandra.yaml
+storage.keyspace=onos
+storage.replication-factor=1
+storage.write-consistency-level=ALL
+storage.read-consistency-level=ONE
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java
deleted file mode 100644
index d1ef80b..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class Constants {
-
- public static final String VERSION = "0.1.0";
-
-}
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Message.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Message.java
deleted file mode 100644
index 8e4d989..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Message.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class Message implements org.apache.thrift.TBase<Message, Message._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Message");
-
- private static final org.apache.thrift.protocol.TField SESSION_IDS_FIELD_DESC = new org.apache.thrift.protocol.TField("sessionIDs", org.apache.thrift.protocol.TType.LIST, (short)1);
- private static final org.apache.thrift.protocol.TField PACKET_FIELD_DESC = new org.apache.thrift.protocol.TField("packet", org.apache.thrift.protocol.TType.STRUCT, (short)2);
-
- public List<String> sessionIDs; // required
- public Packet packet; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- SESSION_IDS((short)1, "sessionIDs"),
- PACKET((short)2, "packet");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 1: // SESSION_IDS
- return SESSION_IDS;
- case 2: // PACKET
- return PACKET;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.SESSION_IDS, new org.apache.thrift.meta_data.FieldMetaData("sessionIDs", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST,
- new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
- tmpMap.put(_Fields.PACKET, new org.apache.thrift.meta_data.FieldMetaData("packet", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Packet.class)));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Message.class, metaDataMap);
- }
-
- public Message() {
- }
-
- public Message(
- List<String> sessionIDs,
- Packet packet)
- {
- this();
- this.sessionIDs = sessionIDs;
- this.packet = packet;
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public Message(Message other) {
- if (other.isSetSessionIDs()) {
- List<String> __this__sessionIDs = new ArrayList<String>();
- for (String other_element : other.sessionIDs) {
- __this__sessionIDs.add(other_element);
- }
- this.sessionIDs = __this__sessionIDs;
- }
- if (other.isSetPacket()) {
- this.packet = new Packet(other.packet);
- }
- }
-
- public Message deepCopy() {
- return new Message(this);
- }
-
- @Override
- public void clear() {
- this.sessionIDs = null;
- this.packet = null;
- }
-
- public int getSessionIDsSize() {
- return (this.sessionIDs == null) ? 0 : this.sessionIDs.size();
- }
-
- public java.util.Iterator<String> getSessionIDsIterator() {
- return (this.sessionIDs == null) ? null : this.sessionIDs.iterator();
- }
-
- public void addToSessionIDs(String elem) {
- if (this.sessionIDs == null) {
- this.sessionIDs = new ArrayList<String>();
- }
- this.sessionIDs.add(elem);
- }
-
- public List<String> getSessionIDs() {
- return this.sessionIDs;
- }
-
- public Message setSessionIDs(List<String> sessionIDs) {
- this.sessionIDs = sessionIDs;
- return this;
- }
-
- public void unsetSessionIDs() {
- this.sessionIDs = null;
- }
-
- /** Returns true if field sessionIDs is set (has been assigned a value) and false otherwise */
- public boolean isSetSessionIDs() {
- return this.sessionIDs != null;
- }
-
- public void setSessionIDsIsSet(boolean value) {
- if (!value) {
- this.sessionIDs = null;
- }
- }
-
- public Packet getPacket() {
- return this.packet;
- }
-
- public Message setPacket(Packet packet) {
- this.packet = packet;
- return this;
- }
-
- public void unsetPacket() {
- this.packet = null;
- }
-
- /** Returns true if field packet is set (has been assigned a value) and false otherwise */
- public boolean isSetPacket() {
- return this.packet != null;
- }
-
- public void setPacketIsSet(boolean value) {
- if (!value) {
- this.packet = null;
- }
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case SESSION_IDS:
- if (value == null) {
- unsetSessionIDs();
- } else {
- setSessionIDs((List<String>)value);
- }
- break;
-
- case PACKET:
- if (value == null) {
- unsetPacket();
- } else {
- setPacket((Packet)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case SESSION_IDS:
- return getSessionIDs();
-
- case PACKET:
- return getPacket();
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case SESSION_IDS:
- return isSetSessionIDs();
- case PACKET:
- return isSetPacket();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof Message)
- return this.equals((Message)that);
- return false;
- }
-
- public boolean equals(Message that) {
- if (that == null)
- return false;
-
- boolean this_present_sessionIDs = true && this.isSetSessionIDs();
- boolean that_present_sessionIDs = true && that.isSetSessionIDs();
- if (this_present_sessionIDs || that_present_sessionIDs) {
- if (!(this_present_sessionIDs && that_present_sessionIDs))
- return false;
- if (!this.sessionIDs.equals(that.sessionIDs))
- return false;
- }
-
- boolean this_present_packet = true && this.isSetPacket();
- boolean that_present_packet = true && that.isSetPacket();
- if (this_present_packet || that_present_packet) {
- if (!(this_present_packet && that_present_packet))
- return false;
- if (!this.packet.equals(that.packet))
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(Message other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- Message typedOther = (Message)other;
-
- lastComparison = Boolean.valueOf(isSetSessionIDs()).compareTo(typedOther.isSetSessionIDs());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetSessionIDs()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sessionIDs, typedOther.sessionIDs);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- lastComparison = Boolean.valueOf(isSetPacket()).compareTo(typedOther.isSetPacket());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetPacket()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.packet, typedOther.packet);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 1: // SESSION_IDS
- if (field.type == org.apache.thrift.protocol.TType.LIST) {
- {
- org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
- this.sessionIDs = new ArrayList<String>(_list0.size);
- for (int _i1 = 0; _i1 < _list0.size; ++_i1)
- {
- String _elem2; // required
- _elem2 = iprot.readString();
- this.sessionIDs.add(_elem2);
- }
- iprot.readListEnd();
- }
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- case 2: // PACKET
- if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
- this.packet = new Packet();
- this.packet.read(iprot);
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- validate();
-
- oprot.writeStructBegin(STRUCT_DESC);
- if (this.sessionIDs != null) {
- oprot.writeFieldBegin(SESSION_IDS_FIELD_DESC);
- {
- oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, this.sessionIDs.size()));
- for (String _iter3 : this.sessionIDs)
- {
- oprot.writeString(_iter3);
- }
- oprot.writeListEnd();
- }
- oprot.writeFieldEnd();
- }
- if (this.packet != null) {
- oprot.writeFieldBegin(PACKET_FIELD_DESC);
- this.packet.write(oprot);
- oprot.writeFieldEnd();
- }
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("Message(");
- boolean first = true;
-
- sb.append("sessionIDs:");
- if (this.sessionIDs == null) {
- sb.append("null");
- } else {
- sb.append(this.sessionIDs);
- }
- first = false;
- if (!first) sb.append(", ");
- sb.append("packet:");
- if (this.packet == null) {
- sb.append("null");
- } else {
- sb.append(this.packet);
- }
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
-}
-
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/OFMessageType.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/OFMessageType.java
deleted file mode 100644
index b9b2843..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/OFMessageType.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
-
-/**
- * OFMessage type
- *
- */
-@SuppressWarnings("all") public enum OFMessageType implements org.apache.thrift.TEnum {
- HELLO(0),
- ERROR(1),
- ECHO_REQUEST(2),
- ECHO_REPLY(3),
- VENDOR(4),
- FEATURES_REQUEST(5),
- FEATURES_REPLY(6),
- GET_CONFIG_REQUEST(7),
- GET_CONFIG_REPLY(8),
- SET_CONFIG(9),
- PACKET_IN(10),
- FLOW_REMOVED(11),
- PORT_STATUS(12),
- PACKET_OUT(13),
- FLOW_MOD(14),
- PORT_MOD(15),
- STATS_REQUEST(16),
- STATS_REPLY(17),
- BARRIER_REQUEST(18),
- BARRIER_REPLY(19);
-
- private final int value;
-
- private OFMessageType(int value) {
- this.value = value;
- }
-
- /**
- * Get the integer value of this enum value, as defined in the Thrift IDL.
- */
- public int getValue() {
- return value;
- }
-
- /**
- * Find a the enum type by its integer value, as defined in the Thrift IDL.
- * @return null if the value is not found.
- */
- public static OFMessageType findByValue(int value) {
- switch (value) {
- case 0:
- return HELLO;
- case 1:
- return ERROR;
- case 2:
- return ECHO_REQUEST;
- case 3:
- return ECHO_REPLY;
- case 4:
- return VENDOR;
- case 5:
- return FEATURES_REQUEST;
- case 6:
- return FEATURES_REPLY;
- case 7:
- return GET_CONFIG_REQUEST;
- case 8:
- return GET_CONFIG_REPLY;
- case 9:
- return SET_CONFIG;
- case 10:
- return PACKET_IN;
- case 11:
- return FLOW_REMOVED;
- case 12:
- return PORT_STATUS;
- case 13:
- return PACKET_OUT;
- case 14:
- return FLOW_MOD;
- case 15:
- return PORT_MOD;
- case 16:
- return STATS_REQUEST;
- case 17:
- return STATS_REPLY;
- case 18:
- return BARRIER_REQUEST;
- case 19:
- return BARRIER_REPLY;
- default:
- return null;
- }
- }
-}
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Packet.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Packet.java
deleted file mode 100644
index 65c140f..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Packet.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class Packet implements org.apache.thrift.TBase<Packet, Packet._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Packet");
-
- private static final org.apache.thrift.protocol.TField MESSAGE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("messageType", org.apache.thrift.protocol.TType.I32, (short)1);
- private static final org.apache.thrift.protocol.TField SW_PORT_TUPLE_FIELD_DESC = new org.apache.thrift.protocol.TField("swPortTuple", org.apache.thrift.protocol.TType.STRUCT, (short)2);
- private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("data", org.apache.thrift.protocol.TType.STRING, (short)3);
-
- /**
- *
- * @see OFMessageType
- */
- public OFMessageType messageType; // required
- public SwitchPortTuple swPortTuple; // required
- public ByteBuffer data; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- /**
- *
- * @see OFMessageType
- */
- MESSAGE_TYPE((short)1, "messageType"),
- SW_PORT_TUPLE((short)2, "swPortTuple"),
- DATA((short)3, "data");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 1: // MESSAGE_TYPE
- return MESSAGE_TYPE;
- case 2: // SW_PORT_TUPLE
- return SW_PORT_TUPLE;
- case 3: // DATA
- return DATA;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.MESSAGE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("messageType", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, OFMessageType.class)));
- tmpMap.put(_Fields.SW_PORT_TUPLE, new org.apache.thrift.meta_data.FieldMetaData("swPortTuple", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SwitchPortTuple.class)));
- tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true)));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Packet.class, metaDataMap);
- }
-
- public Packet() {
- }
-
- public Packet(
- OFMessageType messageType,
- SwitchPortTuple swPortTuple,
- ByteBuffer data)
- {
- this();
- this.messageType = messageType;
- this.swPortTuple = swPortTuple;
- this.data = data;
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public Packet(Packet other) {
- if (other.isSetMessageType()) {
- this.messageType = other.messageType;
- }
- if (other.isSetSwPortTuple()) {
- this.swPortTuple = new SwitchPortTuple(other.swPortTuple);
- }
- if (other.isSetData()) {
- this.data = org.apache.thrift.TBaseHelper.copyBinary(other.data);
-;
- }
- }
-
- public Packet deepCopy() {
- return new Packet(this);
- }
-
- @Override
- public void clear() {
- this.messageType = null;
- this.swPortTuple = null;
- this.data = null;
- }
-
- /**
- *
- * @see OFMessageType
- */
- public OFMessageType getMessageType() {
- return this.messageType;
- }
-
- /**
- *
- * @see OFMessageType
- */
- public Packet setMessageType(OFMessageType messageType) {
- this.messageType = messageType;
- return this;
- }
-
- public void unsetMessageType() {
- this.messageType = null;
- }
-
- /** Returns true if field messageType is set (has been assigned a value) and false otherwise */
- public boolean isSetMessageType() {
- return this.messageType != null;
- }
-
- public void setMessageTypeIsSet(boolean value) {
- if (!value) {
- this.messageType = null;
- }
- }
-
- public SwitchPortTuple getSwPortTuple() {
- return this.swPortTuple;
- }
-
- public Packet setSwPortTuple(SwitchPortTuple swPortTuple) {
- this.swPortTuple = swPortTuple;
- return this;
- }
-
- public void unsetSwPortTuple() {
- this.swPortTuple = null;
- }
-
- /** Returns true if field swPortTuple is set (has been assigned a value) and false otherwise */
- public boolean isSetSwPortTuple() {
- return this.swPortTuple != null;
- }
-
- public void setSwPortTupleIsSet(boolean value) {
- if (!value) {
- this.swPortTuple = null;
- }
- }
-
- public byte[] getData() {
- setData(org.apache.thrift.TBaseHelper.rightSize(data));
- return data == null ? null : data.array();
- }
-
- public ByteBuffer bufferForData() {
- return data;
- }
-
- public Packet setData(byte[] data) {
- setData(data == null ? (ByteBuffer)null : ByteBuffer.wrap(data));
- return this;
- }
-
- public Packet setData(ByteBuffer data) {
- this.data = data;
- return this;
- }
-
- public void unsetData() {
- this.data = null;
- }
-
- /** Returns true if field data is set (has been assigned a value) and false otherwise */
- public boolean isSetData() {
- return this.data != null;
- }
-
- public void setDataIsSet(boolean value) {
- if (!value) {
- this.data = null;
- }
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case MESSAGE_TYPE:
- if (value == null) {
- unsetMessageType();
- } else {
- setMessageType((OFMessageType)value);
- }
- break;
-
- case SW_PORT_TUPLE:
- if (value == null) {
- unsetSwPortTuple();
- } else {
- setSwPortTuple((SwitchPortTuple)value);
- }
- break;
-
- case DATA:
- if (value == null) {
- unsetData();
- } else {
- setData((ByteBuffer)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case MESSAGE_TYPE:
- return getMessageType();
-
- case SW_PORT_TUPLE:
- return getSwPortTuple();
-
- case DATA:
- return getData();
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case MESSAGE_TYPE:
- return isSetMessageType();
- case SW_PORT_TUPLE:
- return isSetSwPortTuple();
- case DATA:
- return isSetData();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof Packet)
- return this.equals((Packet)that);
- return false;
- }
-
- public boolean equals(Packet that) {
- if (that == null)
- return false;
-
- boolean this_present_messageType = true && this.isSetMessageType();
- boolean that_present_messageType = true && that.isSetMessageType();
- if (this_present_messageType || that_present_messageType) {
- if (!(this_present_messageType && that_present_messageType))
- return false;
- if (!this.messageType.equals(that.messageType))
- return false;
- }
-
- boolean this_present_swPortTuple = true && this.isSetSwPortTuple();
- boolean that_present_swPortTuple = true && that.isSetSwPortTuple();
- if (this_present_swPortTuple || that_present_swPortTuple) {
- if (!(this_present_swPortTuple && that_present_swPortTuple))
- return false;
- if (!this.swPortTuple.equals(that.swPortTuple))
- return false;
- }
-
- boolean this_present_data = true && this.isSetData();
- boolean that_present_data = true && that.isSetData();
- if (this_present_data || that_present_data) {
- if (!(this_present_data && that_present_data))
- return false;
- if (!this.data.equals(that.data))
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(Packet other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- Packet typedOther = (Packet)other;
-
- lastComparison = Boolean.valueOf(isSetMessageType()).compareTo(typedOther.isSetMessageType());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetMessageType()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.messageType, typedOther.messageType);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- lastComparison = Boolean.valueOf(isSetSwPortTuple()).compareTo(typedOther.isSetSwPortTuple());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetSwPortTuple()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.swPortTuple, typedOther.swPortTuple);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- lastComparison = Boolean.valueOf(isSetData()).compareTo(typedOther.isSetData());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetData()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, typedOther.data);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 1: // MESSAGE_TYPE
- if (field.type == org.apache.thrift.protocol.TType.I32) {
- this.messageType = OFMessageType.findByValue(iprot.readI32());
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- case 2: // SW_PORT_TUPLE
- if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
- this.swPortTuple = new SwitchPortTuple();
- this.swPortTuple.read(iprot);
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- case 3: // DATA
- if (field.type == org.apache.thrift.protocol.TType.STRING) {
- this.data = iprot.readBinary();
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- validate();
-
- oprot.writeStructBegin(STRUCT_DESC);
- if (this.messageType != null) {
- oprot.writeFieldBegin(MESSAGE_TYPE_FIELD_DESC);
- oprot.writeI32(this.messageType.getValue());
- oprot.writeFieldEnd();
- }
- if (this.swPortTuple != null) {
- oprot.writeFieldBegin(SW_PORT_TUPLE_FIELD_DESC);
- this.swPortTuple.write(oprot);
- oprot.writeFieldEnd();
- }
- if (this.data != null) {
- oprot.writeFieldBegin(DATA_FIELD_DESC);
- oprot.writeBinary(this.data);
- oprot.writeFieldEnd();
- }
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("Packet(");
- boolean first = true;
-
- sb.append("messageType:");
- if (this.messageType == null) {
- sb.append("null");
- } else {
- sb.append(this.messageType);
- }
- first = false;
- if (!first) sb.append(", ");
- sb.append("swPortTuple:");
- if (this.swPortTuple == null) {
- sb.append("null");
- } else {
- sb.append(this.swPortTuple);
- }
- first = false;
- if (!first) sb.append(", ");
- sb.append("data:");
- if (this.data == null) {
- sb.append("null");
- } else {
- org.apache.thrift.TBaseHelper.toString(this.data, sb);
- }
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
-}
-
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java
deleted file mode 100644
index f4e8ae5..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java
+++ /dev/null
@@ -1,2427 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class PacketStreamer {
-
- /**
- * Packetstreamer API
- */
- public interface Iface {
-
- /**
- * Synchronous method to get packets for a given sessionid
- *
- * @param sessionid
- */
- public List<ByteBuffer> getPackets(String sessionid) throws org.apache.thrift.TException;
-
- /**
- * Synchronous method to publish a packet.
- * It ensure the order that the packets are pushed
- *
- * @param packet
- */
- public int pushMessageSync(Message packet) throws org.apache.thrift.TException;
-
- /**
- * Asynchronous method to publish a packet.
- * Order is not guaranteed.
- *
- * @param packet
- */
- public void pushMessageAsync(Message packet) throws org.apache.thrift.TException;
-
- /**
- * Terminate a session
- *
- * @param sessionid
- */
- public void terminateSession(String sessionid) throws org.apache.thrift.TException;
-
- }
-
- public interface AsyncIface {
-
- public void getPackets(String sessionid, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.getPackets_call> resultHandler) throws org.apache.thrift.TException;
-
- public void pushMessageSync(Message packet, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.pushMessageSync_call> resultHandler) throws org.apache.thrift.TException;
-
- public void pushMessageAsync(Message packet, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.pushMessageAsync_call> resultHandler) throws org.apache.thrift.TException;
-
- public void terminateSession(String sessionid, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.terminateSession_call> resultHandler) throws org.apache.thrift.TException;
-
- }
-
- public static class Client extends org.apache.thrift.TServiceClient implements Iface {
- public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
- public Factory() {}
- public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
- return new Client(prot);
- }
- public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
- return new Client(iprot, oprot);
- }
- }
-
- public Client(org.apache.thrift.protocol.TProtocol prot)
- {
- super(prot, prot);
- }
-
- public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
- super(iprot, oprot);
- }
-
- public List<ByteBuffer> getPackets(String sessionid) throws org.apache.thrift.TException
- {
- send_getPackets(sessionid);
- return recv_getPackets();
- }
-
- public void send_getPackets(String sessionid) throws org.apache.thrift.TException
- {
- getPackets_args args = new getPackets_args();
- args.setSessionid(sessionid);
- sendBase("getPackets", args);
- }
-
- public List<ByteBuffer> recv_getPackets() throws org.apache.thrift.TException
- {
- getPackets_result result = new getPackets_result();
- receiveBase(result, "getPackets");
- if (result.isSetSuccess()) {
- return result.success;
- }
- throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getPackets failed: unknown result");
- }
-
- public int pushMessageSync(Message packet) throws org.apache.thrift.TException
- {
- send_pushMessageSync(packet);
- return recv_pushMessageSync();
- }
-
- public void send_pushMessageSync(Message packet) throws org.apache.thrift.TException
- {
- pushMessageSync_args args = new pushMessageSync_args();
- args.setPacket(packet);
- sendBase("pushMessageSync", args);
- }
-
- public int recv_pushMessageSync() throws org.apache.thrift.TException
- {
- pushMessageSync_result result = new pushMessageSync_result();
- receiveBase(result, "pushMessageSync");
- if (result.isSetSuccess()) {
- return result.success;
- }
- throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pushMessageSync failed: unknown result");
- }
-
- public void pushMessageAsync(Message packet) throws org.apache.thrift.TException
- {
- send_pushMessageAsync(packet);
- }
-
- public void send_pushMessageAsync(Message packet) throws org.apache.thrift.TException
- {
- pushMessageAsync_args args = new pushMessageAsync_args();
- args.setPacket(packet);
- sendBase("pushMessageAsync", args);
- }
-
- public void terminateSession(String sessionid) throws org.apache.thrift.TException
- {
- send_terminateSession(sessionid);
- recv_terminateSession();
- }
-
- public void send_terminateSession(String sessionid) throws org.apache.thrift.TException
- {
- terminateSession_args args = new terminateSession_args();
- args.setSessionid(sessionid);
- sendBase("terminateSession", args);
- }
-
- public void recv_terminateSession() throws org.apache.thrift.TException
- {
- terminateSession_result result = new terminateSession_result();
- receiveBase(result, "terminateSession");
- return;
- }
-
- }
- public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
- public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
- private org.apache.thrift.async.TAsyncClientManager clientManager;
- private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
- public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
- this.clientManager = clientManager;
- this.protocolFactory = protocolFactory;
- }
- public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
- return new AsyncClient(protocolFactory, clientManager, transport);
- }
- }
-
- public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
- super(protocolFactory, clientManager, transport);
- }
-
- public void getPackets(String sessionid, org.apache.thrift.async.AsyncMethodCallback<getPackets_call> resultHandler) throws org.apache.thrift.TException {
- checkReady();
- getPackets_call method_call = new getPackets_call(sessionid, resultHandler, this, ___protocolFactory, ___transport);
- this.___currentMethod = method_call;
- ___manager.call(method_call);
- }
-
- public static class getPackets_call extends org.apache.thrift.async.TAsyncMethodCall {
- private String sessionid;
- public getPackets_call(String sessionid, org.apache.thrift.async.AsyncMethodCallback<getPackets_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
- super(client, protocolFactory, transport, resultHandler, false);
- this.sessionid = sessionid;
- }
-
- public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
- prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getPackets", org.apache.thrift.protocol.TMessageType.CALL, 0));
- getPackets_args args = new getPackets_args();
- args.setSessionid(sessionid);
- args.write(prot);
- prot.writeMessageEnd();
- }
-
- public List<ByteBuffer> getResult() throws org.apache.thrift.TException {
- if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
- throw new IllegalStateException("Method call not finished!");
- }
- org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
- org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
- return (new Client(prot)).recv_getPackets();
- }
- }
-
- public void pushMessageSync(Message packet, org.apache.thrift.async.AsyncMethodCallback<pushMessageSync_call> resultHandler) throws org.apache.thrift.TException {
- checkReady();
- pushMessageSync_call method_call = new pushMessageSync_call(packet, resultHandler, this, ___protocolFactory, ___transport);
- this.___currentMethod = method_call;
- ___manager.call(method_call);
- }
-
- public static class pushMessageSync_call extends org.apache.thrift.async.TAsyncMethodCall {
- private Message packet;
- public pushMessageSync_call(Message packet, org.apache.thrift.async.AsyncMethodCallback<pushMessageSync_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
- super(client, protocolFactory, transport, resultHandler, false);
- this.packet = packet;
- }
-
- public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
- prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pushMessageSync", org.apache.thrift.protocol.TMessageType.CALL, 0));
- pushMessageSync_args args = new pushMessageSync_args();
- args.setPacket(packet);
- args.write(prot);
- prot.writeMessageEnd();
- }
-
- public int getResult() throws org.apache.thrift.TException {
- if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
- throw new IllegalStateException("Method call not finished!");
- }
- org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
- org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
- return (new Client(prot)).recv_pushMessageSync();
- }
- }
-
- public void pushMessageAsync(Message packet, org.apache.thrift.async.AsyncMethodCallback<pushMessageAsync_call> resultHandler) throws org.apache.thrift.TException {
- checkReady();
- pushMessageAsync_call method_call = new pushMessageAsync_call(packet, resultHandler, this, ___protocolFactory, ___transport);
- this.___currentMethod = method_call;
- ___manager.call(method_call);
- }
-
- public static class pushMessageAsync_call extends org.apache.thrift.async.TAsyncMethodCall {
- private Message packet;
- public pushMessageAsync_call(Message packet, org.apache.thrift.async.AsyncMethodCallback<pushMessageAsync_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
- super(client, protocolFactory, transport, resultHandler, true);
- this.packet = packet;
- }
-
- public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
- prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pushMessageAsync", org.apache.thrift.protocol.TMessageType.CALL, 0));
- pushMessageAsync_args args = new pushMessageAsync_args();
- args.setPacket(packet);
- args.write(prot);
- prot.writeMessageEnd();
- }
-
- public void getResult() throws org.apache.thrift.TException {
- if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
- throw new IllegalStateException("Method call not finished!");
- }
- org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
- org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
- }
- }
-
- public void terminateSession(String sessionid, org.apache.thrift.async.AsyncMethodCallback<terminateSession_call> resultHandler) throws org.apache.thrift.TException {
- checkReady();
- terminateSession_call method_call = new terminateSession_call(sessionid, resultHandler, this, ___protocolFactory, ___transport);
- this.___currentMethod = method_call;
- ___manager.call(method_call);
- }
-
- public static class terminateSession_call extends org.apache.thrift.async.TAsyncMethodCall {
- private String sessionid;
- public terminateSession_call(String sessionid, org.apache.thrift.async.AsyncMethodCallback<terminateSession_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
- super(client, protocolFactory, transport, resultHandler, false);
- this.sessionid = sessionid;
- }
-
- public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
- prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("terminateSession", org.apache.thrift.protocol.TMessageType.CALL, 0));
- terminateSession_args args = new terminateSession_args();
- args.setSessionid(sessionid);
- args.write(prot);
- prot.writeMessageEnd();
- }
-
- public void getResult() throws org.apache.thrift.TException {
- if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
- throw new IllegalStateException("Method call not finished!");
- }
- org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
- org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
- (new Client(prot)).recv_terminateSession();
- }
- }
-
- }
-
- public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor implements org.apache.thrift.TProcessor {
- private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
- public Processor(I iface) {
- super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
- }
-
- protected Processor(I iface, Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
- super(iface, getProcessMap(processMap));
- }
-
- private static <I extends Iface> Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
- processMap.put("getPackets", new getPackets());
- processMap.put("pushMessageSync", new pushMessageSync());
- processMap.put("pushMessageAsync", new pushMessageAsync());
- processMap.put("terminateSession", new terminateSession());
- return processMap;
- }
-
- private static class getPackets<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getPackets_args> {
- public getPackets() {
- super("getPackets");
- }
-
- protected getPackets_args getEmptyArgsInstance() {
- return new getPackets_args();
- }
-
- protected getPackets_result getResult(I iface, getPackets_args args) throws org.apache.thrift.TException {
- getPackets_result result = new getPackets_result();
- result.success = iface.getPackets(args.sessionid);
- return result;
- }
- }
-
- private static class pushMessageSync<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pushMessageSync_args> {
- public pushMessageSync() {
- super("pushMessageSync");
- }
-
- protected pushMessageSync_args getEmptyArgsInstance() {
- return new pushMessageSync_args();
- }
-
- protected pushMessageSync_result getResult(I iface, pushMessageSync_args args) throws org.apache.thrift.TException {
- pushMessageSync_result result = new pushMessageSync_result();
- result.success = iface.pushMessageSync(args.packet);
- result.setSuccessIsSet(true);
- return result;
- }
- }
-
- private static class pushMessageAsync<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pushMessageAsync_args> {
- public pushMessageAsync() {
- super("pushMessageAsync");
- }
-
- protected pushMessageAsync_args getEmptyArgsInstance() {
- return new pushMessageAsync_args();
- }
-
- protected org.apache.thrift.TBase getResult(I iface, pushMessageAsync_args args) throws org.apache.thrift.TException {
- iface.pushMessageAsync(args.packet);
- return null;
- }
- }
-
- private static class terminateSession<I extends Iface> extends org.apache.thrift.ProcessFunction<I, terminateSession_args> {
- public terminateSession() {
- super("terminateSession");
- }
-
- protected terminateSession_args getEmptyArgsInstance() {
- return new terminateSession_args();
- }
-
- protected terminateSession_result getResult(I iface, terminateSession_args args) throws org.apache.thrift.TException {
- terminateSession_result result = new terminateSession_result();
- iface.terminateSession(args.sessionid);
- return result;
- }
- }
-
- }
-
- public static class getPackets_args implements org.apache.thrift.TBase<getPackets_args, getPackets_args._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getPackets_args");
-
- private static final org.apache.thrift.protocol.TField SESSIONID_FIELD_DESC = new org.apache.thrift.protocol.TField("sessionid", org.apache.thrift.protocol.TType.STRING, (short)1);
-
- public String sessionid; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- SESSIONID((short)1, "sessionid");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 1: // SESSIONID
- return SESSIONID;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.SESSIONID, new org.apache.thrift.meta_data.FieldMetaData("sessionid", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getPackets_args.class, metaDataMap);
- }
-
- public getPackets_args() {
- }
-
- public getPackets_args(
- String sessionid)
- {
- this();
- this.sessionid = sessionid;
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public getPackets_args(getPackets_args other) {
- if (other.isSetSessionid()) {
- this.sessionid = other.sessionid;
- }
- }
-
- public getPackets_args deepCopy() {
- return new getPackets_args(this);
- }
-
- @Override
- public void clear() {
- this.sessionid = null;
- }
-
- public String getSessionid() {
- return this.sessionid;
- }
-
- public getPackets_args setSessionid(String sessionid) {
- this.sessionid = sessionid;
- return this;
- }
-
- public void unsetSessionid() {
- this.sessionid = null;
- }
-
- /** Returns true if field sessionid is set (has been assigned a value) and false otherwise */
- public boolean isSetSessionid() {
- return this.sessionid != null;
- }
-
- public void setSessionidIsSet(boolean value) {
- if (!value) {
- this.sessionid = null;
- }
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case SESSIONID:
- if (value == null) {
- unsetSessionid();
- } else {
- setSessionid((String)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case SESSIONID:
- return getSessionid();
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case SESSIONID:
- return isSetSessionid();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof getPackets_args)
- return this.equals((getPackets_args)that);
- return false;
- }
-
- public boolean equals(getPackets_args that) {
- if (that == null)
- return false;
-
- boolean this_present_sessionid = true && this.isSetSessionid();
- boolean that_present_sessionid = true && that.isSetSessionid();
- if (this_present_sessionid || that_present_sessionid) {
- if (!(this_present_sessionid && that_present_sessionid))
- return false;
- if (!this.sessionid.equals(that.sessionid))
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(getPackets_args other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- getPackets_args typedOther = (getPackets_args)other;
-
- lastComparison = Boolean.valueOf(isSetSessionid()).compareTo(typedOther.isSetSessionid());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetSessionid()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sessionid, typedOther.sessionid);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 1: // SESSIONID
- if (field.type == org.apache.thrift.protocol.TType.STRING) {
- this.sessionid = iprot.readString();
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- validate();
-
- oprot.writeStructBegin(STRUCT_DESC);
- if (this.sessionid != null) {
- oprot.writeFieldBegin(SESSIONID_FIELD_DESC);
- oprot.writeString(this.sessionid);
- oprot.writeFieldEnd();
- }
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("getPackets_args(");
- boolean first = true;
-
- sb.append("sessionid:");
- if (this.sessionid == null) {
- sb.append("null");
- } else {
- sb.append(this.sessionid);
- }
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- }
-
- public static class getPackets_result implements org.apache.thrift.TBase<getPackets_result, getPackets_result._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getPackets_result");
-
- private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
-
- public List<ByteBuffer> success; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- SUCCESS((short)0, "success");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 0: // SUCCESS
- return SUCCESS;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST,
- new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getPackets_result.class, metaDataMap);
- }
-
- public getPackets_result() {
- }
-
- public getPackets_result(
- List<ByteBuffer> success)
- {
- this();
- this.success = success;
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public getPackets_result(getPackets_result other) {
- if (other.isSetSuccess()) {
- List<ByteBuffer> __this__success = new ArrayList<ByteBuffer>();
- for (ByteBuffer other_element : other.success) {
- ByteBuffer temp_binary_element = org.apache.thrift.TBaseHelper.copyBinary(other_element);
-;
- __this__success.add(temp_binary_element);
- }
- this.success = __this__success;
- }
- }
-
- public getPackets_result deepCopy() {
- return new getPackets_result(this);
- }
-
- @Override
- public void clear() {
- this.success = null;
- }
-
- public int getSuccessSize() {
- return (this.success == null) ? 0 : this.success.size();
- }
-
- public java.util.Iterator<ByteBuffer> getSuccessIterator() {
- return (this.success == null) ? null : this.success.iterator();
- }
-
- public void addToSuccess(ByteBuffer elem) {
- if (this.success == null) {
- this.success = new ArrayList<ByteBuffer>();
- }
- this.success.add(elem);
- }
-
- public List<ByteBuffer> getSuccess() {
- return this.success;
- }
-
- public getPackets_result setSuccess(List<ByteBuffer> success) {
- this.success = success;
- return this;
- }
-
- public void unsetSuccess() {
- this.success = null;
- }
-
- /** Returns true if field success is set (has been assigned a value) and false otherwise */
- public boolean isSetSuccess() {
- return this.success != null;
- }
-
- public void setSuccessIsSet(boolean value) {
- if (!value) {
- this.success = null;
- }
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case SUCCESS:
- if (value == null) {
- unsetSuccess();
- } else {
- setSuccess((List<ByteBuffer>)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case SUCCESS:
- return getSuccess();
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case SUCCESS:
- return isSetSuccess();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof getPackets_result)
- return this.equals((getPackets_result)that);
- return false;
- }
-
- public boolean equals(getPackets_result that) {
- if (that == null)
- return false;
-
- boolean this_present_success = true && this.isSetSuccess();
- boolean that_present_success = true && that.isSetSuccess();
- if (this_present_success || that_present_success) {
- if (!(this_present_success && that_present_success))
- return false;
- if (!this.success.equals(that.success))
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(getPackets_result other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- getPackets_result typedOther = (getPackets_result)other;
-
- lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetSuccess()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 0: // SUCCESS
- if (field.type == org.apache.thrift.protocol.TType.LIST) {
- {
- org.apache.thrift.protocol.TList _list4 = iprot.readListBegin();
- this.success = new ArrayList<ByteBuffer>(_list4.size);
- for (int _i5 = 0; _i5 < _list4.size; ++_i5)
- {
- ByteBuffer _elem6; // required
- _elem6 = iprot.readBinary();
- this.success.add(_elem6);
- }
- iprot.readListEnd();
- }
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- oprot.writeStructBegin(STRUCT_DESC);
-
- if (this.isSetSuccess()) {
- oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
- {
- oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, this.success.size()));
- for (ByteBuffer _iter7 : this.success)
- {
- oprot.writeBinary(_iter7);
- }
- oprot.writeListEnd();
- }
- oprot.writeFieldEnd();
- }
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("getPackets_result(");
- boolean first = true;
-
- sb.append("success:");
- if (this.success == null) {
- sb.append("null");
- } else {
- sb.append(this.success);
- }
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- }
-
- public static class pushMessageSync_args implements org.apache.thrift.TBase<pushMessageSync_args, pushMessageSync_args._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pushMessageSync_args");
-
- private static final org.apache.thrift.protocol.TField PACKET_FIELD_DESC = new org.apache.thrift.protocol.TField("packet", org.apache.thrift.protocol.TType.STRUCT, (short)1);
-
- public Message packet; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- PACKET((short)1, "packet");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 1: // PACKET
- return PACKET;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.PACKET, new org.apache.thrift.meta_data.FieldMetaData("packet", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Message.class)));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pushMessageSync_args.class, metaDataMap);
- }
-
- public pushMessageSync_args() {
- }
-
- public pushMessageSync_args(
- Message packet)
- {
- this();
- this.packet = packet;
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public pushMessageSync_args(pushMessageSync_args other) {
- if (other.isSetPacket()) {
- this.packet = new Message(other.packet);
- }
- }
-
- public pushMessageSync_args deepCopy() {
- return new pushMessageSync_args(this);
- }
-
- @Override
- public void clear() {
- this.packet = null;
- }
-
- public Message getPacket() {
- return this.packet;
- }
-
- public pushMessageSync_args setPacket(Message packet) {
- this.packet = packet;
- return this;
- }
-
- public void unsetPacket() {
- this.packet = null;
- }
-
- /** Returns true if field packet is set (has been assigned a value) and false otherwise */
- public boolean isSetPacket() {
- return this.packet != null;
- }
-
- public void setPacketIsSet(boolean value) {
- if (!value) {
- this.packet = null;
- }
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case PACKET:
- if (value == null) {
- unsetPacket();
- } else {
- setPacket((Message)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case PACKET:
- return getPacket();
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case PACKET:
- return isSetPacket();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof pushMessageSync_args)
- return this.equals((pushMessageSync_args)that);
- return false;
- }
-
- public boolean equals(pushMessageSync_args that) {
- if (that == null)
- return false;
-
- boolean this_present_packet = true && this.isSetPacket();
- boolean that_present_packet = true && that.isSetPacket();
- if (this_present_packet || that_present_packet) {
- if (!(this_present_packet && that_present_packet))
- return false;
- if (!this.packet.equals(that.packet))
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(pushMessageSync_args other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- pushMessageSync_args typedOther = (pushMessageSync_args)other;
-
- lastComparison = Boolean.valueOf(isSetPacket()).compareTo(typedOther.isSetPacket());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetPacket()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.packet, typedOther.packet);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 1: // PACKET
- if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
- this.packet = new Message();
- this.packet.read(iprot);
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- validate();
-
- oprot.writeStructBegin(STRUCT_DESC);
- if (this.packet != null) {
- oprot.writeFieldBegin(PACKET_FIELD_DESC);
- this.packet.write(oprot);
- oprot.writeFieldEnd();
- }
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("pushMessageSync_args(");
- boolean first = true;
-
- sb.append("packet:");
- if (this.packet == null) {
- sb.append("null");
- } else {
- sb.append(this.packet);
- }
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- }
-
- public static class pushMessageSync_result implements org.apache.thrift.TBase<pushMessageSync_result, pushMessageSync_result._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pushMessageSync_result");
-
- private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.I32, (short)0);
-
- public int success; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- SUCCESS((short)0, "success");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 0: // SUCCESS
- return SUCCESS;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
- private static final int __SUCCESS_ISSET_ID = 0;
- private BitSet __isset_bit_vector = new BitSet(1);
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pushMessageSync_result.class, metaDataMap);
- }
-
- public pushMessageSync_result() {
- }
-
- public pushMessageSync_result(
- int success)
- {
- this();
- this.success = success;
- setSuccessIsSet(true);
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public pushMessageSync_result(pushMessageSync_result other) {
- __isset_bit_vector.clear();
- __isset_bit_vector.or(other.__isset_bit_vector);
- this.success = other.success;
- }
-
- public pushMessageSync_result deepCopy() {
- return new pushMessageSync_result(this);
- }
-
- @Override
- public void clear() {
- setSuccessIsSet(false);
- this.success = 0;
- }
-
- public int getSuccess() {
- return this.success;
- }
-
- public pushMessageSync_result setSuccess(int success) {
- this.success = success;
- setSuccessIsSet(true);
- return this;
- }
-
- public void unsetSuccess() {
- __isset_bit_vector.clear(__SUCCESS_ISSET_ID);
- }
-
- /** Returns true if field success is set (has been assigned a value) and false otherwise */
- public boolean isSetSuccess() {
- return __isset_bit_vector.get(__SUCCESS_ISSET_ID);
- }
-
- public void setSuccessIsSet(boolean value) {
- __isset_bit_vector.set(__SUCCESS_ISSET_ID, value);
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case SUCCESS:
- if (value == null) {
- unsetSuccess();
- } else {
- setSuccess((Integer)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case SUCCESS:
- return Integer.valueOf(getSuccess());
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case SUCCESS:
- return isSetSuccess();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof pushMessageSync_result)
- return this.equals((pushMessageSync_result)that);
- return false;
- }
-
- public boolean equals(pushMessageSync_result that) {
- if (that == null)
- return false;
-
- boolean this_present_success = true;
- boolean that_present_success = true;
- if (this_present_success || that_present_success) {
- if (!(this_present_success && that_present_success))
- return false;
- if (this.success != that.success)
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(pushMessageSync_result other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- pushMessageSync_result typedOther = (pushMessageSync_result)other;
-
- lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetSuccess()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 0: // SUCCESS
- if (field.type == org.apache.thrift.protocol.TType.I32) {
- this.success = iprot.readI32();
- setSuccessIsSet(true);
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- oprot.writeStructBegin(STRUCT_DESC);
-
- if (this.isSetSuccess()) {
- oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
- oprot.writeI32(this.success);
- oprot.writeFieldEnd();
- }
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("pushMessageSync_result(");
- boolean first = true;
-
- sb.append("success:");
- sb.append(this.success);
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
- __isset_bit_vector = new BitSet(1);
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- }
-
- public static class pushMessageAsync_args implements org.apache.thrift.TBase<pushMessageAsync_args, pushMessageAsync_args._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pushMessageAsync_args");
-
- private static final org.apache.thrift.protocol.TField PACKET_FIELD_DESC = new org.apache.thrift.protocol.TField("packet", org.apache.thrift.protocol.TType.STRUCT, (short)1);
-
- public Message packet; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- PACKET((short)1, "packet");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 1: // PACKET
- return PACKET;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.PACKET, new org.apache.thrift.meta_data.FieldMetaData("packet", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Message.class)));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pushMessageAsync_args.class, metaDataMap);
- }
-
- public pushMessageAsync_args() {
- }
-
- public pushMessageAsync_args(
- Message packet)
- {
- this();
- this.packet = packet;
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public pushMessageAsync_args(pushMessageAsync_args other) {
- if (other.isSetPacket()) {
- this.packet = new Message(other.packet);
- }
- }
-
- public pushMessageAsync_args deepCopy() {
- return new pushMessageAsync_args(this);
- }
-
- @Override
- public void clear() {
- this.packet = null;
- }
-
- public Message getPacket() {
- return this.packet;
- }
-
- public pushMessageAsync_args setPacket(Message packet) {
- this.packet = packet;
- return this;
- }
-
- public void unsetPacket() {
- this.packet = null;
- }
-
- /** Returns true if field packet is set (has been assigned a value) and false otherwise */
- public boolean isSetPacket() {
- return this.packet != null;
- }
-
- public void setPacketIsSet(boolean value) {
- if (!value) {
- this.packet = null;
- }
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case PACKET:
- if (value == null) {
- unsetPacket();
- } else {
- setPacket((Message)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case PACKET:
- return getPacket();
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case PACKET:
- return isSetPacket();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof pushMessageAsync_args)
- return this.equals((pushMessageAsync_args)that);
- return false;
- }
-
- public boolean equals(pushMessageAsync_args that) {
- if (that == null)
- return false;
-
- boolean this_present_packet = true && this.isSetPacket();
- boolean that_present_packet = true && that.isSetPacket();
- if (this_present_packet || that_present_packet) {
- if (!(this_present_packet && that_present_packet))
- return false;
- if (!this.packet.equals(that.packet))
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(pushMessageAsync_args other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- pushMessageAsync_args typedOther = (pushMessageAsync_args)other;
-
- lastComparison = Boolean.valueOf(isSetPacket()).compareTo(typedOther.isSetPacket());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetPacket()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.packet, typedOther.packet);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 1: // PACKET
- if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
- this.packet = new Message();
- this.packet.read(iprot);
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- validate();
-
- oprot.writeStructBegin(STRUCT_DESC);
- if (this.packet != null) {
- oprot.writeFieldBegin(PACKET_FIELD_DESC);
- this.packet.write(oprot);
- oprot.writeFieldEnd();
- }
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("pushMessageAsync_args(");
- boolean first = true;
-
- sb.append("packet:");
- if (this.packet == null) {
- sb.append("null");
- } else {
- sb.append(this.packet);
- }
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- }
-
- public static class terminateSession_args implements org.apache.thrift.TBase<terminateSession_args, terminateSession_args._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("terminateSession_args");
-
- private static final org.apache.thrift.protocol.TField SESSIONID_FIELD_DESC = new org.apache.thrift.protocol.TField("sessionid", org.apache.thrift.protocol.TType.STRING, (short)1);
-
- public String sessionid; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- SESSIONID((short)1, "sessionid");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 1: // SESSIONID
- return SESSIONID;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.SESSIONID, new org.apache.thrift.meta_data.FieldMetaData("sessionid", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(terminateSession_args.class, metaDataMap);
- }
-
- public terminateSession_args() {
- }
-
- public terminateSession_args(
- String sessionid)
- {
- this();
- this.sessionid = sessionid;
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public terminateSession_args(terminateSession_args other) {
- if (other.isSetSessionid()) {
- this.sessionid = other.sessionid;
- }
- }
-
- public terminateSession_args deepCopy() {
- return new terminateSession_args(this);
- }
-
- @Override
- public void clear() {
- this.sessionid = null;
- }
-
- public String getSessionid() {
- return this.sessionid;
- }
-
- public terminateSession_args setSessionid(String sessionid) {
- this.sessionid = sessionid;
- return this;
- }
-
- public void unsetSessionid() {
- this.sessionid = null;
- }
-
- /** Returns true if field sessionid is set (has been assigned a value) and false otherwise */
- public boolean isSetSessionid() {
- return this.sessionid != null;
- }
-
- public void setSessionidIsSet(boolean value) {
- if (!value) {
- this.sessionid = null;
- }
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case SESSIONID:
- if (value == null) {
- unsetSessionid();
- } else {
- setSessionid((String)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case SESSIONID:
- return getSessionid();
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case SESSIONID:
- return isSetSessionid();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof terminateSession_args)
- return this.equals((terminateSession_args)that);
- return false;
- }
-
- public boolean equals(terminateSession_args that) {
- if (that == null)
- return false;
-
- boolean this_present_sessionid = true && this.isSetSessionid();
- boolean that_present_sessionid = true && that.isSetSessionid();
- if (this_present_sessionid || that_present_sessionid) {
- if (!(this_present_sessionid && that_present_sessionid))
- return false;
- if (!this.sessionid.equals(that.sessionid))
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(terminateSession_args other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- terminateSession_args typedOther = (terminateSession_args)other;
-
- lastComparison = Boolean.valueOf(isSetSessionid()).compareTo(typedOther.isSetSessionid());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetSessionid()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sessionid, typedOther.sessionid);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 1: // SESSIONID
- if (field.type == org.apache.thrift.protocol.TType.STRING) {
- this.sessionid = iprot.readString();
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- validate();
-
- oprot.writeStructBegin(STRUCT_DESC);
- if (this.sessionid != null) {
- oprot.writeFieldBegin(SESSIONID_FIELD_DESC);
- oprot.writeString(this.sessionid);
- oprot.writeFieldEnd();
- }
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("terminateSession_args(");
- boolean first = true;
-
- sb.append("sessionid:");
- if (this.sessionid == null) {
- sb.append("null");
- } else {
- sb.append(this.sessionid);
- }
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- }
-
- public static class terminateSession_result implements org.apache.thrift.TBase<terminateSession_result, terminateSession_result._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("terminateSession_result");
-
-
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-;
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(terminateSession_result.class, metaDataMap);
- }
-
- public terminateSession_result() {
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public terminateSession_result(terminateSession_result other) {
- }
-
- public terminateSession_result deepCopy() {
- return new terminateSession_result(this);
- }
-
- @Override
- public void clear() {
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof terminateSession_result)
- return this.equals((terminateSession_result)that);
- return false;
- }
-
- public boolean equals(terminateSession_result that) {
- if (that == null)
- return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(terminateSession_result other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- terminateSession_result typedOther = (terminateSession_result)other;
-
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- oprot.writeStructBegin(STRUCT_DESC);
-
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("terminateSession_result(");
- boolean first = true;
-
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- }
-
-}
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/SwitchPortTuple.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/SwitchPortTuple.java
deleted file mode 100644
index 8fe8191..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/SwitchPortTuple.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A struct that defines switch port tuple
- */
-@SuppressWarnings("all") public class SwitchPortTuple implements org.apache.thrift.TBase<SwitchPortTuple, SwitchPortTuple._Fields>, java.io.Serializable, Cloneable {
- private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SwitchPortTuple");
-
- private static final org.apache.thrift.protocol.TField DPID_FIELD_DESC = new org.apache.thrift.protocol.TField("dpid", org.apache.thrift.protocol.TType.I64, (short)1);
- private static final org.apache.thrift.protocol.TField PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("port", org.apache.thrift.protocol.TType.I16, (short)2);
-
- public long dpid; // required
- public short port; // required
-
- /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
- public enum _Fields implements org.apache.thrift.TFieldIdEnum {
- DPID((short)1, "dpid"),
- PORT((short)2, "port");
-
- private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
- static {
- for (_Fields field : EnumSet.allOf(_Fields.class)) {
- byName.put(field.getFieldName(), field);
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, or null if its not found.
- */
- public static _Fields findByThriftId(int fieldId) {
- switch(fieldId) {
- case 1: // DPID
- return DPID;
- case 2: // PORT
- return PORT;
- default:
- return null;
- }
- }
-
- /**
- * Find the _Fields constant that matches fieldId, throwing an exception
- * if it is not found.
- */
- public static _Fields findByThriftIdOrThrow(int fieldId) {
- _Fields fields = findByThriftId(fieldId);
- if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
- return fields;
- }
-
- /**
- * Find the _Fields constant that matches name, or null if its not found.
- */
- public static _Fields findByName(String name) {
- return byName.get(name);
- }
-
- private final short _thriftId;
- private final String _fieldName;
-
- _Fields(short thriftId, String fieldName) {
- _thriftId = thriftId;
- _fieldName = fieldName;
- }
-
- public short getThriftFieldId() {
- return _thriftId;
- }
-
- public String getFieldName() {
- return _fieldName;
- }
- }
-
- // isset id assignments
- private static final int __DPID_ISSET_ID = 0;
- private static final int __PORT_ISSET_ID = 1;
- private BitSet __isset_bit_vector = new BitSet(2);
-
- public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
- static {
- Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
- tmpMap.put(_Fields.DPID, new org.apache.thrift.meta_data.FieldMetaData("dpid", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
- tmpMap.put(_Fields.PORT, new org.apache.thrift.meta_data.FieldMetaData("port", org.apache.thrift.TFieldRequirementType.DEFAULT,
- new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16)));
- metaDataMap = Collections.unmodifiableMap(tmpMap);
- org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SwitchPortTuple.class, metaDataMap);
- }
-
- public SwitchPortTuple() {
- }
-
- public SwitchPortTuple(
- long dpid,
- short port)
- {
- this();
- this.dpid = dpid;
- setDpidIsSet(true);
- this.port = port;
- setPortIsSet(true);
- }
-
- /**
- * Performs a deep copy on <i>other</i>.
- */
- public SwitchPortTuple(SwitchPortTuple other) {
- __isset_bit_vector.clear();
- __isset_bit_vector.or(other.__isset_bit_vector);
- this.dpid = other.dpid;
- this.port = other.port;
- }
-
- public SwitchPortTuple deepCopy() {
- return new SwitchPortTuple(this);
- }
-
- @Override
- public void clear() {
- setDpidIsSet(false);
- this.dpid = 0;
- setPortIsSet(false);
- this.port = 0;
- }
-
- public long getDpid() {
- return this.dpid;
- }
-
- public SwitchPortTuple setDpid(long dpid) {
- this.dpid = dpid;
- setDpidIsSet(true);
- return this;
- }
-
- public void unsetDpid() {
- __isset_bit_vector.clear(__DPID_ISSET_ID);
- }
-
- /** Returns true if field dpid is set (has been assigned a value) and false otherwise */
- public boolean isSetDpid() {
- return __isset_bit_vector.get(__DPID_ISSET_ID);
- }
-
- public void setDpidIsSet(boolean value) {
- __isset_bit_vector.set(__DPID_ISSET_ID, value);
- }
-
- public short getPort() {
- return this.port;
- }
-
- public SwitchPortTuple setPort(short port) {
- this.port = port;
- setPortIsSet(true);
- return this;
- }
-
- public void unsetPort() {
- __isset_bit_vector.clear(__PORT_ISSET_ID);
- }
-
- /** Returns true if field port is set (has been assigned a value) and false otherwise */
- public boolean isSetPort() {
- return __isset_bit_vector.get(__PORT_ISSET_ID);
- }
-
- public void setPortIsSet(boolean value) {
- __isset_bit_vector.set(__PORT_ISSET_ID, value);
- }
-
- public void setFieldValue(_Fields field, Object value) {
- switch (field) {
- case DPID:
- if (value == null) {
- unsetDpid();
- } else {
- setDpid((Long)value);
- }
- break;
-
- case PORT:
- if (value == null) {
- unsetPort();
- } else {
- setPort((Short)value);
- }
- break;
-
- }
- }
-
- public Object getFieldValue(_Fields field) {
- switch (field) {
- case DPID:
- return Long.valueOf(getDpid());
-
- case PORT:
- return Short.valueOf(getPort());
-
- }
- throw new IllegalStateException();
- }
-
- /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
- public boolean isSet(_Fields field) {
- if (field == null) {
- throw new IllegalArgumentException();
- }
-
- switch (field) {
- case DPID:
- return isSetDpid();
- case PORT:
- return isSetPort();
- }
- throw new IllegalStateException();
- }
-
- @Override
- public boolean equals(Object that) {
- if (that == null)
- return false;
- if (that instanceof SwitchPortTuple)
- return this.equals((SwitchPortTuple)that);
- return false;
- }
-
- public boolean equals(SwitchPortTuple that) {
- if (that == null)
- return false;
-
- boolean this_present_dpid = true;
- boolean that_present_dpid = true;
- if (this_present_dpid || that_present_dpid) {
- if (!(this_present_dpid && that_present_dpid))
- return false;
- if (this.dpid != that.dpid)
- return false;
- }
-
- boolean this_present_port = true;
- boolean that_present_port = true;
- if (this_present_port || that_present_port) {
- if (!(this_present_port && that_present_port))
- return false;
- if (this.port != that.port)
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- public int compareTo(SwitchPortTuple other) {
- if (!getClass().equals(other.getClass())) {
- return getClass().getName().compareTo(other.getClass().getName());
- }
-
- int lastComparison = 0;
- SwitchPortTuple typedOther = (SwitchPortTuple)other;
-
- lastComparison = Boolean.valueOf(isSetDpid()).compareTo(typedOther.isSetDpid());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetDpid()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dpid, typedOther.dpid);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- lastComparison = Boolean.valueOf(isSetPort()).compareTo(typedOther.isSetPort());
- if (lastComparison != 0) {
- return lastComparison;
- }
- if (isSetPort()) {
- lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.port, typedOther.port);
- if (lastComparison != 0) {
- return lastComparison;
- }
- }
- return 0;
- }
-
- public _Fields fieldForId(int fieldId) {
- return _Fields.findByThriftId(fieldId);
- }
-
- public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
- org.apache.thrift.protocol.TField field;
- iprot.readStructBegin();
- while (true)
- {
- field = iprot.readFieldBegin();
- if (field.type == org.apache.thrift.protocol.TType.STOP) {
- break;
- }
- switch (field.id) {
- case 1: // DPID
- if (field.type == org.apache.thrift.protocol.TType.I64) {
- this.dpid = iprot.readI64();
- setDpidIsSet(true);
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- case 2: // PORT
- if (field.type == org.apache.thrift.protocol.TType.I16) {
- this.port = iprot.readI16();
- setPortIsSet(true);
- } else {
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- break;
- default:
- org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
- }
- iprot.readFieldEnd();
- }
- iprot.readStructEnd();
-
- // check for required fields of primitive type, which can't be checked in the validate method
- validate();
- }
-
- public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
- validate();
-
- oprot.writeStructBegin(STRUCT_DESC);
- oprot.writeFieldBegin(DPID_FIELD_DESC);
- oprot.writeI64(this.dpid);
- oprot.writeFieldEnd();
- oprot.writeFieldBegin(PORT_FIELD_DESC);
- oprot.writeI16(this.port);
- oprot.writeFieldEnd();
- oprot.writeFieldStop();
- oprot.writeStructEnd();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("SwitchPortTuple(");
- boolean first = true;
-
- sb.append("dpid:");
- sb.append(this.dpid);
- first = false;
- if (!first) sb.append(", ");
- sb.append("port:");
- sb.append(this.port);
- first = false;
- sb.append(")");
- return sb.toString();
- }
-
- public void validate() throws org.apache.thrift.TException {
- // check for required fields
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
- try {
- write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
- private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
- try {
- // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
- __isset_bit_vector = new BitSet(1);
- read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
- } catch (org.apache.thrift.TException te) {
- throw new java.io.IOException(te);
- }
- }
-
-}
-
diff --git a/onos-embedded.sh b/onos-embedded.sh
index b5cfed6..fe0db44 100755
--- a/onos-embedded.sh
+++ b/onos-embedded.sh
@@ -1,9 +1,9 @@
#!/bin/sh
# Set paths
-FL_HOME=`dirname $0`
-FL_JAR="${FL_HOME}/target/floodlight.jar"
-FL_LOGBACK="${FL_HOME}/logback.xml"
+ONOS_HOME=`dirname $0`
+ONOS_JAR="${ONOS_HOME}/target/floodlight.jar"
+ONOS_LOGBACK="${ONOS_HOME}/logback.xml"
TITAN_CONFIG="/tmp/cassandra.titan"
CASSANDRA_CONFIG="/home/`whoami`/apache-cassandra-1.1.4/conf/cassandra.yaml"
@@ -17,15 +17,15 @@
#JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
# Set classpath to include titan libs
-#CLASSPATH=`echo ${FL_HOME}/lib/*.jar ${FL_HOME}/lib/titan/*.jar | sed 's/ /:/g'`
-CLASSPATH="${FL_HOME}/lib/*.jar:${FL_HOME}/lib/titan/*.jar"
+#CLASSPATH=`echo ${ONOS_HOME}/lib/*.jar ${ONOS_HOME}/lib/titan/*.jar | sed 's/ /:/g'`
+CLASSPATH="${ONOS_HOME}/lib/*.jar:${ONOS_HOME}/lib/titan/*.jar"
CASSANDRA_OPTS="-Dcom.sun.management.jmxremote.port=7199"
CASSANDRA_OPTS="$CASSANDRA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
CASSANDRA_OPTS="$CASSANDRA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
# Create a logback file if required
-cat <<EOF_LOGBACK >${FL_LOGBACK}
+cat <<EOF_LOGBACK >${ONOS_LOGBACK}
<configuration scan="true" debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
@@ -64,5 +64,5 @@
# Run floodlight
echo "Starting ONOS controller ..."
echo
-#java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -Xbootclasspath/a:$CLASSPATH -jar ${FL_JAR} -cf ./onos.properties
-java ${JVM_OPTS} ${CASSANDRA_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR}
+#java ${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -Xbootclasspath/a:$CLASSPATH -jar ${ONOS_JAR} -cf ./onos.properties
+java ${JVM_OPTS} ${CASSANDRA_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -jar ${ONOS_JAR}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..44b7f07
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,382 @@
+<?xml version="1.0"?>
+<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>
+ <prerequisites>
+ <maven>3.0.4</maven>
+ </prerequisites>
+ <groupId>net.onrc.onos</groupId>
+ <artifactId>onos</artifactId>
+ <version>0.1.0</version>
+ <packaging>jar</packaging>
+ <name>ONOS</name>
+ <url>http://onlab.us/</url>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Maven Central repository</name>
+ <url>http://repo1.maven.org/maven2</url>
+ </repository>
+ <repository>
+ <id>maven-restlet</id>
+ <name>Public online Restlet repository</name>
+ <url>http://maven.restlet.org</url>
+ </repository>
+ <repository>
+ <id>tinkerpop-repository</id>
+ <name>TinkerPop Maven2 Repository</name>
+ <url>http://tinkerpop.com/maven2</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <powermock.version>1.5</powermock.version>
+ <restlet.version>2.1-RC1</restlet.version>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.3.1</version>
+ <executions>
+ </executions>
+ </plugin>
+ <!-- guice maven plugin for dependency injection inside maven -->
+ <plugin>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>guice-maven-plugin</artifactId>
+ <version>2.11.0</version>
+ </plugin>
+ <!-- compile -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ <executions>
+ </executions>
+ </plugin>
+ <!-- test -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.12</version>
+ <configuration>
+ <excludes>
+ <!-- exclude all test cases for now -->
+ <!-- <exclude>**/storage/tests/StorageTest.java</exclude> -->
+ <!-- <exclude>**/test/*</exclude> -->
+ <!--
+ <exclude>**/test/*</exclude>
+ <exclude>**/Test*.java</exclude>
+ <exclude>**/*Test.java</exclude>
+ <exclude>**/*TestCase.java</exclude>
+ -->
+ </excludes>
+ </configuration>
+ </plugin>
+ <!-- exec:java -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2.1</version>
+ <configuration>
+ <mainClass>net.onrc.onos.ofcontroller.core.Main</mainClass>
+ </configuration>
+ <executions>
+ </executions>
+ </plugin>
+ <!--<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.7</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>lib/gen-java</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>-->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9</version>
+ <configuration>
+ <charset>UTF-8</charset>
+ <locale>en</locale>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <version>0.6.3.201306030806</version>
+ <configuration>
+ <destfile>${basedir}/target/jacoco/jacoco.exec</destfile>
+ <datafile>${basedir}/target/jacoco/jacoco.exec</datafile>
+ </configuration>
+ <executions>
+ <execution>
+ <id>jacoco-initialize</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>jacoco-site</id>
+ <phase>package</phase>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <!-- for getting visualization reporting -->
+ <reporting>
+ <excludeDefaults>true</excludeDefaults>
+ <outputDirectory>${project.build.directory}/site</outputDirectory>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>guice-maven-plugin</artifactId>
+ <version>2.11.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <dependencyDetailsEnabled>false</dependencyDetailsEnabled>
+ <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>dependencies</report>
+ <report>maven-emma-plugin</report>
+ <report>scm</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9</version>
+ <configuration>
+ <charset>UTF-8</charset>
+ <locale>en</locale>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+ <dependencies>
+ <!-- ONOS's direct dependencies -->
+ <dependency>
+ <groupId>org.apache.cassandra</groupId>
+ <artifactId>apache-cassandra</artifactId>
+ <version>1.2.4</version>
+ <type>pom</type>
+ </dependency>
+ <dependency>
+ <groupId>com.thinkaurelius.titan</groupId>
+ <artifactId>titan-all</artifactId>
+ <version>0.2.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.tinkerpop</groupId>
+ <artifactId>frames</artifactId>
+ <version>2.3.1</version>
+ </dependency>
+ <!--
+ <dependency>
+ <groupId>com.tinkerpop.blueprints</groupId>
+ <artifactId>blueprints-core</artifactId>
+ <version>2.3.0</version>
+ </dependency>
+ -->
+ <dependency>
+ <groupId>net.sf.json-lib</groupId>
+ <artifactId>json-lib</artifactId>
+ <version>2.4</version>
+ <classifier>jdk15</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.restlet.jse</groupId>
+ <artifactId>org.restlet</artifactId>
+ <version>${restlet.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.restlet.jse</groupId>
+ <artifactId>org.restlet.ext.slf4j</artifactId>
+ <version>${restlet.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ <version>1.9.11</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ <version>1.9.11</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.0.0</version>
+ <scope>runtime</scope>
+ </dependency>
+ <!-- Floodlight's dependencies -->
+ <dependency>
+ <groupId>net.sourceforge.cobertura</groupId>
+ <artifactId>cobertura</artifactId>
+ <version>1.9.4.1</version>
+ </dependency>
+ <!--
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>13.0.1</version>
+ </dependency>
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.6.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.restlet.jse</groupId>
+ <artifactId>org.restlet.ext.jackson</artifactId>
+ <version>${restlet.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.restlet.jse</groupId>
+ <artifactId>org.restlet.ext.simple</artifactId>
+ <version>${restlet.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.simpleframework</groupId>
+ <artifactId>simple</artifactId>
+ <version>4.1.21</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.netty</groupId>
+ <artifactId>netty</artifactId>
+ <version>3.2.6.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>args4j</groupId>
+ <artifactId>args4j</artifactId>
+ <version>2.0.16</version>
+ </dependency>
+ <dependency>
+ <groupId>com.googlecode.concurrentlinkedhashmap</groupId>
+ <artifactId>concurrentlinkedhashmap-lru</artifactId>
+ <version>1.3</version>
+ </dependency>
+ <!--<dependency>
+ <groupId>org.python</groupId>
+ <artifactId>jython-standalone</artifactId>
+ <version>2.5.2</version>
+ </dependency>-->
+ <!--<dependency>
+ <groupId>org.apache.thrift</groupId>
+ <artifactId>libthrift</artifactId>
+ <version>0.7.0</version>
+ </dependency>-->
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ <version>3.0</version>
+ </dependency>
+ <!-- Dependency for libraries used for testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>3.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-easymock</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <!--
+ <dependency>
+ <groupId>org.objenesis</groupId>
+ <artifactId>objenesis</artifactId>
+ <version>1.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib-nodep</artifactId>
+ <version>2.2.2</version>
+ </dependency>
+ -->
+ <!-- dependency to locally modified version -->
+ <dependency>
+ <groupId>com.netflix.curator</groupId>
+ <artifactId>curator-framework</artifactId>
+ <version>1.3.5-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>com.netflix.curator</groupId>
+ <artifactId>curator-client</artifactId>
+ <version>1.3.5-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>com.netflix.curator</groupId>
+ <artifactId>curator-recipes</artifactId>
+ <version>1.3.5-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>com.netflix.curator</groupId>
+ <artifactId>curator-x-discovery</artifactId>
+ <version>1.3.5-SNAPSHOT</version>
+ </dependency>
+ <!--
+ <dependency>
+ <groupId>net.floodlightcontroller</groupId>
+ <artifactId>packetstreamer-thrift</artifactId>
+ <version>0.1.0</version>
+ </dependency>
+ -->
+ </dependencies>
+</project>
diff --git a/scripts/run-onos-simple.sh b/scripts/run-onos-simple.sh
deleted file mode 100755
index 41b2cc6..0000000
--- a/scripts/run-onos-simple.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-basedir=`dirname $0`
-onosdir="${basedir}/.."
-
-logfile="${onosdir}/logback.xml"
-jarfile="${onosdir}/target/floodlight-only.jar"
-classpath="${jarfile}:${onosdir}/lib/*:${onosdir}/lib/titan/*"
-mainclass="net.floodlightcontroller.core.Main"
-propfile="${onosdir}/onos.properties"
-
-#java -Dlogback.configurationFile=logback.xml -cp target/floodlight-only.jar:lib/*:lib/titan/* net.floodlightcontroller.core.Main -cf onos.properties
-java -Dlogback.configurationFile=${logfile} -cp ${classpath} ${mainclass} -cf ${propfile}
diff --git a/scripts/runiperf.sh b/scripts/runiperf.sh
index 4e26bd2..6233986 100755
--- a/scripts/runiperf.sh
+++ b/scripts/runiperf.sh
@@ -2,11 +2,17 @@
import sys
import os
+ONOSDIR=os.getenv("HOME") + "/ONOS"
+IPERF=ONOSDIR + "/scripts/iperf"
+IPERFLOGDIR=ONOSDIR + "/web/log"
+
# Usage: flowid src_dpid dst_dpid params
def usage():
print "%s flowid src_dpid dst_dpid hw:svr|sw:svr|hw:client|sw:client <proto>/<duration>/<interval>/<samples>" % sys.argv[0]
sys.exit()
+
+
def main():
flowid = sys.argv[1]
src_dpid = sys.argv[2]
@@ -24,9 +30,16 @@
src_hostid=int(src_dpid.split(':')[-1], 16)
dst_hostid=int(dst_dpid.split(':')[-1], 16)
+ if (testbed == "SW"):
+ MRUN=ONOSDIR + "/test-network/mininet/mrun"
+ HOST_FMT="host%d.%d"
+ else:
+ MRUN=ONOSDIR + "$HOME/mininet/util/m"
+ HOST_FMT="g%sh%02d"
+
if (proto == "tcp"):
- if (testbed == "SW"):
- cmd="ssh -o StrictHostKeyChecking=no 1.1.%d.1 '/home/ubuntu/ONOS/scripts/iperf -t%s -i%s -k%s -yJ -o /home/ubuntu/ONOS/web/log/iperf_%s.out -c 192.168.%d.%d 2>&1 &' &" % (src_hostid, duration, interval, samples, flowid, dst_nwid, dst_hostid)
+ mininet_host = HOST_FMT % (dst_nwid, dst_hostid)
+ cmd="%s %s \'%s -t%s -i%s -k%s -yJ -o %s/iperf_%s.out -c 192.168.%d.%d 2>&1 &\' &" % (MRUN, mininet_host, IPERF, src_hostid, duration, interval, samples, IPERFLOGDIR, flowid, dst_nwid, dst_hostid)
killcmd='sudo pkill -KILL -f \"iperf .* -o .*/iperf_%s.out\"' % (flowid)
print killcmd
print cmd
@@ -34,21 +47,18 @@
os.popen(cmd)
else:
if (server == 'S'):
- if (testbed == "SW"):
- cmd="ssh -o StrictHostKeyChecking=no 1.1.%d.1 '/home/ubuntu/ONOS/scripts/iperf -us -i%s -k%s -yJ -o /home/ubuntu/ONOS/web/log/iperfsvr_%s.out 2>&1 &' &" % (dst_hostid, interval, samples, flowid)
- else:
- cmd="~/mininet/util/m g%sh%02d '/home/ubuntu/ONOS/scripts/iperf -us -i%s -k%s -yJ -o /home/ubuntu/ONOS/web/log/iperfsvr_%s.out 2>&1 &' &" % (dst_nwid, dst_hostid, interval, samples, flowid)
+ mininet_host = HOST_FMT % (dst_nwid, dst_hostid)
+ cmd="%s %s \'%s -us -i%s -k%s -yJ -o %s/iperfsvr_%s.out 2>&1 &\' &" % (MRUN, mininet_host, IPERF, interval, samples, IPERFLOGDIR, flowid)
killcmd='sudo pkill -KILL -f \"iperf .* -o .*/iperfsvr_%s.out\"' % (flowid)
print killcmd
print cmd
else:
- if (testbed == "SW"):
- cmd="ssh -o StrictHostKeyChecking=no 1.1.%d.1 '/home/ubuntu/ONOS/scripts/iperf -u -t%s -i%s -k%s -yJ -o /home/ubuntu/ONOS/web/log/iperfclient_%s.out -c 192.168.%d.%d 2>&1 &' &" % (src_hostid, duration, interval, samples, flowid, dst_nwid, dst_hostid)
- else:
- cmd="~/mininet/util/m g%sh%02d '/home/ubuntu/ONOS/scripts/iperf -u -t%s -i%s -k%s -yJ -o /home/ubuntu/ONOS/web/log/iperfclient_%s.out -c 192.168.%d.%d 2>&1 &' &" % (src_nwid, src_hostid, duration, interval, samples, flowid, dst_nwid, dst_hostid )
+ mininet_host = HOST_FMT % (src_nwid, src_hostid)
+ cmd="%s %s \'%s -u -t%s -i%s -k%s -yJ -o %s/iperfclient_%s.out -c 192.168.%d.%d 2>&1 &\' &" % (MRUN, mininet_host, IPERF, duration, interval, samples, IPERFLOGDIR, flowid, dst_nwid, dst_hostid)
killcmd='sudo pkill -KILL -f \"iperf .* -o .*/iperfclient_%s.out\"' % (flowid)
print killcmd
print cmd
+
os.popen(killcmd)
os.popen(cmd)
diff --git a/setup-eclipse.sh b/setup-eclipse.sh
index a39dc62..8cf8ed3 100755
--- a/setup-eclipse.sh
+++ b/setup-eclipse.sh
@@ -1,50 +1,6 @@
#!/bin/bash
+if [ -z "${MVN}" ]; then
+ MVN="mvn"
+fi
+${MVN} eclipse:eclipse
-d=$(dirname $0)
-MAIN_CLASS=$1
-LIBRARIES=$2
-[ "${MAIN_CLASS}" ] || { echo "Run 'ant eclipse' to generate Eclipse project files"; exit 1; }
-
-
-cat >$d/.project <<EOF
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>floodlight</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
-EOF
-
-
-cat >$d/.classpath <<EOF
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src/main/java" output="target/bin"/>
- <classpathentry kind="src" path="src/main/resources"/>
- <classpathentry kind="src" path="src/test/java" output="target/bin-test"/>
- <classpathentry kind="src" path="lib/gen-java" output="target/bin"/>
-EOF
-(
-IFS=":"
-for l in ${LIBRARIES}; do
-cat >>$d/.classpath <<EOF
- <classpathentry exported="true" kind="lib" path="$l"/>
-EOF
-done
-)
-cat >>$d/.classpath <<EOF
- <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="output" path="target/bin"/>
-</classpath>
-EOF
diff --git a/setup-local-maven.sh b/setup-local-maven.sh
new file mode 100755
index 0000000..3a2538c
--- /dev/null
+++ b/setup-local-maven.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+if [ -z "${MVN}" ]; then
+ MVN="mvn"
+fi
+
+${MVN} install:install-file -Dfile=./lib/curator-framework-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-framework -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
+${MVN} install:install-file -Dfile=./lib/curator-client-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-client -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
+${MVN} install:install-file -Dfile=./lib/curator-recipes-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-recipes -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
+${MVN} install:install-file -Dfile=./lib/curator-x-discovery-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-x-discovery -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
+
+# download package dependencies
+${MVN} dependency:go-offline
+
+# run goals to download required plugins
+${MVN} -q test -Dtest=DoNotTest -DfailIfNoTests=false > /dev/null
+${MVN} clean compile
diff --git a/src/main/java/net/floodlightcontroller/bgproute/BgpRoute.java b/src/main/java/net/floodlightcontroller/bgproute/BgpRoute.java
deleted file mode 100644
index 47f3d1a..0000000
--- a/src/main/java/net/floodlightcontroller/bgproute/BgpRoute.java
+++ /dev/null
@@ -1,313 +0,0 @@
-package net.floodlightcontroller.bgproute;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collection;
-import java.util.Map;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.topology.ITopologyListener;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.restclient.RestClient;
-
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-import net.sf.json.JSONSerializer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BgpRoute implements IFloodlightModule, IBgpRouteService, ITopologyListener {
-
- protected static Logger log = LoggerFactory.getLogger(BgpRoute.class);
-
- protected IFloodlightProviderService floodlightProvider;
- protected ITopologyService topology;
-
- protected static Ptree ptree;
- protected static String BGPdRestIp;
- protected static String RouterId;
-
-
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IBgpRouteService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
- Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
- m.put(IBgpRouteService.class, this);
- return m;
- }
-
- protected IRestApiService restApi;
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(ITopologyService.class);
- l.add(IBgpRouteService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
-
- ptree = new Ptree(32);
-
- // Register floodlight provider and REST handler.
- floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
- restApi = context.getServiceImpl(IRestApiService.class);
- topology = context.getServiceImpl(ITopologyService.class);
-
- // Test.
- //test();
-
- }
-
- public Ptree getPtree() {
- return ptree;
- }
- public void clearPtree() {
- ptree = null;
- ptree = new Ptree(32);
-
- }
- public String getBGPdRestIp() {
- return BGPdRestIp;
- }
- public String getRouterId() {
- return RouterId;
- }
-
- // Return nexthop address as byte array.
- public Rib lookupRib(byte[] dest) {
- if (ptree == null) {
- log.debug("lookupRib: ptree null");
- return null;
- }
-
- PtreeNode node = ptree.match(dest, 32);
- if (node == null) {
- log.debug("lookupRib: ptree node null");
- return null;
- }
- if (node.rib == null) {
- log.debug("lookupRib: ptree rib null");
- return null;
- }
- ptree.delReference(node);
-
- return node.rib;
- }
-
- @SuppressWarnings("unused")
- private void test() {
- System.out.println("Here it is");
- Prefix p = new Prefix("128.0.0.0", 8);
- Prefix q = new Prefix("8.0.0.0", 8);
- Prefix r = new Prefix("10.0.0.0", 24);
- Prefix a = new Prefix("10.0.0.1", 32);
-
- ptree.acquire(p.getAddress(), p.masklen);
- ptree.acquire(q.getAddress(), q.masklen);
- ptree.acquire(r.getAddress(), r.masklen);
-
- System.out.println("Traverse start");
- for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
- Prefix p_result = new Prefix(node.key, node.keyBits);
- }
-
- PtreeNode n = ptree.match(a.getAddress(), a.masklen);
- if (n != null) {
- System.out.println("Matched prefix for 10.0.0.1:");
- Prefix x = new Prefix(n.key, n.keyBits);
- ptree.delReference(n);
- }
-
- n = ptree.lookup(p.getAddress(), p.masklen);
- if (n != null) {
- ptree.delReference(n);
- ptree.delReference(n);
- }
- System.out.println("Traverse start");
- for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
- Prefix p_result = new Prefix(node.key, node.keyBits);
- }
-
- n = ptree.lookup(q.getAddress(), q.masklen);
- if (n != null) {
- ptree.delReference(n);
- ptree.delReference(n);
- }
- System.out.println("Traverse start");
- for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
- Prefix p_result = new Prefix(node.key, node.keyBits);
- }
-
- n = ptree.lookup(r.getAddress(), r.masklen);
- if (n != null) {
- ptree.delReference(n);
- ptree.delReference(n);
- }
- System.out.println("Traverse start");
- for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
- Prefix p_result = new Prefix(node.key, node.keyBits);
- }
-
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- restApi.addRestletRoutable(new BgpRouteWebRoutable());
- topology.addListener((ITopologyListener) this);
-
- // get the BGPdRestIp and RouterId from transit-route-pusher.py
- File file = new File("/home/ubuntu/sdn/transit-route-pusher.py");
-
-
- try{
- BufferedReader input = new BufferedReader (new FileReader(file));
- String text;
- int is_BGPdRestIp=0;
- int is_RouterId=0;
-
- while((text = input.readLine()) != null && (is_BGPdRestIp == 0) || (is_RouterId == 0) ){
-
- if(is_BGPdRestIp == 1 && is_RouterId ==1)
- {break;}
-
- if(is_BGPdRestIp == 0 && text.contains("BGPdRestIp") ){
- String[] temp = text.split("\"");
- BGPdRestIp = temp[1];
- is_BGPdRestIp = 1;
-
-
- }else if (is_RouterId == 0 && text.contains("RouterId") ){
-
- String[] temp = text.split("\"");
- RouterId = temp[1];
- is_RouterId = 1;
-
-
- }
-
- }
-
-
- } catch(Exception e){
- e.printStackTrace();
- }
-
-
- // automatically get the rib from bgpd at the ONOS initiation process.
- String dest=RouterId;
- String str="http://"+BGPdRestIp+"/wm/bgp/"+dest;
-
-
- try {
-
- URL url = new URL(str);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- conn.setRequestProperty("Accept", "application/json");
-
- if (conn.getResponseCode() != 200) {
- throw new RuntimeException("Failed : HTTP error code : "
- + conn.getResponseCode());
- }
-
- BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
- StringBuffer res = new StringBuffer();
- String line;
- while ((line = br.readLine()) != null) {
- res.append(line);
- }
-
- String res2=res.toString().replaceAll("\"", "'");
- JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(res2);
- JSONArray rib_json_array = jsonObj.getJSONArray("rib");
- String router_id = jsonObj.getString("router-id");
-
- int size = rib_json_array.size();
- System.out.print("size:"+size+"\n");
- for (int j = 0; j < size; j++) {
- JSONObject second_json_object = rib_json_array.getJSONObject(j);
- String prefix = second_json_object.getString("prefix");
- String nexthop = second_json_object.getString("nexthop");
-
- //insert each rib entry into the local rib;
- String[] substring= prefix.split("/");
- String prefix1=substring[0];
- String mask1=substring[1];
-
- Prefix p = new Prefix(prefix1, Integer.valueOf(mask1));
- PtreeNode node = ptree.acquire(p.getAddress(), p.masklen);
- Rib rib = new Rib(router_id, nexthop, p.masklen);
-
- if (node.rib != null) {
- node.rib = null;
- ptree.delReference(node);
- }
- node.rib = rib;
-
- }
- br.close();
- conn.disconnect();
-
- } catch (MalformedURLException e) {
-
- e.printStackTrace();
-
- } catch (IOException e) {
-
- e.printStackTrace();
-
- }
-
-
- }
-
- @Override
- public void topologyChanged() {
- boolean change = false;
- String changelog = "";
-
- for (LDUpdate ldu : topology.getLastLinkUpdates()) {
- if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_DOWN)) {
- change = true;
- changelog = changelog + " down ";
- } else if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_UP)) {
- change = true;
- changelog = changelog + " up ";
- }
- }
- log.info ("received topo change" + changelog);
-
- if (change) {
- RestClient.get ("http://localhost:5000/topo_change");
- }
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/bgproute/BgpRouteResource.java b/src/main/java/net/floodlightcontroller/bgproute/BgpRouteResource.java
deleted file mode 100644
index 28d9621..0000000
--- a/src/main/java/net/floodlightcontroller/bgproute/BgpRouteResource.java
+++ /dev/null
@@ -1,193 +0,0 @@
-package net.floodlightcontroller.bgproute;
-
-import org.restlet.resource.Get;
-import org.restlet.resource.Post;
-import org.restlet.resource.Delete;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import net.floodlightcontroller.restclient.RestClient;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-
-public class BgpRouteResource extends ServerResource {
-
- protected static Logger log = LoggerFactory
- .getLogger(BgpRouteResource.class);
-
- private String addrToString(byte [] addr) {
- String str = "";
-
- for (int i = 0; i < 4; i++) {
- int val = (addr[i] & 0xff);
- str += val;
- if (i != 3)
- str += ".";
- }
-
- return str;
- }
-
- @SuppressWarnings("unused")
- @Get
- public String get(String fmJson) {
- String linpp=fmJson;
- String dest = (String) getRequestAttributes().get("dest");
- String output = "";
- IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
- get(IBgpRouteService.class.getCanonicalName());
-
- if (dest != null) {
- Prefix p = new Prefix(dest, 32);
- if (p == null) {
- return "[GET]: dest address format is wrong";
- }
-
- // the dest here refers to router-id
- //BGPdRestIp includes port number, such as 1.1.1.1:8080
- String BGPdRestIp = bgpRoute.getBGPdRestIp();
- String url="http://"+BGPdRestIp+"/wm/bgp/"+dest;
-
-
-
- RestClient.get(url);
- output="Get rib from bgpd finished!\n";
- return output;
-
- } else {
- Ptree ptree = bgpRoute.getPtree();
- output += "{\n \"rib\": [\n";
- boolean printed = false;
- for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
- if (node.rib == null) {
- continue;
- }
- if (printed == true) {
- output += ",\n";
- }
- output += " {\"prefix\": \"" + addrToString(node.key) + "/" + node.keyBits +"\", ";
- output += "\"nexthop\": \"" + addrToString(node.rib.nextHop.getAddress()) +"\"}";
- printed = true;
- }
- //output += "{\"router_id\": \"" + addrToString(node.rib.routerId.getAddress()) +"\"}\n";
- output += "\n ]\n}\n";
-
- }
- return output;
- }
-
- public static ByteBuffer toByteBuffer(String value) throws UnsupportedEncodingException
- {
- return ByteBuffer.wrap(value.getBytes("UTF-8"));
- }
-
-public static String toString(ByteBuffer buffer) throws UnsupportedEncodingException
- {
- byte[] bytes = new byte[buffer.remaining()];
- buffer.get(bytes);
- return new String(bytes, "UTF-8");
-
- }
-
-
- @Post
- public String store(String fmJson) {
- IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
- get(IBgpRouteService.class.getCanonicalName());
-
- Ptree ptree = bgpRoute.getPtree();
-
- String router_id = (String) getRequestAttributes().get("routerid");
- String prefix = (String) getRequestAttributes().get("prefix");
- String mask = (String) getRequestAttributes().get("mask");
- String nexthop = (String) getRequestAttributes().get("nexthop");
- String capability = (String) getRequestAttributes().get("capability");
-
-
- String reply = "";
-
- if (capability == null) {
-
- // this is a prefix add
- Prefix p = new Prefix(prefix, Integer.valueOf(mask));
- PtreeNode node = ptree.acquire(p.getAddress(), p.masklen);
- Rib rib = new Rib(router_id, nexthop, p.masklen);
-
- if (node.rib != null) {
- node.rib = null;
- ptree.delReference(node);
- }
- node.rib = rib;
-
- reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "]";
- log.info(reply);
-
-
- }else if(capability.equals("1")){
- reply = "[POST-capability: " + capability + "]\n";
- log.info(reply);
- // to store the number in the top node of the Ptree
-
- }else{
- reply = "[POST-capability: " + capability + "]\n";
- log.info(reply);
- // to store the number in the top node of the Ptree
-
- }
-
-
- return reply + "\n";
-
-
- }
-
- @Delete
- public String delete(String fmJson) {
- IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
- get(IBgpRouteService.class.getCanonicalName());
-
- Ptree ptree = bgpRoute.getPtree();
-
- String routerId = (String) getRequestAttributes().get("routerid");
- String prefix = (String) getRequestAttributes().get("prefix");
- String mask = (String) getRequestAttributes().get("mask");
- String nextHop = (String) getRequestAttributes().get("nexthop");
- String capability = (String) getRequestAttributes().get("capability");
-
- String reply = "";
-
- if (capability == null) {
- // this is a prefix delete
- Prefix p = new Prefix(prefix, Integer.valueOf(mask));
-
- PtreeNode node = ptree.lookup(p.getAddress(), p.masklen);
-
- Rib r = new Rib(routerId, nextHop, p.masklen);
-
- if (node != null && node.rib != null) {
-
- if (r.equals(node.rib)) {
-
- node.rib = null;
- ptree.delReference(node);
- }
- }
-
-
- reply =reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "]";
-
- }else {
-
- // clear the local rib: Ptree
- bgpRoute.clearPtree();
- reply = "[DELE-capability: " + capability + "; The local Rib is cleared!]\n";
-
-
- // to store the number in the top node of the Ptree
-
- }
- log.info(reply);
-
- return reply + "\n";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/bgproute/IBgpRouteService.java b/src/main/java/net/floodlightcontroller/bgproute/IBgpRouteService.java
deleted file mode 100644
index a6025ef..0000000
--- a/src/main/java/net/floodlightcontroller/bgproute/IBgpRouteService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package net.floodlightcontroller.bgproute;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IBgpRouteService extends IFloodlightService {
-
- public Rib lookupRib(byte[] dest);
-
- public Ptree getPtree();
-
- public String getBGPdRestIp();
-
- public String getRouterId();
-
- public void clearPtree() ;
-
-
-}
diff --git a/src/main/java/net/floodlightcontroller/bgproute/Prefix.java b/src/main/java/net/floodlightcontroller/bgproute/Prefix.java
deleted file mode 100644
index 7ba014b..0000000
--- a/src/main/java/net/floodlightcontroller/bgproute/Prefix.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package net.floodlightcontroller.bgproute;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-public class Prefix {
- public int masklen;
- protected InetAddress address;
-
- Prefix(byte[] addr, int masklen) {
- try {
- address = InetAddress.getByAddress(addr);
- } catch (UnknownHostException e) {
- System.out.println("InetAddress exception");
- return;
- }
- this.masklen = masklen;
- System.out.println(address.toString() + "/" + masklen);
- }
-
- Prefix(String str, int masklen) {
- try {
- address = InetAddress.getByName(str);
- //System.out.println(address.toString());
- } catch (UnknownHostException e) {
- System.out.println("InetAddress exception");
- return;
- }
- this.masklen = masklen;
- }
-
- public byte [] getAddress() {
- return address.getAddress();
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
index cd15927..c821339 100644
--- a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
@@ -10,13 +10,12 @@
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.flowcache.IFlowService;
import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.storage.IStorageSourceService;
import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
import net.onrc.onos.registry.controller.IControllerRegistryService;
public class FloodlightProvider implements IFloodlightModule {
@@ -52,8 +51,8 @@
dependencies.add(IRestApiService.class);
dependencies.add(ICounterStoreService.class);
dependencies.add(IThreadPoolService.class);
+ // Following added by ONOS
dependencies.add(IFlowService.class);
- dependencies.add(ITopoRouteService.class);
dependencies.add(IControllerRegistryService.class);
return dependencies;
@@ -71,8 +70,8 @@
context.getServiceImpl(IRestApiService.class));
controller.setThreadPoolService(
context.getServiceImpl(IThreadPoolService.class));
+ // Following added by ONOS
controller.setFlowService(context.getServiceImpl(IFlowService.class));
- controller.setTopoRouteService(context.getServiceImpl(ITopoRouteService.class));
controller.setMastershipService(
context.getServiceImpl(IControllerRegistryService.class));
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapService.java b/src/main/java/net/floodlightcontroller/core/INetMapService.java
deleted file mode 100644
index fcc542a..0000000
--- a/src/main/java/net/floodlightcontroller/core/INetMapService.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.floodlightcontroller.core;
-
-public interface INetMapService {
-
-}
diff --git a/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java b/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java
deleted file mode 100644
index 36b5be3..0000000
--- a/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package net.floodlightcontroller.core;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IOFMessageFilterManagerService extends IFloodlightService {
- // empty for now
-}
diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
index df609e7..d63624c 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
@@ -338,12 +338,6 @@
Object removeAttribute(String name);
/**
- * Setup an unconnected switch with the info required.
- * @param dpid of the switch
- */
- public void setupRemoteSwitch(Long dpid);
-
- /**
* Clear all flowmods on this switch
*/
public void clearAllFlowMods();
diff --git a/src/main/java/net/floodlightcontroller/core/ISwitchStorage.java b/src/main/java/net/floodlightcontroller/core/ISwitchStorage.java
deleted file mode 100644
index 1219aac..0000000
--- a/src/main/java/net/floodlightcontroller/core/ISwitchStorage.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package net.floodlightcontroller.core;
-
-import java.util.Collection;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-
-import org.openflow.protocol.OFPhysicalPort;
-
-public interface ISwitchStorage extends INetMapStorage {
-
- public enum SwitchState {
- INACTIVE,
- ACTIVE
- }
-
- /*
- * Update the switch details
- */
- public void update(String dpid,SwitchState state, DM_OPERATION op);
- /*
- * Associate a port on switch
- */
- public void addPort(String dpid, OFPhysicalPort port);
- /*
- * Get all ports associated on a switch
- */
- public Collection<OFPhysicalPort> getPorts(long dpid);
- /*
- * Get Port by Number
- */
- public OFPhysicalPort getPort(String dpid, short portnum);
- /*
- * Get port by name
- */
- public OFPhysicalPort getPort(String dpid, String portName);
- /*
- * Add a switch
- */
- public void addSwitch(String dpid);
- /*
- * Delete switch and associated ports
- */
- public void deleteSwitch(String dpid);
- /*
- * Delete a port on a switch by num
- */
- public void deletePort(String dpid, short port);
- /*
- * Delete port on a switch by name
- */
- public void deletePort(String dpid, String portName);
-
-
- /*
- * Initialize
- */
- public void init(String conf);
-
-
-}
diff --git a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
deleted file mode 100644
index 391c002..0000000
--- a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/**
- * Copyright 2011, Big Switch Networks, Inc.
- * Originally created by David Erickson, Stanford University
- *
- * 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 net.floodlightcontroller.core;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFType;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-import java.util.ArrayList;
-import org.apache.thrift.TException;
-import org.apache.thrift.transport.TFramedTransport;
-import org.apache.thrift.transport.TTransport;
-import org.apache.thrift.transport.TSocket;
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.protocol.TProtocol;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packetstreamer.thrift.*;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-
-@LogMessageCategory("OpenFlow Message Tracing")
-public class OFMessageFilterManager
- implements IOFMessageListener, IFloodlightModule, IOFMessageFilterManagerService {
-
- /**
- * @author Srini
- */
- protected static Logger log = LoggerFactory.getLogger(OFMessageFilterManager.class);
-
- // The port and client reference for packet streaming
- protected int serverPort = 9090;
- protected final int MaxRetry = 1;
- protected static TTransport transport = null;
- protected static PacketStreamer.Client packetClient = null;
-
- protected IFloodlightProviderService floodlightProvider = null;
- protected IThreadPoolService threadPool = null;
- // filter List is a key value pair. Key is the session id,
- // value is the filter rules.
- protected ConcurrentHashMap<String,
- ConcurrentHashMap<String,
- String>> filterMap = null;
- protected ConcurrentHashMap<String, Long> filterTimeoutMap = null;
- protected Timer timer = null;
-
- protected int MAX_FILTERS=5;
- protected long MAX_FILTER_TIME= 300000; // maximum filter time is 5 minutes.
- protected int TIMER_INTERVAL = 1000; // 1 second time interval.
-
- public static final String SUCCESS = "0";
- public static final String FILTER_SETUP_FAILED = "-1001";
- public static final String FILTER_NOT_FOUND = "-1002";
- public static final String FILTER_LIMIT_REACHED = "-1003";
- public static final String FILTER_SESSION_ID_NOT_FOUND = "-1004";
- public static final String SERVICE_UNAVAILABLE = "-1005";
-
- public enum FilterResult {
- /*
- * FILTER_NOT_DEFINED: Filter is not defined
- * FILTER_NO_MATCH: Filter is defined and the packet doesn't
- * match the filter
- * FILTER_MATCH: Filter is defined and the packet matches
- * the filter
- */
- FILTER_NOT_DEFINED, FILTER_NO_MATCH, FILTER_MATCH
- }
-
- protected String addFilter(ConcurrentHashMap<String,String> f, long delta) {
-
- // Create unique session ID.
- int prime = 33791;
- String s = null;
- int i;
-
- if ((filterMap == null) || (filterTimeoutMap == null))
- return String.format("%d", FILTER_SETUP_FAILED);
-
- for (i=0; i<MAX_FILTERS; ++i) {
- Integer x = prime + i;
- s = String.format("%d", x.hashCode());
- // implies you can use this key for session id.
- if (!filterMap.containsKey(s)) break;
- }
-
- if (i==MAX_FILTERS) {
- return FILTER_LIMIT_REACHED;
- }
-
- filterMap.put(s, f);
- if (filterTimeoutMap.containsKey(s)) filterTimeoutMap.remove(s);
- filterTimeoutMap.put(s, delta);
-
- // set the timer as there will be no existing timers.
- if (filterMap.size() == 1) {
- TimeoutFilterTask task = new TimeoutFilterTask(this);
- Timer timer = new Timer();
- timer.schedule (task, TIMER_INTERVAL);
- // Keep the listeners to avoid race condition
- //startListening();
- }
- return s; // the return string is the session ID.
- }
-
- public String setupFilter(String sid,
- ConcurrentHashMap<String,String> f,
- int deltaInMilliSeconds) {
-
- if (sid == null) {
- // Delta in filter needs to be milliseconds
- log.debug("Adding new filter: {} for {} ms", f, deltaInMilliSeconds);
- return addFilter(f, deltaInMilliSeconds);
- } else {// this is the session id.
- // we will ignore the hash map features.
- if (deltaInMilliSeconds > 0)
- return refreshFilter(sid, deltaInMilliSeconds);
- else
- return deleteFilter(sid);
- }
- }
-
- public int timeoutFilters() {
- Iterator<String> i = filterTimeoutMap.keySet().iterator();
-
- while(i.hasNext()) {
- String s = i.next();
-
- Long t = filterTimeoutMap.get(s);
- if (t != null) {
- i.remove();
- t -= TIMER_INTERVAL;
- if (t > 0) {
- filterTimeoutMap.put(s, t);
- } else deleteFilter(s);
- } else deleteFilter(s);
- }
- return filterMap.size();
- }
-
- protected String refreshFilter(String s, int delta) {
- Long t = filterTimeoutMap.get(s);
- if (t != null) {
- filterTimeoutMap.remove(s);
- t += delta; // time is in milliseconds
- if (t > MAX_FILTER_TIME) t = MAX_FILTER_TIME;
- filterTimeoutMap.put(s, t);
- return SUCCESS;
- } else return FILTER_SESSION_ID_NOT_FOUND;
- }
-
- @LogMessageDoc(level="ERROR",
- message="Error while terminating packet " +
- "filter session",
- explanation="An unknown error occurred while terminating " +
- "a packet filter session.",
- recommendation=LogMessageDoc.GENERIC_ACTION)
- protected String deleteFilter(String sessionId) {
-
- if (filterMap.containsKey(sessionId)) {
- filterMap.remove(sessionId);
- try {
- if (packetClient != null)
- packetClient.terminateSession(sessionId);
- } catch (TException e) {
- log.error("Error while terminating packet " +
- "filter session", e);
- }
- log.debug("Deleted Filter {}. # of filters" +
- " remaining: {}", sessionId, filterMap.size());
- return SUCCESS;
- } else return FILTER_SESSION_ID_NOT_FOUND;
- }
-
- public HashSet<String> getMatchedFilters(OFMessage m, FloodlightContext cntx) {
-
- HashSet<String> matchedFilters = new HashSet<String>();
-
- // This default function is written to match on packet ins and
- // packet outs.
- Ethernet eth = null;
-
- if (m.getType() == OFType.PACKET_IN) {
- eth = IFloodlightProviderService.bcStore.get(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
- } else if (m.getType() == OFType.PACKET_OUT) {
- eth = new Ethernet();
- OFPacketOut p = (OFPacketOut) m;
-
- // No MAC match if packetOut doesn't have the packet.
- if (p.getPacketData() == null) return null;
-
- eth.deserialize(p.getPacketData(), 0, p.getPacketData().length);
- } else if (m.getType() == OFType.FLOW_MOD) {
- // flow-mod can't be matched by mac.
- return null;
- }
-
- if (eth == null) return null;
-
- Iterator<String> filterIt = filterMap.keySet().iterator();
- while (filterIt.hasNext()) { // for every filter
- boolean filterMatch = false;
- String filterSessionId = filterIt.next();
- Map<String,String> filter = filterMap.get(filterSessionId);
-
- // If the filter has empty fields, then it is not considered as a match.
- if (filter == null || filter.isEmpty()) continue;
- Iterator<String> fieldIt = filter.keySet().iterator();
- while (fieldIt.hasNext()) {
- String filterFieldType = fieldIt.next();
- String filterFieldValue = filter.get(filterFieldType);
- if (filterFieldType.equals("mac")) {
-
- String srcMac = HexString.toHexString(eth.getSourceMACAddress());
- String dstMac = HexString.toHexString(eth.getDestinationMACAddress());
- log.debug("srcMac: {}, dstMac: {}", srcMac, dstMac);
-
- if (filterFieldValue.equals(srcMac) ||
- filterFieldValue.equals(dstMac)){
- filterMatch = true;
- } else {
- filterMatch = false;
- break;
- }
- }
- }
- if (filterMatch) {
- matchedFilters.add(filterSessionId);
- }
- }
-
- if (matchedFilters.isEmpty())
- return null;
- else
- return matchedFilters;
- }
-
- @LogMessageDoc(level="ERROR",
- message="Failed to establish connection with the " +
- "packetstreamer server.",
- explanation="The message tracing server is not running " +
- "or otherwise unavailable.",
- recommendation=LogMessageDoc.CHECK_CONTROLLER)
- public boolean connectToPSServer() {
- int numRetries = 0;
- if (transport != null && transport.isOpen()) {
- return true;
- }
-
- while (numRetries++ < MaxRetry) {
- try {
- transport = new TFramedTransport(new TSocket("localhost",
- serverPort));
- transport.open();
-
- TProtocol protocol = new TBinaryProtocol(transport);
- packetClient = new PacketStreamer.Client(protocol);
-
- log.debug("Have a connection to packetstreamer server " +
- "localhost:{}", serverPort);
- break;
- } catch (TException x) {
- try {
- // Wait for 1 second before retry
- if (numRetries < MaxRetry) {
- Thread.sleep(1000);
- }
- } catch (Exception e) {}
- }
- }
-
- if (numRetries > MaxRetry) {
- log.error("Failed to establish connection with the " +
- "packetstreamer server.");
- return false;
- }
- return true;
- }
-
- public void disconnectFromPSServer() {
- if (transport != null && transport.isOpen()) {
- log.debug("Close the connection to packetstreamer server" +
- " localhost:{}", serverPort);
- transport.close();
- }
- }
-
- @Override
- public String getName() {
- return "messageFilterManager";
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return (type == OFType.PACKET_IN && name.equals("devicemanager"));
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return (type == OFType.PACKET_IN && name.equals("learningswitch"));
- }
-
- @Override
- @LogMessageDoc(level="ERROR",
- message="Error while sending packet",
- explanation="Failed to send a message to the message " +
- "tracing server",
- recommendation=LogMessageDoc.CHECK_CONTROLLER)
- public Command receive(IOFSwitch sw, OFMessage msg,
- FloodlightContext cntx) {
-
- if (filterMap == null || filterMap.isEmpty()) return Command.CONTINUE;
-
- HashSet<String> matchedFilters = null;
- if (log.isDebugEnabled()) {
- log.debug("Received packet {} from switch {}",
- msg, sw.getStringId());
- }
-
- matchedFilters = getMatchedFilters(msg, cntx);
- if (matchedFilters == null) {
- return Command.CONTINUE;
- } else {
- try {
- sendPacket(matchedFilters, sw, msg, cntx, true);
- } catch (Exception e) {
- log.error("Error while sending packet", e);
- }
- }
-
- return Command.CONTINUE;
- }
-
-
- public class TimeoutFilterTask extends TimerTask {
-
- OFMessageFilterManager filterManager;
- ScheduledExecutorService ses = threadPool.getScheduledExecutor();
-
- public TimeoutFilterTask(OFMessageFilterManager manager) {
- filterManager = manager;
- }
-
- public void run() {
- int x = filterManager.timeoutFilters();
-
- if (x > 0) { // there's at least one filter still active.
- Timer timer = new Timer();
- timer.schedule(new TimeoutFilterTask(filterManager),
- TIMER_INTERVAL);
- } else {
- // Don't stop the listener to avoid race condition
- //stopListening();
- }
- }
- }
-
- public int getNumberOfFilters() {
- return filterMap.size();
- }
-
- public int getMaxFilterSize() {
- return MAX_FILTERS;
- }
-
- protected void sendPacket(HashSet<String> matchedFilters, IOFSwitch sw,
- OFMessage msg, FloodlightContext cntx, boolean sync)
- throws TException {
- Message sendMsg = new Message();
- Packet packet = new Packet();
- ChannelBuffer bb;
- sendMsg.setPacket(packet);
-
- List<String> sids = new ArrayList<String>(matchedFilters);
-
- sendMsg.setSessionIDs(sids);
- packet.setMessageType(OFMessageType.findByValue((msg.getType().ordinal())));
-
- switch (msg.getType()) {
- case PACKET_IN:
- OFPacketIn pktIn = (OFPacketIn)msg;
- packet.setSwPortTuple(new SwitchPortTuple(sw.getId(),
- pktIn.getInPort()));
- bb = ChannelBuffers.buffer(pktIn.getLength());
- pktIn.writeTo(bb);
- packet.setData(OFMessage.getData(sw, msg, cntx));
- break;
- case PACKET_OUT:
- OFPacketOut pktOut = (OFPacketOut)msg;
- packet.setSwPortTuple(new SwitchPortTuple(sw.getId(),
- pktOut.getInPort()));
- bb = ChannelBuffers.buffer(pktOut.getLength());
- pktOut.writeTo(bb);
- packet.setData(OFMessage.getData(sw, msg, cntx));
- break;
- case FLOW_MOD:
- OFFlowMod offlowMod = (OFFlowMod)msg;
- packet.setSwPortTuple(new SwitchPortTuple(sw.getId(),
- offlowMod.
- getOutPort()));
- bb = ChannelBuffers.buffer(offlowMod.getLength());
- offlowMod.writeTo(bb);
- packet.setData(OFMessage.getData(sw, msg, cntx));
- break;
- default:
- packet.setSwPortTuple(new SwitchPortTuple(sw.getId(),
- (short)0));
- String strData = "Unknown packet";
- packet.setData(strData.getBytes());
- break;
- }
-
- try {
- if (transport == null ||
- !transport.isOpen() ||
- packetClient == null) {
- if (!connectToPSServer()) {
- // No need to sendPacket if can't make connection to
- // the server
- return;
- }
- }
- if (sync) {
- log.debug("Send packet sync: {}", packet.toString());
- packetClient.pushMessageSync(sendMsg);
- } else {
- log.debug("Send packet sync: ", packet.toString());
- packetClient.pushMessageAsync(sendMsg);
- }
- } catch (Exception e) {
- log.error("Error while sending packet", e);
- disconnectFromPSServer();
- connectToPSServer();
- }
- }
-
- // IFloodlightModule methods
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IOFMessageFilterManagerService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- // We are the class that implements the service
- m.put(IOFMessageFilterManagerService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(IThreadPoolService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- this.floodlightProvider =
- context.getServiceImpl(IFloodlightProviderService.class);
- this.threadPool =
- context.getServiceImpl(IThreadPoolService.class);
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- // This is our 'constructor'
-
- filterMap = new ConcurrentHashMap<String, ConcurrentHashMap<String,String>>();
- filterTimeoutMap = new ConcurrentHashMap<String, Long>();
- serverPort =
- Integer.parseInt(System.getProperty("net.floodlightcontroller." +
- "packetstreamer.port", "9090"));
-
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- floodlightProvider.addOFMessageListener(OFType.PACKET_OUT, this);
- floodlightProvider.addOFMessageListener(OFType.FLOW_MOD, this);
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 0d49c03..ac29983 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -54,20 +54,16 @@
import net.floodlightcontroller.core.IHAListener;
import net.floodlightcontroller.core.IInfoProvider;
import net.floodlightcontroller.core.IListener.Command;
-import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitchFilter;
import net.floodlightcontroller.core.IOFSwitchListener;
-import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
import net.floodlightcontroller.core.annotations.LogMessageDoc;
import net.floodlightcontroller.core.annotations.LogMessageDocs;
import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState;
import net.floodlightcontroller.core.util.ListenerDispatcher;
import net.floodlightcontroller.core.web.CoreWebRoutable;
import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.flowcache.IFlowService;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
import net.floodlightcontroller.restserver.IRestApiService;
@@ -77,6 +73,8 @@
import net.floodlightcontroller.storage.OperatorPredicate;
import net.floodlightcontroller.storage.StorageException;
import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
import net.onrc.onos.registry.controller.IControllerRegistryService;
import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
import net.onrc.onos.registry.controller.RegistryException;
@@ -140,15 +138,20 @@
import org.slf4j.LoggerFactory;
-
/**
* The main controller class. Handles all setup and network listeners
+ *
+ * Extensions made by ONOS are:
+ * - Detailed Port event: PORTCHANGED -> {PORTCHANGED, PORTADDED, PORTREMOVED}
+ * Available as net.onrc.onos.ofcontroller.core.IOFSwitchPortListener
+ * - Distributed ownership control of switch through RegistryService(IControllerRegistryService)
+ * - Register ONOS services. (IFlowService, IControllerRegistryService)
+ * - Additional DEBUG logs
+ * - Try using hostname as controller ID, when ID was not explicitly given.
*/
public class Controller implements IFloodlightProviderService,
IStorageSourceListener {
-
- protected SwitchStorageImpl swStore;;
-
+
protected static Logger log = LoggerFactory.getLogger(Controller.class);
private static final String ERROR_DATABASE =
@@ -185,7 +188,6 @@
protected IPktInProcessingTimeService pktinProcTime;
protected IThreadPoolService threadPool;
protected IFlowService flowService;
- protected ITopoRouteService topoRouteService;
protected IControllerRegistryService registryService;
// Configuration options
@@ -265,18 +267,27 @@
public enum SwitchUpdateType {
ADDED,
REMOVED,
- PORTCHANGED
+ PORTCHANGED,
+ PORTADDED,
+ PORTREMOVED
}
/**
* Update message indicating a switch was added or removed
+ * ONOS: This message extended to indicate Port add or removed event.
*/
protected class SwitchUpdate implements IUpdate {
public IOFSwitch sw;
+ public OFPhysicalPort port; // Added by ONOS
public SwitchUpdateType switchUpdateType;
public SwitchUpdate(IOFSwitch sw, SwitchUpdateType switchUpdateType) {
this.sw = sw;
this.switchUpdateType = switchUpdateType;
}
+ public SwitchUpdate(IOFSwitch sw, OFPhysicalPort port, SwitchUpdateType switchUpdateType) {
+ this.sw = sw;
+ this.port = port;
+ this.switchUpdateType = switchUpdateType;
+ }
public void dispatch() {
if (log.isTraceEnabled()) {
log.trace("Dispatching switch update {} {}",
@@ -294,6 +305,18 @@
case PORTCHANGED:
listener.switchPortChanged(sw.getId());
break;
+ case PORTADDED:
+ if (listener instanceof IOFSwitchPortListener) {
+ ((IOFSwitchPortListener) listener).switchPortAdded(sw.getId(), port);
+ }
+ break;
+ case PORTREMOVED:
+ if (listener instanceof IOFSwitchPortListener) {
+ ((IOFSwitchPortListener) listener).switchPortRemoved(sw.getId(), port);
+ }
+ break;
+ default:
+ break;
}
}
}
@@ -393,10 +416,6 @@
this.flowService = serviceImpl;
}
- public void setTopoRouteService(ITopoRouteService serviceImpl) {
- this.topoRouteService = serviceImpl;
- }
-
public void setMastershipService(IControllerRegistryService serviceImpl) {
this.registryService = serviceImpl;
}
@@ -789,10 +808,9 @@
dfuture);
}
-
+
volatile Boolean controlRequested = Boolean.FALSE;
protected void checkSwitchReady() {
-
if (state.hsState == HandshakeState.FEATURES_REPLY &&
state.hasDescription && state.hasGetConfigReply) {
@@ -1128,7 +1146,7 @@
}
state.firstRoleReplyReceived = true;
Role requestedRole =
- sw.deliverRoleRequestNotSupported(error.getXid());
+ sw.deliverRoleRequestNotSupportedEx(error.getXid());
synchronized(roleChanger) {
if (sw.role == null && Controller.this.role==Role.SLAVE) {
//This will now never happen. The Controller's role
@@ -1269,23 +1287,43 @@
((OFPortState.OFPPS_LINK_DOWN.getValue() & port.getState()) > 0);
sw.setPort(port);
if (!portDown) {
- swStore.addPort(sw.getStringId(), port);
+ SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTADDED);
+ try {
+ this.updates.put(update);
+ } catch (InterruptedException e) {
+ log.error("Failure adding update to queue", e);
+ }
} else {
- swStore.deletePort(sw.getStringId(), port.getPortNumber());
+ SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTREMOVED);
+ try {
+ this.updates.put(update);
+ } catch (InterruptedException e) {
+ log.error("Failure adding update to queue", e);
+ }
}
if (updateStorage)
updatePortInfo(sw, port);
log.debug("Port #{} modified for {}", portNumber, sw);
} else if (m.getReason() == (byte)OFPortReason.OFPPR_ADD.ordinal()) {
sw.setPort(port);
- swStore.addPort(sw.getStringId(), port);
+ SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTADDED);
+ try {
+ this.updates.put(update);
+ } catch (InterruptedException e) {
+ log.error("Failure adding update to queue", e);
+ }
if (updateStorage)
updatePortInfo(sw, port);
log.debug("Port #{} added for {}", portNumber, sw);
} else if (m.getReason() ==
(byte)OFPortReason.OFPPR_DELETE.ordinal()) {
sw.deletePort(portNumber);
- swStore.deletePort(sw.getStringId(), portNumber);
+ SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTREMOVED);
+ try {
+ this.updates.put(update);
+ } catch (InterruptedException e) {
+ log.error("Failure adding update to queue", e);
+ }
if (updateStorage)
removePortInfo(sw, portNumber);
log.debug("Port #{} deleted for {}", portNumber, sw);
@@ -1559,12 +1597,6 @@
}
updateActiveSwitchInfo(sw);
- if (registryService.hasControl(sw.getId())) {
- swStore.update(sw.getStringId(), SwitchState.ACTIVE, DM_OPERATION.UPDATE);
- for (OFPhysicalPort port: sw.getPorts()) {
- swStore.addPort(sw.getStringId(), port);
- }
- }
SwitchUpdate update = new SwitchUpdate(sw, SwitchUpdateType.ADDED);
try {
this.updates.put(update);
@@ -1584,14 +1616,6 @@
// this method is only called after netty has processed all
// pending messages
log.debug("removeSwitch: {}", sw);
- //
- // Cannot set sw to inactive in network map due to race condition
- // Need a cleanup thread to periodically check switches not active in registry
- // and acquire control to set to inactive state in network map and release it
- //
- // if (registryService.hasControl(sw.getId())) {
- // swStore.update(sw.getStringId(), SwitchState.INACTIVE, DM_OPERATION.UPDATE);
- // }
if (!this.activeSwitches.remove(sw.getId(), sw) || !sw.isConnected()) {
log.debug("Not removing switch {}; already removed", sw);
return;
@@ -1601,7 +1625,6 @@
// from slave controllers. Then we need to move this cancelation
// to switch disconnect
sw.cancelAllStatisticsReplies();
-
// FIXME: I think there's a race condition if we call updateInactiveSwitchInfo
// here if role support is enabled. In that case if the switch is being
@@ -1613,7 +1636,6 @@
// of the switch state that's written to storage.
updateInactiveSwitchInfo(sw);
-
SwitchUpdate update = new SwitchUpdate(sw, SwitchUpdateType.REMOVED);
try {
this.updates.put(update);
@@ -2207,22 +2229,11 @@
this.updates = new LinkedBlockingQueue<IUpdate>();
this.factory = new BasicFactory();
this.providerMap = new HashMap<String, List<IInfoProvider>>();
-
setConfigParams(configParams);
//this.role = getInitialRole(configParams);
//Set the controller's role to MASTER so it always tries to do role requests.
this.role = Role.MASTER;
this.roleChanger = new RoleChanger();
-
- String conf = configParams.get("dbconf");
- if (conf == null || conf.isEmpty()) {
- conf = "/tmp/cassandra.titan";
- log.debug("did not get DB config setting using default {}", conf);
- }
- log.debug("setting DB config {}", conf);
- this.swStore = new SwitchStorageImpl();
- this.swStore.init(conf);
-
initVendorMessages();
this.systemStartTime = System.currentTimeMillis();
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
index e0ff8c3..467c74a 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
@@ -44,6 +44,7 @@
import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.util.TimedCache;
+import net.onrc.onos.ofcontroller.core.IOnosRemoteSwitch;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -75,7 +76,7 @@
/**
* This is the internal representation of an openflow switch.
*/
-public class OFSwitchImpl implements IOFSwitch {
+public class OFSwitchImpl implements IOFSwitch, IOnosRemoteSwitch {
// TODO: should we really do logging in the class or should we throw
// exception that can then be handled by callers?
protected static Logger log = LoggerFactory.getLogger(OFSwitchImpl.class);
@@ -268,7 +269,7 @@
public void disconnectOutputStream() {
channel.close();
}
-
+
@Override
@JsonIgnore
public void setFeaturesReply(OFFeaturesReply featuresReply) {
@@ -401,7 +402,7 @@
*/
@Override
public String toString() {
- return "OFSwitchImpl [" + channel.getRemoteAddress() + " DPID[" + ((stringId != null) ? stringId : "?") + "]]";
+ return "OFSwitchImpl [" + ((channel != null) ? channel.getRemoteAddress() : "?") + " DPID[" + ((stringId != null) ? stringId : "?") + "]]";
}
@Override
@@ -787,7 +788,18 @@
* Otherwise we ignore it.
* @param xid
*/
- protected Role deliverRoleRequestNotSupported(int xid) {
+ protected void deliverRoleRequestNotSupported(int xid) {
+ deliverRoleRequestNotSupportedEx(xid);
+ }
+
+ /**
+ * ONOS Extension to deliverRoleRequestNotSupported().
+ * This version return the Roll request made.
+ * @see deliverRoleRequestNotSupported
+ * @param xid
+ * @return Role of attempted RoleRequest.
+ */
+ protected Role deliverRoleRequestNotSupportedEx(int xid) {
synchronized(pendingRoleRequests) {
PendingRoleRequestEntry head = pendingRoleRequests.poll();
this.role = null;
diff --git a/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java b/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
index b2de649..4924fbc 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
@@ -277,8 +277,9 @@
// Handle cases #1 and #2
log.debug("Sending NxRoleRequest to {}", sw);
sw.sendNxRoleRequest(role, cookie);
- } else {
+ } else {
if (role == Role.MASTER) {
+ // ONOS extension:
log.debug("Switch {} doesn't support NxRoleRequests, but sending " +
"{} request anyway", sw, role);
//Send the role request anyway, even though we know the switch
diff --git a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
deleted file mode 100644
index b8197b7..0000000
--- a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
+++ /dev/null
@@ -1,228 +0,0 @@
-package net.floodlightcontroller.core.internal;
-
-import java.util.Collection;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.ISwitchStorage;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.GraphDBConnection.GenerateEvent;
-import net.onrc.onos.util.GraphDBConnection.Transaction;
-
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
-import org.openflow.protocol.OFPhysicalPort.OFPortState;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SwitchStorageImpl implements ISwitchStorage {
- protected GraphDBConnection conn;
- protected static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
- @Override
- public void update(String dpid, SwitchState state, DM_OPERATION op) {
- // TODO Auto-generated method stub
- log.info("SwitchStorage:update dpid:{} state: {} ", dpid, state);
- switch(op) {
-
- case UPDATE:
- case INSERT:
- case CREATE:
- addSwitch(dpid);
- if (state != SwitchState.ACTIVE) {
- setStatus(dpid, state);
- }
- break;
- case DELETE:
- deleteSwitch(dpid);
- break;
- default:
- }
- }
-
- private void setStatus(String dpid, SwitchState state) {
- ISwitchObject sw = conn.utils().searchSwitch(conn, dpid);
- if (sw != null) {
- sw.setState(state.toString());
- conn.endTx(Transaction.COMMIT);
- log.info("SwitchStorage:setStatus dpid:{} state: {} done", dpid, state);
- } else {
- conn.endTx(Transaction.ROLLBACK);
- log.info("SwitchStorage:setStatus dpid:{} state: {} failed: switch not found", dpid, state);
- }
- }
-
- @Override
- public void addPort(String dpid, OFPhysicalPort port) {
- // TODO Auto-generated method stub
-
- boolean portDown = ((OFPortConfig.OFPPC_PORT_DOWN.getValue() & port.getConfig()) > 0) ||
- ((OFPortState.OFPPS_LINK_DOWN.getValue() & port.getState()) > 0);
- if (portDown) {
- deletePort(dpid, port.getPortNumber());
- return;
- }
-
- try {
- ISwitchObject sw = conn.utils().searchSwitch(conn, dpid);
-
- if (sw != null) {
- IPortObject p = conn.utils().searchPort(conn, dpid, port.getPortNumber());
- log.info("SwitchStorage:addPort dpid:{} port:{}", dpid, port.getPortNumber());
- if (p != null) {
- log.error("SwitchStorage:addPort dpid:{} port:{} exists", dpid, port.getPortNumber());
- } else {
- p = conn.utils().newPort(conn);
-
- p.setType("port");
- p.setNumber(port.getPortNumber());
- p.setState("ACTIVE");
- p.setPortState(port.getState());
- p.setDesc(port.getName());
- sw.addPort(p);
- conn.endTx(Transaction.COMMIT);
-
- }
- } else {
- log.error("SwitchStorage:addPort dpid:{} port:{} : failed switch does not exist", dpid, port.getPortNumber());
- }
- } catch (Exception e) {
- // TODO: handle exceptions
- e.printStackTrace();
- conn.endTx(Transaction.ROLLBACK);
- log.error("SwitchStorage:addPort dpid:{} port:{} failed", dpid, port.getPortNumber());
- }
-
- }
-
- @Override
- public Collection<OFPhysicalPort> getPorts(long dpid) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public OFPhysicalPort getPort(String dpid, short portnum) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public OFPhysicalPort getPort(String dpid, String portName) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public void addSwitch(String dpid) {
-
- log.info("SwitchStorage:addSwitch(): dpid {} ", dpid);
-
- try {
- ISwitchObject sw = conn.utils().searchSwitch(conn, dpid);
- if (sw != null) {
- /*
- * Do nothing or throw exception?
- */
-
- log.info("SwitchStorage:addSwitch dpid:{} already exists", dpid);
- sw.setState(SwitchState.ACTIVE.toString());
- conn.endTx(Transaction.COMMIT);
- } else {
- sw = conn.utils().newSwitch(conn);
-
- if (sw != null) {
- sw.setType("switch");
- sw.setDPID(dpid);
- sw.setState(SwitchState.ACTIVE.toString());
- conn.endTx(Transaction.COMMIT);
- log.info("SwitchStorage:addSwitch dpid:{} added", dpid);
- } else {
- log.error("switchStorage:addSwitch dpid:{} failed -> newSwitch failed", dpid);
- }
- }
- } catch (Exception e) {
- /*
- * retry?
- */
- e.printStackTrace();
- conn.endTx(Transaction.ROLLBACK);
- log.info("SwitchStorage:addSwitch dpid:{} failed", dpid);
- }
-
-
- }
-
- @Override
- public void deleteSwitch(String dpid) {
- // TODO Setting inactive but we need to eventually remove data
-
- try {
-
- ISwitchObject sw = conn.utils().searchSwitch(conn, dpid);
- if (sw != null) {
- conn.utils().removeSwitch(conn, sw);
-
- conn.endTx(Transaction.COMMIT);
- log.info("SwitchStorage:DeleteSwitch dpid:{} done", dpid);
- }
- } catch (Exception e) {
- // TODO: handle exceptions
- e.printStackTrace();
- conn.endTx(Transaction.ROLLBACK);
- log.error("SwitchStorage:deleteSwitch {} failed", dpid);
- }
-
- }
-
- @Override
- public void deletePort(String dpid, short port) {
- // TODO Auto-generated method stub
- try {
- ISwitchObject sw = conn.utils().searchSwitch(conn, dpid);
-
- if (sw != null) {
- IPortObject p = conn.utils().searchPort(conn, dpid, port);
- if (p != null) {
- log.info("SwitchStorage:deletePort dpid:{} port:{} found and deleted", dpid, port);
- sw.removePort(p);
- conn.utils().removePort(conn, p);
- conn.endTx(Transaction.COMMIT);
- }
- }
- } catch (Exception e) {
- // TODO: handle exceptions
- e.printStackTrace();
- conn.endTx(Transaction.ROLLBACK);
- log.info("SwitchStorage:deletePort dpid:{} port:{} failed", dpid, port);
- }
- }
-
- @Override
- public void deletePort(String dpid, String portName) {
- // TODO Auto-generated method stub
-
- }
-
-
-
- @Override
- public void init(String conf) {
-
- conn = GraphDBConnection.getInstance(conf);
-
- }
-
-
-
- public void finalize() {
- close();
- }
-
- @Override
- public void close() {
- conn.close();
- }
-
-
-}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
deleted file mode 100644
index 502fad6..0000000
--- a/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package net.floodlightcontroller.core.internal;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoSwitchService;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.GraphDBConnection.Transaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopoSwitchServiceImpl implements ITopoSwitchService {
-
- private GraphDBConnection conn;
- protected static Logger log = LoggerFactory.getLogger(TopoSwitchServiceImpl.class);
-
-
- public void finalize() {
- close();
- }
-
- @Override
- public void close() {
-
- conn.close();
- }
-
- @Override
- public Iterable<ISwitchObject> getActiveSwitches() {
- // TODO Auto-generated method stub
- conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
- conn.close(); //Commit to ensure we see latest data
- return conn.utils().getActiveSwitches(conn);
- }
-
- @Override
- public Iterable<ISwitchObject> getAllSwitches() {
- // TODO Auto-generated method stub
- conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
- conn.close(); //Commit to ensure we see latest data
- return conn.utils().getAllSwitches(conn);
- }
-
- @Override
- public Iterable<ISwitchObject> getInactiveSwitches() {
- // TODO Auto-generated method stub
- conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
- conn.close(); //Commit to ensure we see latest data
- return conn.utils().getInactiveSwitches(conn);
- }
-
- @Override
- public Iterable<IPortObject> getPortsOnSwitch(String dpid) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public IPortObject getPortOnSwitch(String dpid, short port_num) {
- // TODO Auto-generated method stub
- return null;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index 2bb39ef..7604d7c 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -18,9 +18,11 @@
package net.floodlightcontroller.core.web;
import net.floodlightcontroller.core.module.ModuleLoaderResource;
-import net.floodlightcontroller.linkdiscovery.web.TopoLinksResource;
-import net.floodlightcontroller.devicemanager.web.TopoDevicesResource;
import net.floodlightcontroller.restserver.RestletRoutable;
+import net.onrc.onos.ofcontroller.core.web.ClearFlowTableResource;
+import net.onrc.onos.ofcontroller.core.web.TopoLinksResource;
+import net.onrc.onos.ofcontroller.core.web.TopoSwitchesResource;
+import net.onrc.onos.ofcontroller.devicemanager.web.TopoDevicesResource;
import org.restlet.Context;
import org.restlet.Restlet;
@@ -49,7 +51,6 @@
router.attach("/counter/{switchId}/{counterName}/json", SwitchCounterResource.class);
router.attach("/counter/categories/{switchId}/{counterName}/{layer}/json", SwitchCounterCategoriesResource.class);
router.attach("/memory/json", ControllerMemoryResource.class);
- router.attach("/packettrace/json", PacketTraceResource.class);
// Get the last {count} events from the event histories
router.attach("/event-history/topology-switch/{count}/json",
EventHistoryTopologySwitchResource.class);
@@ -62,6 +63,7 @@
router.attach("/role/json", ControllerRoleResource.class);
router.attach("/health/json", HealthCheckResource.class);
router.attach("/system/uptime/json", SystemUptimeResource.class);
+ // Following added by ONOS
router.attach("/topology/switches/{filter}/json", TopoSwitchesResource.class);
router.attach("/topology/links/json", TopoLinksResource.class);
router.attach("/topology/devices/json", TopoDevicesResource.class);
diff --git a/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologyClusterResource.java b/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologyClusterResource.java
index 1be942c..648866f 100644
--- a/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologyClusterResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologyClusterResource.java
@@ -1,9 +1,9 @@
package net.floodlightcontroller.core.web;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.floodlightcontroller.linkdiscovery.internal.EventHistoryTopologyCluster;
-import net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager;
import net.floodlightcontroller.util.EventHistory;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.internal.EventHistoryTopologyCluster;
+import net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologyLinkResource.java b/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologyLinkResource.java
index 4a21070..79c4006 100644
--- a/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologyLinkResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologyLinkResource.java
@@ -1,9 +1,9 @@
package net.floodlightcontroller.core.web;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.floodlightcontroller.linkdiscovery.internal.EventHistoryTopologyLink;
-import net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager;
import net.floodlightcontroller.util.EventHistory;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.internal.EventHistoryTopologyLink;
+import net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologySwitchResource.java b/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologySwitchResource.java
index 1c95e2c..4a81db4 100644
--- a/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologySwitchResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/EventHistoryTopologySwitchResource.java
@@ -1,9 +1,9 @@
package net.floodlightcontroller.core.web;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.floodlightcontroller.linkdiscovery.internal.EventHistoryTopologySwitch;
-import net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager;
import net.floodlightcontroller.util.EventHistory;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.internal.EventHistoryTopologySwitch;
+import net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java b/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java
deleted file mode 100644
index 85da942..0000000
--- a/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package net.floodlightcontroller.core.web;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.restlet.data.Status;
-import org.restlet.resource.Post;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.OFMessageFilterManager;
-
-public class PacketTraceResource extends ServerResource {
- protected static Logger log = LoggerFactory.getLogger(PacketTraceResource.class);
-
- public static class FilterParameters {
-
- protected String sessionId = null;
- protected String mac = null;
- protected Integer period = null;
- protected String direction = null;
- protected String output = null;
-
- public String getSessionId() {
- return sessionId;
- }
- public void setSessionId(String sessionId) {
- this.sessionId = sessionId;
- }
- public String getMac() {
- return mac;
- }
- public void setMac(String mac) {
- this.mac = mac;
- }
- public Integer getPeriod() {
- return period;
- }
- public void setPeriod(Integer period) {
- this.period = period;
- }
- public String getDirection() {
- return direction;
- }
- public void setDirection(String direction) {
- this.direction = direction;
- }
- public String getOutput() {
- return output;
- }
- public void setOutput(String output) {
- this.output = output;
- }
-
- public String toString() {
- return "SessionID: " + sessionId +
- "\tmac" + mac +
- "\tperiod" + period +
- "\tdirection" + direction +
- "\toutput" + output;
- }
- }
-
- public static class PacketTraceOutput {
- protected String sessionId = null;
-
- public String getSessionId() {
- return sessionId;
- }
-
- public void setSessionId(String sessionId) {
- this.sessionId = sessionId;
- }
- }
-
- @Post("json")
- public PacketTraceOutput packettrace(FilterParameters fp) {
-
- ConcurrentHashMap <String,String> filter = new ConcurrentHashMap<String,String> ();
- String sid = null;
- PacketTraceOutput output = new PacketTraceOutput();
- OFMessageFilterManager manager =
- (OFMessageFilterManager)getContext()
- .getAttributes().
- get(OFMessageFilterManager.class.getCanonicalName());
-
- if (manager == null) {
- sid = null;
- setStatus(Status.SERVER_ERROR_SERVICE_UNAVAILABLE);
- }
-
- if (fp.getSessionId() != null) {
- filter.put("sessionId", fp.getSessionId());
- }
- if (fp.getMac() != null) {
- filter.put("mac", fp.getMac());
- }
- if (fp.getDirection() != null) {
- filter.put("direction", fp.getDirection());
- }
-
- if (filter.isEmpty()) {
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
- } else {
- if (log.isDebugEnabled()) {
- log.debug ("Call setupFilter: sid:{} filter:{}, period:{}",
- new Object[] {fp.getSessionId(), filter,
- fp.getPeriod()*1000});
- }
- sid = manager.setupFilter(fp.getSessionId(), filter,
- fp.getPeriod()*1000);
- output.setSessionId(sid);
- setStatus(Status.SUCCESS_OK);
- }
-
- return output;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index feccdc4..04543ac 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -59,7 +59,6 @@
import net.floodlightcontroller.flowcache.IFlowReconcileListener;
import net.floodlightcontroller.flowcache.IFlowReconcileService;
import net.floodlightcontroller.flowcache.OFMatchReconcile;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
import net.floodlightcontroller.packet.ARP;
import net.floodlightcontroller.packet.DHCP;
import net.floodlightcontroller.packet.Ethernet;
@@ -71,6 +70,7 @@
import net.floodlightcontroller.topology.ITopologyListener;
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.util.MultiIterator;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
import static net.floodlightcontroller.devicemanager.internal.
DeviceManagerImpl.DeviceUpdate.Change.*;
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceStorageImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceStorageImpl.java
deleted file mode 100644
index e964b8e..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceStorageImpl.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package net.floodlightcontroller.devicemanager.internal;
-
-import java.util.List;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Lists;
-import com.thinkaurelius.titan.core.TitanException;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.internal.SwitchStorageImpl;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceStorage;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.GraphDBConnection.Transaction;
-
-public class DeviceStorageImpl implements IDeviceStorage {
-
- public GraphDBConnection conn;
- protected static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
- @Override
- public void init(String conf) {
- conn = GraphDBConnection.getInstance(conf);
- }
-
- public void finalize() {
- close();
- }
-
- @Override
- public void close() {
- conn.close();
- }
-
- @Override
- public IDeviceObject addDevice(IDevice device) {
- // TODO Auto-generated method stub
- IDeviceObject obj = null;
- try {
- if ((obj = conn.utils().searchDevice(conn, device.getMACAddressString())) != null) {
- log.debug("Adding device {}: found existing device",device.getMACAddressString());
- } else {
- obj = conn.utils().newDevice(conn);
- log.debug("Adding device {}: creating new device",device.getMACAddressString());
- }
- changeDeviceAttachments(device, obj);
-
- obj.setIPAddress(device.getIPv4Addresses().toString());
- obj.setMACAddress(device.getMACAddressString());
- obj.setType("device");
- obj.setState("ACTIVE");
- conn.endTx(Transaction.COMMIT);
-
- log.debug("Adding device {}",device.getMACAddressString());
- } catch (Exception e) {
- // TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
- log.error(":addDevice mac:{} failed", device.getMACAddressString());
- }
-
- return obj;
- }
-
- @Override
- public IDeviceObject updateDevice(IDevice device) {
- return addDevice(device);
- }
-
- @Override
- public void removeDevice(IDevice device) {
- // TODO Auto-generated method stub
- IDeviceObject dev;
- try {
- if ((dev = conn.utils().searchDevice(conn, device.getMACAddressString())) != null) {
- conn.utils().removeDevice(conn, dev);
- conn.endTx(Transaction.COMMIT);
- log.error("DeviceStorage:removeDevice mac:{} done", device.getMACAddressString());
- }
- } catch (Exception e) {
- // TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
- log.error("DeviceStorage:removeDevice mac:{} failed", device.getMACAddressString());
- }
- }
-
- @Override
- public IDeviceObject getDeviceByMac(String mac) {
- return conn.utils().searchDevice(conn, mac);
- }
-
- @Override
- public IDeviceObject getDeviceByIP(String ip) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public void changeDeviceAttachments(IDevice device) {
- // TODO Auto-generated method stub
- IDeviceObject obj = null;
- try {
- if ((obj = conn.utils().searchDevice(conn, device.getMACAddressString())) != null) {
- log.debug("Changing device ports {}: found existing device",device.getMACAddressString());
- changeDeviceAttachments(device, obj);
- conn.endTx(Transaction.COMMIT);
- } else {
- log.debug("failed to search device...now adding {}",device.getMACAddressString());
- addDevice(device);
- }
- } catch (Exception e) {
- // TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
- log.error(":addDevice mac:{} failed", device.getMACAddressString());
- }
- }
-
- public void changeDeviceAttachments(IDevice device, IDeviceObject obj) {
- SwitchPort[] attachmentPoints = device.getAttachmentPoints();
- List<IPortObject> attachedPorts = Lists.newArrayList(obj.getAttachedPorts());
-
- for (SwitchPort ap : attachmentPoints) {
- IPortObject port = conn.utils().searchPort(conn,
- HexString.toHexString(ap.getSwitchDPID()),
- (short) ap.getPort());
- if (attachedPorts.contains(port)) {
- attachedPorts.remove(port);
- } else {
- log.debug("Adding device {}: attaching to port",device.getMACAddressString());
- port.setDevice(obj);
- //obj.setHostPort(port);
- }
- }
- for (IPortObject port: attachedPorts) {
- port.removeDevice(obj);
- // obj.removeHostPort(port);
- }
- }
-
- @Override
- public void changeDeviceIPv4Address(IDevice device) {
- // TODO Auto-generated method stub
- IDeviceObject obj;
- try {
- if ((obj = conn.utils().searchDevice(conn, device.getMACAddressString())) != null) {
- obj.setIPAddress(device.getIPv4Addresses().toString());
- conn.endTx(Transaction.COMMIT);
- } else {
- log.error(":changeDeviceIPv4Address mac:{} failed", device.getMACAddressString());
- }
- } catch (TitanException e) {
- // TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
- log.error(":changeDeviceIPv4Address mac:{} failed due to exception {}", device.getMACAddressString(),e);
- }
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/TopoDevicesResource.java b/src/main/java/net/floodlightcontroller/devicemanager/web/TopoDevicesResource.java
deleted file mode 100644
index db7059f..0000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/web/TopoDevicesResource.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package net.floodlightcontroller.devicemanager.web;
-
-import java.util.Iterator;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.onrc.onos.util.GraphDBConnection;
-
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-
-public class TopoDevicesResource extends ServerResource {
-
- @Get("json")
- public Iterator<IDeviceObject> retrieve() {
-
- GraphDBConnection conn = GraphDBConnection.getInstance("");
-
- return conn.utils().getDevices(conn).iterator();
-
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/Firewall.java b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
deleted file mode 100644
index 3f8ff6c..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/Firewall.java
+++ /dev/null
@@ -1,667 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-
-import java.util.ArrayList;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.IRoutingDecision;
-import net.floodlightcontroller.routing.RoutingDecision;
-import net.floodlightcontroller.storage.IResultSet;
-import net.floodlightcontroller.storage.IStorageSourceService;
-import net.floodlightcontroller.storage.StorageException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Stateless firewall implemented as a Google Summer of Code project.
- * Configuration done through REST API
- *
- * @author Amer Tahir
- * @edited KC Wang
- */
-public class Firewall implements IFirewallService, IOFMessageListener,
- IFloodlightModule {
-
- // service modules needed
- protected IFloodlightProviderService floodlightProvider;
- protected IStorageSourceService storageSource;
- protected IRestApiService restApi;
- protected static Logger logger;
-
- protected List<FirewallRule> rules; // protected by synchronized
- protected boolean enabled;
- protected int subnet_mask = IPv4.toIPv4Address("255.255.255.0");
-
- // constant strings for storage/parsing
- public static final String TABLE_NAME = "controller_firewallrules";
- public static final String COLUMN_RULEID = "ruleid";
- public static final String COLUMN_DPID = "dpid";
- public static final String COLUMN_IN_PORT = "in_port";
- public static final String COLUMN_DL_SRC = "dl_src";
- public static final String COLUMN_DL_DST = "dl_dst";
- public static final String COLUMN_DL_TYPE = "dl_type";
- public static final String COLUMN_NW_SRC_PREFIX = "nw_src_prefix";
- public static final String COLUMN_NW_SRC_MASKBITS = "nw_src_maskbits";
- public static final String COLUMN_NW_DST_PREFIX = "nw_dst_prefix";
- public static final String COLUMN_NW_DST_MASKBITS = "nw_dst_maskbits";
- public static final String COLUMN_NW_PROTO = "nw_proto";
- public static final String COLUMN_TP_SRC = "tp_src";
- public static final String COLUMN_TP_DST = "tp_dst";
- public static final String COLUMN_WILDCARD_DPID = "wildcard_dpid";
- public static final String COLUMN_WILDCARD_IN_PORT = "wildcard_in_port";
- public static final String COLUMN_WILDCARD_DL_SRC = "wildcard_dl_src";
- public static final String COLUMN_WILDCARD_DL_DST = "wildcard_dl_dst";
- public static final String COLUMN_WILDCARD_DL_TYPE = "wildcard_dl_type";
- public static final String COLUMN_WILDCARD_NW_SRC = "wildcard_nw_src";
- public static final String COLUMN_WILDCARD_NW_DST = "wildcard_nw_dst";
- public static final String COLUMN_WILDCARD_NW_PROTO = "wildcard_nw_proto";
- public static final String COLUMN_WILDCARD_TP_SRC = "wildcard_tp_src";
- public static final String COLUMN_WILDCARD_TP_DST = "wildcard_tp_dst";
- public static final String COLUMN_PRIORITY = "priority";
- public static final String COLUMN_ACTION = "action";
- public static String ColumnNames[] = { COLUMN_RULEID, COLUMN_DPID,
- COLUMN_IN_PORT, COLUMN_DL_SRC, COLUMN_DL_DST, COLUMN_DL_TYPE,
- COLUMN_NW_SRC_PREFIX, COLUMN_NW_SRC_MASKBITS, COLUMN_NW_DST_PREFIX,
- COLUMN_NW_DST_MASKBITS, COLUMN_NW_PROTO, COLUMN_TP_SRC,
- COLUMN_TP_DST, COLUMN_WILDCARD_DPID, COLUMN_WILDCARD_IN_PORT,
- COLUMN_WILDCARD_DL_SRC, COLUMN_WILDCARD_DL_DST,
- COLUMN_WILDCARD_DL_TYPE, COLUMN_WILDCARD_NW_SRC,
- COLUMN_WILDCARD_NW_DST, COLUMN_WILDCARD_NW_PROTO, COLUMN_PRIORITY,
- COLUMN_ACTION };
-
- @Override
- public String getName() {
- return "firewall";
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- // no prereq
- return false;
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return (type.equals(OFType.PACKET_IN) && name.equals("forwarding"));
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFirewallService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
- Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
- // We are the class that implements the service
- m.put(IFirewallService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(IStorageSourceService.class);
- l.add(IRestApiService.class);
- return l;
- }
-
- /**
- * Reads the rules from the storage and creates a sorted arraylist of
- * FirewallRule from them.
- *
- * Similar to getStorageRules(), which only reads contents for REST GET and
- * does no parsing, checking, nor putting into FirewallRule objects
- *
- * @return the sorted arraylist of FirewallRule instances (rules from
- * storage)
- */
- protected ArrayList<FirewallRule> readRulesFromStorage() {
- ArrayList<FirewallRule> l = new ArrayList<FirewallRule>();
-
- try {
- Map<String, Object> row;
-
- // (..., null, null) for no predicate, no ordering
- IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
- ColumnNames, null, null);
-
- // put retrieved rows into FirewallRules
- for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
- row = it.next().getRow();
- // now, parse row
- FirewallRule r = new FirewallRule();
- if (!row.containsKey(COLUMN_RULEID)
- || !row.containsKey(COLUMN_DPID)) {
- logger.error(
- "skipping entry with missing required 'ruleid' or 'switchid' entry: {}",
- row);
- return l;
- }
- try {
- r.ruleid = Integer
- .parseInt((String) row.get(COLUMN_RULEID));
- r.dpid = Long.parseLong((String) row.get(COLUMN_DPID));
-
- for (String key : row.keySet()) {
- if (row.get(key) == null)
- continue;
- if (key.equals(COLUMN_RULEID)
- || key.equals(COLUMN_DPID)
- || key.equals("id")) {
- continue; // already handled
- }
-
- else if (key.equals(COLUMN_IN_PORT)) {
- r.in_port = Short.parseShort((String) row
- .get(COLUMN_IN_PORT));
- }
-
- else if (key.equals(COLUMN_DL_SRC)) {
- r.dl_src = Long.parseLong((String) row
- .get(COLUMN_DL_SRC));
- }
-
- else if (key.equals(COLUMN_DL_DST)) {
- r.dl_dst = Long.parseLong((String) row
- .get(COLUMN_DL_DST));
- }
-
- else if (key.equals(COLUMN_DL_TYPE)) {
- r.dl_type = Short.parseShort((String) row
- .get(COLUMN_DL_TYPE));
- }
-
- else if (key.equals(COLUMN_NW_SRC_PREFIX)) {
- r.nw_src_prefix = Integer.parseInt((String) row
- .get(COLUMN_NW_SRC_PREFIX));
- }
-
- else if (key.equals(COLUMN_NW_SRC_MASKBITS)) {
- r.nw_src_maskbits = Integer.parseInt((String) row
- .get(COLUMN_NW_SRC_MASKBITS));
- }
-
- else if (key.equals(COLUMN_NW_DST_PREFIX)) {
- r.nw_dst_prefix = Integer.parseInt((String) row
- .get(COLUMN_NW_DST_PREFIX));
- }
-
- else if (key.equals(COLUMN_NW_DST_MASKBITS)) {
- r.nw_dst_maskbits = Integer.parseInt((String) row
- .get(COLUMN_NW_DST_MASKBITS));
- }
-
- else if (key.equals(COLUMN_NW_PROTO)) {
- r.nw_proto = Short.parseShort((String) row
- .get(COLUMN_NW_PROTO));
- }
-
- else if (key.equals(COLUMN_TP_SRC)) {
- r.tp_src = Short.parseShort((String) row
- .get(COLUMN_TP_SRC));
- }
-
- else if (key.equals(COLUMN_TP_DST)) {
- r.tp_dst = Short.parseShort((String) row
- .get(COLUMN_TP_DST));
- }
-
- else if (key.equals(COLUMN_WILDCARD_DPID)) {
- r.wildcard_dpid = Boolean.parseBoolean((String) row
- .get(COLUMN_WILDCARD_DPID));
- }
-
- else if (key.equals(COLUMN_WILDCARD_IN_PORT)) {
- r.wildcard_in_port = Boolean
- .parseBoolean((String) row
- .get(COLUMN_WILDCARD_IN_PORT));
- }
-
- else if (key.equals(COLUMN_WILDCARD_DL_SRC)) {
- r.wildcard_dl_src = Boolean
- .parseBoolean((String) row
- .get(COLUMN_WILDCARD_DL_SRC));
- }
-
- else if (key.equals(COLUMN_WILDCARD_DL_DST)) {
- r.wildcard_dl_dst = Boolean
- .parseBoolean((String) row
- .get(COLUMN_WILDCARD_DL_DST));
- }
-
- else if (key.equals(COLUMN_WILDCARD_DL_TYPE)) {
- r.wildcard_dl_type = Boolean
- .parseBoolean((String) row
- .get(COLUMN_WILDCARD_DL_TYPE));
- }
-
- else if (key.equals(COLUMN_WILDCARD_NW_SRC)) {
- r.wildcard_nw_src = Boolean
- .parseBoolean((String) row
- .get(COLUMN_WILDCARD_NW_SRC));
- }
-
- else if (key.equals(COLUMN_WILDCARD_NW_DST)) {
- r.wildcard_nw_dst = Boolean
- .parseBoolean((String) row
- .get(COLUMN_WILDCARD_NW_DST));
- }
-
- else if (key.equals(COLUMN_WILDCARD_NW_PROTO)) {
- r.wildcard_nw_proto = Boolean
- .parseBoolean((String) row
- .get(COLUMN_WILDCARD_NW_PROTO));
- }
-
- else if (key.equals(COLUMN_PRIORITY)) {
- r.priority = Integer.parseInt((String) row
- .get(COLUMN_PRIORITY));
- }
-
- else if (key.equals(COLUMN_ACTION)) {
- int tmp = Integer.parseInt((String) row.get(COLUMN_ACTION));
- if (tmp == FirewallRule.FirewallAction.DENY.ordinal())
- r.action = FirewallRule.FirewallAction.DENY;
- else if (tmp == FirewallRule.FirewallAction.ALLOW.ordinal())
- r.action = FirewallRule.FirewallAction.ALLOW;
- else {
- r.action = null;
- logger.error("action not recognized");
- }
- }
- }
- } catch (ClassCastException e) {
- logger.error(
- "skipping rule {} with bad data : "
- + e.getMessage(), r.ruleid);
- }
- if (r.action != null)
- l.add(r);
- }
- } catch (StorageException e) {
- logger.error("failed to access storage: {}", e.getMessage());
- // if the table doesn't exist, then wait to populate later via
- // setStorageSource()
- }
-
- // now, sort the list based on priorities
- Collections.sort(l);
-
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- floodlightProvider = context
- .getServiceImpl(IFloodlightProviderService.class);
- storageSource = context.getServiceImpl(IStorageSourceService.class);
- restApi = context.getServiceImpl(IRestApiService.class);
- rules = new ArrayList<FirewallRule>();
- logger = LoggerFactory.getLogger(Firewall.class);
-
- // start disabled
- enabled = false;
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- // register REST interface
- restApi.addRestletRoutable(new FirewallWebRoutable());
-
- // always place firewall in pipeline at bootup
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-
- // storage, create table and read rules
- storageSource.createTable(TABLE_NAME, null);
- storageSource.setTablePrimaryKeyName(TABLE_NAME, COLUMN_RULEID);
- synchronized (rules) {
- this.rules = readRulesFromStorage();
- }
- }
-
- @Override
- public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
- if (!this.enabled)
- return Command.CONTINUE;
-
- switch (msg.getType()) {
- case PACKET_IN:
- IRoutingDecision decision = null;
- if (cntx != null) {
- decision = IRoutingDecision.rtStore.get(cntx,
- IRoutingDecision.CONTEXT_DECISION);
-
- return this.processPacketInMessage(sw, (OFPacketIn) msg,
- decision, cntx);
- }
- break;
- default:
- break;
- }
-
- return Command.CONTINUE;
- }
-
- @Override
- public void enableFirewall(boolean enabled) {
- logger.info("Setting firewall to {}", enabled);
- this.enabled = enabled;
- }
-
- @Override
- public List<FirewallRule> getRules() {
- return this.rules;
- }
-
- // Only used to serve REST GET
- // Similar to readRulesFromStorage(), which actually checks and stores
- // record into FirewallRule list
- @Override
- public List<Map<String, Object>> getStorageRules() {
- ArrayList<Map<String, Object>> l = new ArrayList<Map<String, Object>>();
- try {
- // null1=no predicate, null2=no ordering
- IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
- ColumnNames, null, null);
- for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
- l.add(it.next().getRow());
- }
- } catch (StorageException e) {
- logger.error("failed to access storage: {}", e.getMessage());
- // if the table doesn't exist, then wait to populate later via
- // setStorageSource()
- }
- return l;
- }
-
- @Override
- public String getSubnetMask() {
- return IPv4.fromIPv4Address(this.subnet_mask);
- }
-
- @Override
- public void setSubnetMask(String newMask) {
- if (newMask.trim().isEmpty())
- return;
- this.subnet_mask = IPv4.toIPv4Address(newMask.trim());
- }
-
- @Override
- public synchronized void addRule(FirewallRule rule) {
-
- // generate random ruleid for each newly created rule
- // may want to return to caller if useful
- // may want to check conflict
- rule.ruleid = rule.genID();
-
- int i = 0;
- // locate the position of the new rule in the sorted arraylist
- for (i = 0; i < this.rules.size(); i++) {
- if (this.rules.get(i).priority >= rule.priority)
- break;
- }
- // now, add rule to the list
- if (i <= this.rules.size()) {
- this.rules.add(i, rule);
- } else {
- this.rules.add(rule);
- }
- // add rule to database
- Map<String, Object> entry = new HashMap<String, Object>();
- entry.put(COLUMN_RULEID, Integer.toString(rule.ruleid));
- entry.put(COLUMN_DPID, Long.toString(rule.dpid));
- entry.put(COLUMN_IN_PORT, Short.toString(rule.in_port));
- entry.put(COLUMN_DL_SRC, Long.toString(rule.dl_src));
- entry.put(COLUMN_DL_DST, Long.toString(rule.dl_dst));
- entry.put(COLUMN_DL_TYPE, Short.toString(rule.dl_type));
- entry.put(COLUMN_NW_SRC_PREFIX, Integer.toString(rule.nw_src_prefix));
- entry.put(COLUMN_NW_SRC_MASKBITS, Integer.toString(rule.nw_src_maskbits));
- entry.put(COLUMN_NW_DST_PREFIX, Integer.toString(rule.nw_dst_prefix));
- entry.put(COLUMN_NW_DST_MASKBITS, Integer.toString(rule.nw_dst_maskbits));
- entry.put(COLUMN_NW_PROTO, Short.toString(rule.nw_proto));
- entry.put(COLUMN_TP_SRC, Integer.toString(rule.tp_src));
- entry.put(COLUMN_TP_DST, Integer.toString(rule.tp_dst));
- entry.put(COLUMN_WILDCARD_DPID,
- Boolean.toString(rule.wildcard_dpid));
- entry.put(COLUMN_WILDCARD_IN_PORT,
- Boolean.toString(rule.wildcard_in_port));
- entry.put(COLUMN_WILDCARD_DL_SRC,
- Boolean.toString(rule.wildcard_dl_src));
- entry.put(COLUMN_WILDCARD_DL_DST,
- Boolean.toString(rule.wildcard_dl_dst));
- entry.put(COLUMN_WILDCARD_DL_TYPE,
- Boolean.toString(rule.wildcard_dl_type));
- entry.put(COLUMN_WILDCARD_NW_SRC,
- Boolean.toString(rule.wildcard_nw_src));
- entry.put(COLUMN_WILDCARD_NW_DST,
- Boolean.toString(rule.wildcard_nw_dst));
- entry.put(COLUMN_WILDCARD_NW_PROTO,
- Boolean.toString(rule.wildcard_nw_proto));
- entry.put(COLUMN_WILDCARD_TP_SRC,
- Boolean.toString(rule.wildcard_tp_src));
- entry.put(COLUMN_WILDCARD_TP_DST,
- Boolean.toString(rule.wildcard_tp_dst));
- entry.put(COLUMN_PRIORITY, Integer.toString(rule.priority));
- entry.put(COLUMN_ACTION, Integer.toString(rule.action.ordinal()));
- storageSource.insertRow(TABLE_NAME, entry);
- }
-
- @Override
- public synchronized void deleteRule(int ruleid) {
- Iterator<FirewallRule> iter = this.rules.iterator();
- while (iter.hasNext()) {
- FirewallRule r = iter.next();
- if (r.ruleid == ruleid) {
- // found the rule, now remove it
- iter.remove();
- break;
- }
- }
- // delete from database
- storageSource.deleteRow(TABLE_NAME, Integer.toString(ruleid));
- }
-
- /**
- * Iterates over the firewall rules and tries to match them with the
- * incoming packet (flow). Uses the FirewallRule class's matchWithFlow
- * method to perform matching. It maintains a pair of wildcards (allow and
- * deny) which are assigned later to the firewall's decision, where 'allow'
- * wildcards are applied if the matched rule turns out to be an ALLOW rule
- * and 'deny' wildcards are applied otherwise. Wildcards are applied to
- * firewall decision to optimize flows in the switch, ensuring least number
- * of flows per firewall rule. So, if a particular field is not "ANY" (i.e.
- * not wildcarded) in a higher priority rule, then if a lower priority rule
- * matches the packet and wildcards it, it can't be wildcarded in the
- * switch's flow entry, because otherwise some packets matching the higher
- * priority rule might escape the firewall. The reason for keeping different
- * two different wildcards is that if a field is not wildcarded in a higher
- * priority allow rule, the same field shouldn't be wildcarded for packets
- * matching the lower priority deny rule (non-wildcarded fields in higher
- * priority rules override the wildcarding of those fields in lower priority
- * rules of the opposite type). So, to ensure that wildcards are
- * appropriately set for different types of rules (allow vs. deny), separate
- * wildcards are maintained. Iteration is performed on the sorted list of
- * rules (sorted in decreasing order of priority).
- *
- * @param sw
- * the switch instance
- * @param pi
- * the incoming packet data structure
- * @param cntx
- * the floodlight context
- * @return an instance of RuleWildcardsPair that specify rule that matches
- * and the wildcards for the firewall decision
- */
- protected RuleWildcardsPair matchWithRule(IOFSwitch sw, OFPacketIn pi,
- FloodlightContext cntx) {
- FirewallRule matched_rule = null;
- Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
- WildcardsPair wildcards = new WildcardsPair();
-
- synchronized (rules) {
- Iterator<FirewallRule> iter = this.rules.iterator();
- FirewallRule rule = null;
- // iterate through list to find a matching firewall rule
- while (iter.hasNext()) {
- // get next rule from list
- rule = iter.next();
-
- // check if rule matches
- if (rule.matchesFlow(sw.getId(), pi.getInPort(), eth, wildcards) == true) {
- matched_rule = rule;
- break;
- }
- }
- }
-
- // make a pair of rule and wildcards, then return it
- RuleWildcardsPair ret = new RuleWildcardsPair();
- ret.rule = matched_rule;
- if (matched_rule == null || matched_rule.action == FirewallRule.FirewallAction.DENY) {
- ret.wildcards = wildcards.drop;
- } else {
- ret.wildcards = wildcards.allow;
- }
- return ret;
- }
-
- /**
- * Checks whether an IP address is a broadcast address or not (determines
- * using subnet mask)
- *
- * @param IPAddress
- * the IP address to check
- * @return true if it is a broadcast address, false otherwise
- */
- protected boolean IPIsBroadcast(int IPAddress) {
- // inverted subnet mask
- int inv_subnet_mask = ~this.subnet_mask;
- return ((IPAddress & inv_subnet_mask) == inv_subnet_mask);
- }
-
- public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi,
- IRoutingDecision decision, FloodlightContext cntx) {
- Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
- // Allowing L2 broadcast + ARP broadcast request (also deny malformed
- // broadcasts -> L2 broadcast + L3 unicast)
- if (eth.isBroadcast() == true) {
- boolean allowBroadcast = true;
- // the case to determine if we have L2 broadcast + L3 unicast
- // don't allow this broadcast packet if such is the case (malformed
- // packet)
- if (eth.getEtherType() == Ethernet.TYPE_IPv4
- && this.IPIsBroadcast(((IPv4) eth.getPayload())
- .getDestinationAddress()) == false) {
- allowBroadcast = false;
- }
- if (allowBroadcast == true) {
- if (logger.isTraceEnabled())
- logger.trace("Allowing broadcast traffic for PacketIn={}",
- pi);
-
- decision = new RoutingDecision(sw.getId(), pi.getInPort()
- , IDeviceService.fcStore.
- get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
- IRoutingDecision.RoutingAction.MULTICAST);
- decision.addToContext(cntx);
- } else {
- if (logger.isTraceEnabled())
- logger.trace(
- "Blocking malformed broadcast traffic for PacketIn={}",
- pi);
-
- decision = new RoutingDecision(sw.getId(), pi.getInPort()
- , IDeviceService.fcStore.
- get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
- IRoutingDecision.RoutingAction.DROP);
- decision.addToContext(cntx);
- }
- return Command.CONTINUE;
- }
- /*
- * ARP response (unicast) can be let through without filtering through
- * rules by uncommenting the code below
- */
- /*
- * else if (eth.getEtherType() == Ethernet.TYPE_ARP) {
- * logger.info("allowing ARP traffic"); decision = new
- * FirewallDecision(IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
- * decision.addToContext(cntx); return Command.CONTINUE; }
- */
-
- // check if we have a matching rule for this packet/flow
- // and no decision is taken yet
- if (decision == null) {
- RuleWildcardsPair match_ret = this.matchWithRule(sw, pi, cntx);
- FirewallRule rule = match_ret.rule;
-
- if (rule == null || rule.action == FirewallRule.FirewallAction.DENY) {
- decision = new RoutingDecision(sw.getId(), pi.getInPort()
- , IDeviceService.fcStore.
- get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
- IRoutingDecision.RoutingAction.DROP);
- decision.setWildcards(match_ret.wildcards);
- decision.addToContext(cntx);
- if (logger.isTraceEnabled()) {
- if (rule == null)
- logger.trace(
- "No firewall rule found for PacketIn={}, blocking flow",
- pi);
- else if (rule.action == FirewallRule.FirewallAction.DENY) {
- logger.trace("Deny rule={} match for PacketIn={}",
- rule, pi);
- }
- }
- } else {
- decision = new RoutingDecision(sw.getId(), pi.getInPort()
- , IDeviceService.fcStore.
- get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
- IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
- decision.setWildcards(match_ret.wildcards);
- decision.addToContext(cntx);
- if (logger.isTraceEnabled())
- logger.trace("Allow rule={} match for PacketIn={}", rule,
- pi);
- }
- }
-
- return Command.CONTINUE;
- }
-
- @Override
- public boolean isEnabled() {
- return enabled;
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
deleted file mode 100644
index 1f4d71a..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.io.IOException;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.resource.Post;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FirewallResource extends ServerResource {
- protected static Logger log = LoggerFactory.getLogger(FirewallResource.class);
-
- @Get("json")
- public Object handleRequest() {
- IFirewallService firewall =
- (IFirewallService)getContext().getAttributes().
- get(IFirewallService.class.getCanonicalName());
-
- String op = (String) getRequestAttributes().get("op");
-
- // REST API check status
- if (op.equalsIgnoreCase("status")) {
- if (firewall.isEnabled())
- return "{\"result\" : \"firewall enabled\"}";
- else
- return "{\"result\" : \"firewall disabled\"}";
- }
-
- // REST API enable firewall
- if (op.equalsIgnoreCase("enable")) {
- firewall.enableFirewall(true);
- return "{\"status\" : \"success\", \"details\" : \"firewall running\"}";
- }
-
- // REST API disable firewall
- if (op.equalsIgnoreCase("disable")) {
- firewall.enableFirewall(false);
- return "{\"status\" : \"success\", \"details\" : \"firewall stopped\"}";
- }
-
- // REST API retrieving rules from storage
- // currently equivalent to /wm/firewall/rules/json
- if (op.equalsIgnoreCase("storageRules")) {
- return firewall.getStorageRules();
- }
-
- // REST API set local subnet mask -- this only makes sense for one subnet
- // will remove later
- if (op.equalsIgnoreCase("subnet-mask")) {
- return firewall.getSubnetMask();
- }
-
- // no known options found
- return "{\"status\" : \"failure\", \"details\" : \"invalid operation\"}";
- }
-
- /**
- * Allows setting of subnet mask
- * @param fmJson The Subnet Mask in JSON format.
- * @return A string status message
- */
- @Post
- public String handlePost(String fmJson) {
- IFirewallService firewall =
- (IFirewallService)getContext().getAttributes().
- get(IFirewallService.class.getCanonicalName());
-
- String newMask;
- try {
- newMask = jsonExtractSubnetMask(fmJson);
- } catch (IOException e) {
- log.error("Error parsing new subnet mask: " + fmJson, e);
- e.printStackTrace();
- return "{\"status\" : \"Error! Could not parse new subnet mask, see log for details.\"}";
- }
- firewall.setSubnetMask(newMask);
- return ("{\"status\" : \"subnet mask set\"}");
- }
-
- /**
- * Extracts subnet mask from a JSON string
- * @param fmJson The JSON formatted string
- * @return The subnet mask
- * @throws IOException If there was an error parsing the JSON
- */
- public static String jsonExtractSubnetMask(String fmJson) throws IOException {
- String subnet_mask = "";
- MappingJsonFactory f = new MappingJsonFactory();
- JsonParser jp;
-
- try {
- jp = f.createJsonParser(fmJson);
- } catch (JsonParseException e) {
- throw new IOException(e);
- }
-
- jp.nextToken();
- if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected START_OBJECT");
- }
-
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
- throw new IOException("Expected FIELD_NAME");
- }
-
- String n = jp.getCurrentName();
- jp.nextToken();
- if (jp.getText().equals(""))
- continue;
-
- if (n == "subnet-mask") {
- subnet_mask = jp.getText();
- break;
- }
- }
-
- return subnet_mask;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
deleted file mode 100644
index d9b2612..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
+++ /dev/null
@@ -1,392 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.TCP;
-import net.floodlightcontroller.packet.UDP;
-
-public class FirewallRule implements Comparable<FirewallRule> {
- public int ruleid;
-
- public long dpid;
- public short in_port;
- public long dl_src;
- public long dl_dst;
- public short dl_type;
- public int nw_src_prefix;
- public int nw_src_maskbits;
- public int nw_dst_prefix;
- public int nw_dst_maskbits;
- public short nw_proto;
- public short tp_src;
- public short tp_dst;
-
- public boolean wildcard_dpid;
- public boolean wildcard_in_port;
- public boolean wildcard_dl_src;
- public boolean wildcard_dl_dst;
- public boolean wildcard_dl_type;
- public boolean wildcard_nw_src;
- public boolean wildcard_nw_dst;
- public boolean wildcard_nw_proto;
- public boolean wildcard_tp_src;
- public boolean wildcard_tp_dst;
-
- public int priority = 0;
-
- public FirewallAction action;
-
- public enum FirewallAction {
- /*
- * DENY: Deny rule
- * ALLOW: Allow rule
- */
- DENY, ALLOW
- }
-
- public FirewallRule() {
- this.in_port = 0;
- this.dl_src = 0;
- this.nw_src_prefix = 0;
- this.nw_src_maskbits = 0;
- this.dl_dst = 0;
- this.nw_proto = 0;
- this.tp_src = 0;
- this.tp_dst = 0;
- this.dl_dst = 0;
- this.nw_dst_prefix = 0;
- this.nw_dst_maskbits = 0;
- this.dpid = -1;
- this.wildcard_dpid = true;
- this.wildcard_in_port = true;
- this.wildcard_dl_src = true;
- this.wildcard_dl_dst = true;
- this.wildcard_dl_type = true;
- this.wildcard_nw_src = true;
- this.wildcard_nw_dst = true;
- this.wildcard_nw_proto = true;
- this.wildcard_tp_src = true;
- this.wildcard_tp_dst = true;
- this.priority = 0;
- this.action = FirewallAction.ALLOW;
- this.ruleid = 0;
- }
-
- /**
- * Generates a unique ID for the instance
- *
- * @return int representing the unique id
- */
- public int genID() {
- int uid = this.hashCode();
- if (uid < 0) {
- uid = Math.abs(uid);
- uid = uid * 15551;
- }
- return uid;
- }
-
- /**
- * Comparison method for Collections.sort method
- *
- * @param rule
- * the rule to compare with
- * @return number representing the result of comparison 0 if equal negative
- * if less than 'rule' greater than zero if greater priority rule
- * than 'rule'
- */
- @Override
- public int compareTo(FirewallRule rule) {
- return this.priority - rule.priority;
- }
-
- /**
- * Determines if this instance matches an existing rule instance
- *
- * @param r
- * : the FirewallRule instance to compare with
- * @return boolean: true if a match is found
- **/
- public boolean isSameAs(FirewallRule r) {
- if (this.action != r.action
- || this.wildcard_dl_type != r.wildcard_dl_type
- || (this.wildcard_dl_type == false && this.dl_type == r.dl_type)
- || this.wildcard_tp_src != r.wildcard_tp_src
- || (this.wildcard_tp_src == false && this.tp_src != r.tp_src)
- || this.wildcard_tp_dst != r.wildcard_tp_dst
- || (this.wildcard_tp_dst == false &&this.tp_dst != r.tp_dst)
- || this.wildcard_dpid != r.wildcard_dpid
- || (this.wildcard_dpid == false && this.dpid != r.dpid)
- || this.wildcard_in_port != r.wildcard_in_port
- || (this.wildcard_in_port == false && this.in_port != r.in_port)
- || this.wildcard_nw_src != r.wildcard_nw_src
- || (this.wildcard_nw_src == false && (this.nw_src_prefix != r.nw_src_prefix || this.nw_src_maskbits != r.nw_src_maskbits))
- || this.wildcard_dl_src != r.wildcard_dl_src
- || (this.wildcard_dl_src == false && this.dl_src != r.dl_src)
- || this.wildcard_nw_proto != r.wildcard_nw_proto
- || (this.wildcard_nw_proto == false && this.nw_proto != r.nw_proto)
- || this.wildcard_nw_dst != r.wildcard_nw_dst
- || (this.wildcard_nw_dst == false && (this.nw_dst_prefix != r.nw_dst_prefix || this.nw_dst_maskbits != r.nw_dst_maskbits))
- || this.wildcard_dl_dst != r.wildcard_dl_dst
- || (this.wildcard_dl_dst == false && this.dl_dst != r.dl_dst)) {
- return false;
- }
- return true;
- }
-
- /**
- * Matches this rule to a given flow - incoming packet
- *
- * @param switchDpid
- * the Id of the connected switch
- * @param inPort
- * the switch port where the packet originated from
- * @param packet
- * the Ethernet packet that arrives at the switch
- * @param wildcards
- * the pair of wildcards (allow and deny) given by Firewall
- * module that is used by the Firewall module's matchWithRule
- * method to derive wildcards for the decision to be taken
- * @return true if the rule matches the given packet-in, false otherwise
- */
- public boolean matchesFlow(long switchDpid, short inPort, Ethernet packet,
- WildcardsPair wildcards) {
- IPacket pkt = packet.getPayload();
-
- // dl_type type
- IPv4 pkt_ip = null;
-
- // nw_proto types
- TCP pkt_tcp = null;
- UDP pkt_udp = null;
-
- // tp_src and tp_dst (tp port numbers)
- short pkt_tp_src = 0;
- short pkt_tp_dst = 0;
-
- // switchID matches?
- if (wildcard_dpid == false && dpid != switchDpid)
- return false;
-
- // in_port matches?
- if (wildcard_in_port == false && in_port != inPort)
- return false;
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_IN_PORT;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_IN_PORT;
- }
-
- // mac address (src and dst) match?
- if (wildcard_dl_src == false
- && dl_src != packet.getSourceMAC().toLong())
- return false;
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_DL_SRC;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_DL_SRC;
- }
-
- if (wildcard_dl_dst == false
- && dl_dst != packet.getDestinationMAC().toLong())
- return false;
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_DL_DST;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_DL_DST;
- }
-
- // dl_type check: ARP, IP
-
- // if this is not an ARP rule but the pkt is ARP,
- // return false match - no need to continue protocol specific check
- if (wildcard_dl_type == false) {
- if (dl_type == Ethernet.TYPE_ARP) {
- if (packet.getEtherType() != Ethernet.TYPE_ARP)
- return false;
- else {
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
- }
- }
- } else if (dl_type == Ethernet.TYPE_IPv4) {
- if (packet.getEtherType() != Ethernet.TYPE_IPv4)
- return false;
- else {
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
- }
- // IP packets, proceed with ip address check
- pkt_ip = (IPv4) pkt;
-
- // IP addresses (src and dst) match?
- if (wildcard_nw_src == false
- && this.matchIPAddress(nw_src_prefix,
- nw_src_maskbits, pkt_ip.getSourceAddress()) == false)
- return false;
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_NW_SRC_ALL;
- wildcards.drop |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_NW_SRC_ALL;
- wildcards.allow |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
- }
-
- if (wildcard_nw_dst == false
- && this.matchIPAddress(nw_dst_prefix,
- nw_dst_maskbits,
- pkt_ip.getDestinationAddress()) == false)
- return false;
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_NW_DST_ALL;
- wildcards.drop |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_NW_DST_ALL;
- wildcards.allow |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
- }
-
- // nw_proto check
- if (wildcard_nw_proto == false) {
- if (nw_proto == IPv4.PROTOCOL_TCP) {
- if (pkt_ip.getProtocol() != IPv4.PROTOCOL_TCP)
- return false;
- else {
- pkt_tcp = (TCP) pkt_ip.getPayload();
- pkt_tp_src = pkt_tcp.getSourcePort();
- pkt_tp_dst = pkt_tcp.getDestinationPort();
- }
- } else if (nw_proto == IPv4.PROTOCOL_UDP) {
- if (pkt_ip.getProtocol() != IPv4.PROTOCOL_UDP)
- return false;
- else {
- pkt_udp = (UDP) pkt_ip.getPayload();
- pkt_tp_src = pkt_udp.getSourcePort();
- pkt_tp_dst = pkt_udp.getDestinationPort();
- }
- } else if (nw_proto == IPv4.PROTOCOL_ICMP) {
- if (pkt_ip.getProtocol() != IPv4.PROTOCOL_ICMP)
- return false;
- else {
- // nothing more needed for ICMP
- }
- }
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
- }
-
- // TCP/UDP source and destination ports match?
- if (pkt_tcp != null || pkt_udp != null) {
- // does the source port match?
- if (tp_src != 0 && tp_src != pkt_tp_src)
- return false;
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_TP_SRC;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_TP_SRC;
- }
-
- // does the destination port match?
- if (tp_dst != 0 && tp_dst != pkt_tp_dst)
- return false;
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_TP_DST;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_TP_DST;
- }
- }
- }
-
- }
- } else {
- // non-IP packet - not supported - report no match
- return false;
- }
- }
- if (action == FirewallRule.FirewallAction.DENY) {
- wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
- } else {
- wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
- }
-
- // all applicable checks passed
- return true;
- }
-
- /**
- * Determines if rule's CIDR address matches IP address of the packet
- *
- * @param rulePrefix
- * prefix part of the CIDR address
- * @param ruleBits
- * the size of mask of the CIDR address
- * @param packetAddress
- * the IP address of the incoming packet to match with
- * @return true if CIDR address matches the packet's IP address, false
- * otherwise
- */
- protected boolean matchIPAddress(int rulePrefix, int ruleBits,
- int packetAddress) {
- boolean matched = true;
-
- int rule_iprng = 32 - ruleBits;
- int rule_ipint = rulePrefix;
- int pkt_ipint = packetAddress;
- // if there's a subnet range (bits to be wildcarded > 0)
- if (rule_iprng > 0) {
- // right shift bits to remove rule_iprng of LSB that are to be
- // wildcarded
- rule_ipint = rule_ipint >> rule_iprng;
- pkt_ipint = pkt_ipint >> rule_iprng;
- // now left shift to return to normal range, except that the
- // rule_iprng number of LSB
- // are now zeroed
- rule_ipint = rule_ipint << rule_iprng;
- pkt_ipint = pkt_ipint << rule_iprng;
- }
- // check if we have a match
- if (rule_ipint != pkt_ipint)
- matched = false;
-
- return matched;
- }
-
- @Override
- public int hashCode() {
- final int prime = 2521;
- int result = super.hashCode();
- result = prime * result + (int) dpid;
- result = prime * result + in_port;
- result = prime * result + (int) dl_src;
- result = prime * result + (int) dl_dst;
- result = prime * result + dl_type;
- result = prime * result + nw_src_prefix;
- result = prime * result + nw_src_maskbits;
- result = prime * result + nw_dst_prefix;
- result = prime * result + nw_dst_maskbits;
- result = prime * result + nw_proto;
- result = prime * result + tp_src;
- result = prime * result + tp_dst;
- result = prime * result + action.ordinal();
- result = prime * result + priority;
- result = prime * result + (new Boolean(wildcard_dpid)).hashCode();
- result = prime * result + (new Boolean(wildcard_in_port)).hashCode();
- result = prime * result + (new Boolean(wildcard_dl_src)).hashCode();
- result = prime * result + (new Boolean(wildcard_dl_dst)).hashCode();
- result = prime * result + (new Boolean(wildcard_dl_type)).hashCode();
- result = prime * result + (new Boolean(wildcard_nw_src)).hashCode();
- result = prime * result + (new Boolean(wildcard_nw_dst)).hashCode();
- result = prime * result + (new Boolean(wildcard_nw_proto)).hashCode();
- result = prime * result + (new Boolean(wildcard_tp_src)).hashCode();
- result = prime * result + (new Boolean(wildcard_tp_dst)).hashCode();
- return result;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
deleted file mode 100644
index 7a31d38..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
+++ /dev/null
@@ -1,292 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.openflow.util.HexString;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Post;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-
-public class FirewallRulesResource extends ServerResource {
- protected static Logger log = LoggerFactory.getLogger(FirewallRulesResource.class);
-
- @Get("json")
- public Object handleRequest() {
- IFirewallService firewall =
- (IFirewallService)getContext().getAttributes().
- get(IFirewallService.class.getCanonicalName());
-
- return firewall.getRules();
- }
-
- /**
- * Takes a Firewall Rule string in JSON format and parses it into
- * our firewall rule data structure, then adds it to the firewall.
- * @param fmJson The Firewall rule entry in JSON format.
- * @return A string status message
- */
- @Post
- public String store(String fmJson) {
- IFirewallService firewall =
- (IFirewallService)getContext().getAttributes().
- get(IFirewallService.class.getCanonicalName());
-
- FirewallRule rule;
- try {
- rule = jsonToFirewallRule(fmJson);
- } catch (IOException e) {
- log.error("Error parsing firewall rule: " + fmJson, e);
- e.printStackTrace();
- return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
- }
- String status = null;
- if (checkRuleExists(rule, firewall.getRules())) {
- status = "Error! A similar firewall rule already exists.";
- log.error(status);
- } else {
- // add rule to firewall
- firewall.addRule(rule);
- status = "Rule added";
- }
- return ("{\"status\" : \"" + status + "\"}");
- }
-
- /**
- * Takes a Firewall Rule string in JSON format and parses it into
- * our firewall rule data structure, then deletes it from the firewall.
- * @param fmJson The Firewall rule entry in JSON format.
- * @return A string status message
- */
-
- @Delete
- public String remove(String fmJson) {
- IFirewallService firewall =
- (IFirewallService)getContext().getAttributes().
- get(IFirewallService.class.getCanonicalName());
-
- FirewallRule rule;
- try {
- rule = jsonToFirewallRule(fmJson);
- } catch (IOException e) {
- log.error("Error parsing firewall rule: " + fmJson, e);
- e.printStackTrace();
- return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
- }
- String status = null;
- boolean exists = false;
- Iterator<FirewallRule> iter = firewall.getRules().iterator();
- while (iter.hasNext()) {
- FirewallRule r = iter.next();
- if (r.ruleid == rule.ruleid) {
- exists = true;
- break;
- }
- }
- if (!exists) {
- status = "Error! Can't delete, a rule with this ID doesn't exist.";
- log.error(status);
- } else {
- // delete rule from firewall
- firewall.deleteRule(rule.ruleid);
- status = "Rule deleted";
- }
- return ("{\"status\" : \"" + status + "\"}");
- }
-
- /**
- * Turns a JSON formatted Firewall Rule string into a FirewallRule instance
- * @param fmJson The JSON formatted static firewall rule
- * @return The FirewallRule instance
- * @throws IOException If there was an error parsing the JSON
- */
-
- public static FirewallRule jsonToFirewallRule(String fmJson) throws IOException {
- FirewallRule rule = new FirewallRule();
- MappingJsonFactory f = new MappingJsonFactory();
- JsonParser jp;
-
- try {
- jp = f.createJsonParser(fmJson);
- } catch (JsonParseException e) {
- throw new IOException(e);
- }
-
- jp.nextToken();
- if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected START_OBJECT");
- }
-
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
- throw new IOException("Expected FIELD_NAME");
- }
-
- String n = jp.getCurrentName();
- jp.nextToken();
- if (jp.getText().equals(""))
- continue;
-
- String tmp;
-
- // This is currently only applicable for remove(). In store(), ruleid takes a random number
- if (n == "ruleid") {
- rule.ruleid = Integer.parseInt((String)jp.getText());
- }
-
- // This assumes user having dpid info for involved switches
- else if (n == "switchid") {
- tmp = jp.getText();
- if (tmp.equalsIgnoreCase("-1") == false) {
- // user inputs hex format dpid
- rule.dpid = HexString.toLong(tmp);
- rule.wildcard_dpid = false;
- }
- }
-
- else if (n == "src-inport") {
- rule.in_port = Short.parseShort(jp.getText());
- rule.wildcard_in_port = false;
- }
-
- else if (n == "src-mac") {
- tmp = jp.getText();
- if (tmp.equalsIgnoreCase("ANY") == false) {
- rule.wildcard_dl_src = false;
- rule.dl_src = Ethernet.toLong(Ethernet.toMACAddress(tmp));
- }
- }
-
- else if (n == "dst-mac") {
- tmp = jp.getText();
- if (tmp.equalsIgnoreCase("ANY") == false) {
- rule.wildcard_dl_dst = false;
- rule.dl_dst = Ethernet.toLong(Ethernet.toMACAddress(tmp));
- }
- }
-
- else if (n == "dl-type") {
- tmp = jp.getText();
- if (tmp.equalsIgnoreCase("ARP")) {
- rule.wildcard_dl_type = false;
- rule.dl_type = Ethernet.TYPE_ARP;
- }
- }
-
- else if (n == "src-ip") {
- tmp = jp.getText();
- if (tmp.equalsIgnoreCase("ANY") == false) {
- rule.wildcard_nw_src = false;
- rule.wildcard_dl_type = false;
- rule.dl_type = Ethernet.TYPE_IPv4;
- int[] cidr = IPCIDRToPrefixBits(tmp);
- rule.nw_src_prefix = cidr[0];
- rule.nw_src_maskbits = cidr[1];
- }
- }
-
- else if (n == "dst-ip") {
- tmp = jp.getText();
- if (tmp.equalsIgnoreCase("ANY") == false) {
- rule.wildcard_nw_dst = false;
- rule.wildcard_dl_type = false;
- rule.dl_type = Ethernet.TYPE_IPv4;
- int[] cidr = IPCIDRToPrefixBits(tmp);
- rule.nw_dst_prefix = cidr[0];
- rule.nw_dst_maskbits = cidr[1];
- }
- }
-
- else if (n == "nw-proto") {
- tmp = jp.getText();
- if (tmp.equalsIgnoreCase("TCP")) {
- rule.wildcard_nw_proto = false;
- rule.nw_proto = IPv4.PROTOCOL_TCP;
- rule.wildcard_dl_type = false;
- rule.dl_type = Ethernet.TYPE_IPv4;
- } else if (tmp.equalsIgnoreCase("UDP")) {
- rule.wildcard_nw_proto = false;
- rule.nw_proto = IPv4.PROTOCOL_UDP;
- rule.wildcard_dl_type = false;
- rule.dl_type = Ethernet.TYPE_IPv4;
- } else if (tmp.equalsIgnoreCase("ICMP")) {
- rule.wildcard_nw_proto = false;
- rule.nw_proto = IPv4.PROTOCOL_ICMP;
- rule.wildcard_dl_type = false;
- rule.dl_type = Ethernet.TYPE_IPv4;
- }
- }
-
- else if (n == "tp-src") {
- rule.wildcard_tp_src = false;
- rule.tp_src = Short.parseShort(jp.getText());
- }
-
- else if (n == "tp-dst") {
- rule.wildcard_tp_dst = false;
- rule.tp_dst = Short.parseShort(jp.getText());
- }
-
- else if (n == "priority") {
- rule.priority = Integer.parseInt(jp.getText());
- }
-
- else if (n == "action") {
- if (jp.getText().equalsIgnoreCase("allow") == true) {
- rule.action = FirewallRule.FirewallAction.ALLOW;
- } else if (jp.getText().equalsIgnoreCase("deny") == true) {
- rule.action = FirewallRule.FirewallAction.DENY;
- }
- }
- }
-
- return rule;
- }
-
- public static int[] IPCIDRToPrefixBits(String cidr) {
- int ret[] = new int[2];
-
- // as IP can also be a prefix rather than an absolute address
- // split it over "/" to get the bit range
- String[] parts = cidr.split("/");
- String cidr_prefix = parts[0].trim();
- int cidr_bits = 0;
- if (parts.length == 2) {
- try {
- cidr_bits = Integer.parseInt(parts[1].trim());
- } catch (Exception exp) {
- cidr_bits = 32;
- }
- }
- ret[0] = IPv4.toIPv4Address(cidr_prefix);
- ret[1] = cidr_bits;
-
- return ret;
- }
-
- public static boolean checkRuleExists(FirewallRule rule, List<FirewallRule> rules) {
- Iterator<FirewallRule> iter = rules.iterator();
- while (iter.hasNext()) {
- FirewallRule r = iter.next();
-
- // check if we find a similar rule
- if (rule.isSameAs(r)) {
- return true;
- }
- }
-
- // no rule matched, so it doesn't exist in the rules
- return false;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java b/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java
deleted file mode 100644
index 3a9beab..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-import org.restlet.Context;
-import org.restlet.routing.Router;
-
-public class FirewallWebRoutable implements RestletRoutable {
- /**
- * Create the Restlet router and bind to the proper resources.
- */
- @Override
- public Router getRestlet(Context context) {
- Router router = new Router(context);
- router.attach("/module/{op}/json", FirewallResource.class);
- router.attach("/rules/json", FirewallRulesResource.class);
- return router;
- }
-
- /**
- * Set the base path for the Firewall
- */
- @Override
- public String basePath() {
- return "/wm/firewall";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java b/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java
deleted file mode 100644
index ae9d89f..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IFirewallService extends IFloodlightService {
-
- /**
- * Enables/disables the firewall.
- * @param enable Whether to enable or disable the firewall.
- */
- public void enableFirewall(boolean enable);
-
- /**
- * Returns operational status of the firewall
- * @return boolean enabled;
- */
- public boolean isEnabled();
-
- /**
- * Returns all of the firewall rules
- * @return List of all rules
- */
- public List<FirewallRule> getRules();
-
- /**
- * Returns the subnet mask
- * @return subnet mask
- */
- public String getSubnetMask();
-
- /**
- * Sets the subnet mask
- * @param newMask The new subnet mask
- */
- public void setSubnetMask(String newMask);
-
- /**
- * Returns all of the firewall rules in storage
- * for debugging and unit-testing purposes
- * @return List of all rules in storage
- */
- public List<Map<String, Object>> getStorageRules();
-
- /**
- * Adds a new Firewall rule
- */
- public void addRule(FirewallRule rule);
-
- /**
- * Deletes a Firewall rule
- */
- public void deleteRule(int ruleid);
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java b/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java
deleted file mode 100644
index 3fab409..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-public class RuleWildcardsPair {
- public FirewallRule rule;
- public int wildcards = OFMatch.OFPFW_ALL;
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java b/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java
deleted file mode 100644
index 2e5f123..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-public class WildcardsPair {
- public int allow = OFMatch.OFPFW_ALL;
- public int drop = OFMatch.OFPFW_ALL;
-}
diff --git a/src/main/java/net/floodlightcontroller/hub/Hub.java b/src/main/java/net/floodlightcontroller/hub/Hub.java
deleted file mode 100644
index 3618351..0000000
--- a/src/main/java/net/floodlightcontroller/hub/Hub.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford University
-*
-* 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 net.floodlightcontroller.hub;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.U16;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu) - 04/04/10
- */
-public class Hub implements IFloodlightModule, IOFMessageListener {
- protected static Logger log = LoggerFactory.getLogger(Hub.class);
-
- protected IFloodlightProviderService floodlightProvider;
-
- /**
- * @param floodlightProvider the floodlightProvider to set
- */
- public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
- this.floodlightProvider = floodlightProvider;
- }
-
- @Override
- public String getName() {
- return Hub.class.getPackage().getName();
- }
-
- public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
- OFPacketIn pi = (OFPacketIn) msg;
- OFPacketOut po = (OFPacketOut) floodlightProvider.getOFMessageFactory()
- .getMessage(OFType.PACKET_OUT);
- po.setBufferId(pi.getBufferId())
- .setInPort(pi.getInPort());
-
- // set actions
- OFActionOutput action = new OFActionOutput()
- .setPort((short) OFPort.OFPP_FLOOD.getValue());
- po.setActions(Collections.singletonList((OFAction)action));
- po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
-
- // set data if is is included in the packetin
- if (pi.getBufferId() == 0xffffffff) {
- byte[] packetData = pi.getPacketData();
- po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
- + po.getActionsLength() + packetData.length));
- po.setPacketData(packetData);
- } else {
- po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
- + po.getActionsLength()));
- }
- try {
- sw.write(po, cntx);
- } catch (IOException e) {
- log.error("Failure writing PacketOut", e);
- }
-
- return Command.CONTINUE;
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return false;
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return false;
- }
-
- // IFloodlightModule
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- // We don't provide any services, return null
- return null;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- // We don't provide any services, return null
- return null;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>>
- getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- floodlightProvider =
- context.getServiceImpl(IFloodlightProviderService.class);
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/jython/JythonDebugInterface.java b/src/main/java/net/floodlightcontroller/jython/JythonDebugInterface.java
deleted file mode 100644
index 19a97b5..0000000
--- a/src/main/java/net/floodlightcontroller/jython/JythonDebugInterface.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package net.floodlightcontroller.jython;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public class JythonDebugInterface implements IFloodlightModule {
- protected static Logger log = LoggerFactory.getLogger(JythonDebugInterface.class);
- protected JythonServer debug_server;
- protected static int JYTHON_PORT = 6655;
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- // We don't export services
- return null;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- // We don't export services
- return null;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>>
- getModuleDependencies() {
- // We don't have any dependencies
- return null;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- // no-op
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- Map<String, Object> locals = new HashMap<String, Object>();
- // add all existing module references to the debug server
- for (Class<? extends IFloodlightService> s : context.getAllServices()) {
- // Put only the last part of the name
- String[] bits = s.getCanonicalName().split("\\.");
- String name = bits[bits.length-1];
- locals.put(name, context.getServiceImpl(s));
- }
-
- // read our config options
- Map<String, String> configOptions = context.getConfigParams(this);
- int port = JYTHON_PORT;
- String portNum = configOptions.get("port");
- if (portNum != null) {
- port = Integer.parseInt(portNum);
- }
-
- JythonServer debug_server = new JythonServer(port, locals);
- debug_server.start();
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/jython/JythonServer.java b/src/main/java/net/floodlightcontroller/jython/JythonServer.java
deleted file mode 100644
index fc35b15..0000000
--- a/src/main/java/net/floodlightcontroller/jython/JythonServer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package net.floodlightcontroller.jython;
-
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.python.util.PythonInterpreter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class starts a thread that runs a jython interpreter that
- * can be used for debug (or even development).
- *
- * @author mandeepdhami
- *
- */
-public class JythonServer extends Thread {
- protected static Logger log = LoggerFactory.getLogger(JythonServer.class);
-
- int port;
- Map<String, Object> locals;
-
- /**
- * @param port_ Port to use for jython server
- * @param locals_ Locals to add to the interpreters top level name space
- */
- public JythonServer(int port_, Map<String, Object> locals_) {
- this.port = port_ ;
- this.locals = locals_;
- if (this.locals == null) {
- this.locals = new HashMap<String, Object>();
- }
- this.locals.put("log", JythonServer.log);
- this.setName("debugserver");
- }
-
- /**
- * The main thread for this class invoked by Thread.run()
- *
- * @see java.lang.Thread#run()
- */
- public void run() {
- PythonInterpreter p = new PythonInterpreter();
- for (String name : this.locals.keySet()) {
- p.set(name, this.locals.get(name));
- }
-
- URL jarUrl = JythonServer.class.getProtectionDomain().getCodeSource().getLocation();
- String jarPath = jarUrl.getPath();
- if (jarUrl.getProtocol().equals("file")) {
- // If URL is of type file, assume that we are in dev env and set path to python dir.
- // else use the jar file as is
- jarPath = jarPath + "../../src/main/python/";
- }
-
- p.exec("import sys");
- p.exec("sys.path.append('" + jarPath + "')");
- p.exec("from debugserver import run_server");
- p.exec("run_server(" + this.port + ", '0.0.0.0', locals())");
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/ILearningSwitchService.java b/src/main/java/net/floodlightcontroller/learningswitch/ILearningSwitchService.java
deleted file mode 100644
index 71f6625..0000000
--- a/src/main/java/net/floodlightcontroller/learningswitch/ILearningSwitchService.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.floodlightcontroller.learningswitch;
-
-import java.util.Map;
-
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.types.MacVlanPair;
-
-public interface ILearningSwitchService extends IFloodlightService {
- /**
- * Returns the LearningSwitch's learned host table
- * @return The learned host table
- */
- public Map<IOFSwitch, Map<MacVlanPair,Short>> getTable();
-}
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
deleted file mode 100644
index 005708d..0000000
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford University
-*
-* 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.
-**/
-
-/**
- * Floodlight
- * A BSD licensed, Java based OpenFlow controller
- *
- * Floodlight is a Java based OpenFlow controller originally written by David Erickson at Stanford
- * University. It is available under the BSD license.
- *
- * For documentation, forums, issue tracking and more visit:
- *
- * http://www.openflowhub.org/display/Floodlight/Floodlight+Home
- **/
-
-package net.floodlightcontroller.learningswitch;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.types.MacVlanPair;
-import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.restserver.IRestApiService;
-
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFFlowRemoved;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.HexString;
-import org.openflow.util.LRULinkedHashMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class LearningSwitch
- implements IFloodlightModule, ILearningSwitchService, IOFMessageListener {
- protected static Logger log = LoggerFactory.getLogger(LearningSwitch.class);
-
- // Module dependencies
- protected IFloodlightProviderService floodlightProvider;
- protected ICounterStoreService counterStore;
- protected IRestApiService restApi;
-
- // Stores the learned state for each switch
- protected Map<IOFSwitch, Map<MacVlanPair,Short>> macVlanToSwitchPortMap;
-
- // flow-mod - for use in the cookie
- public static final int LEARNING_SWITCH_APP_ID = 1;
- // LOOK! This should probably go in some class that encapsulates
- // the app cookie management
- public static final int APP_ID_BITS = 12;
- public static final int APP_ID_SHIFT = (64 - APP_ID_BITS);
- public static final long LEARNING_SWITCH_COOKIE = (long) (LEARNING_SWITCH_APP_ID & ((1 << APP_ID_BITS) - 1)) << APP_ID_SHIFT;
-
- // more flow-mod defaults
- protected static final short IDLE_TIMEOUT_DEFAULT = 5;
- protected static final short HARD_TIMEOUT_DEFAULT = 0;
- protected static final short PRIORITY_DEFAULT = 100;
-
- // for managing our map sizes
- protected static final int MAX_MACS_PER_SWITCH = 1000;
-
- // normally, setup reverse flow as well. Disable only for using cbench for comparison with NOX etc.
- protected static final boolean LEARNING_SWITCH_REVERSE_FLOW = true;
-
- /**
- * @param floodlightProvider the floodlightProvider to set
- */
- public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
- this.floodlightProvider = floodlightProvider;
- }
-
- @Override
- public String getName() {
- return "learningswitch";
- }
-
- /**
- * Adds a host to the MAC/VLAN->SwitchPort mapping
- * @param sw The switch to add the mapping to
- * @param mac The MAC address of the host to add
- * @param vlan The VLAN that the host is on
- * @param portVal The switchport that the host is on
- */
- protected void addToPortMap(IOFSwitch sw, long mac, short vlan, short portVal) {
- Map<MacVlanPair,Short> swMap = macVlanToSwitchPortMap.get(sw);
-
- if (vlan == (short) 0xffff) {
- // OFMatch.loadFromPacket sets VLAN ID to 0xffff if the packet contains no VLAN tag;
- // for our purposes that is equivalent to the default VLAN ID 0
- vlan = 0;
- }
-
- if (swMap == null) {
- // May be accessed by REST API so we need to make it thread safe
- swMap = Collections.synchronizedMap(new LRULinkedHashMap<MacVlanPair,Short>(MAX_MACS_PER_SWITCH));
- macVlanToSwitchPortMap.put(sw, swMap);
- }
- swMap.put(new MacVlanPair(mac, vlan), portVal);
- }
-
- /**
- * Removes a host from the MAC/VLAN->SwitchPort mapping
- * @param sw The switch to remove the mapping from
- * @param mac The MAC address of the host to remove
- * @param vlan The VLAN that the host is on
- */
- protected void removeFromPortMap(IOFSwitch sw, long mac, short vlan) {
- if (vlan == (short) 0xffff) {
- vlan = 0;
- }
- Map<MacVlanPair,Short> swMap = macVlanToSwitchPortMap.get(sw);
- if (swMap != null)
- swMap.remove(new MacVlanPair(mac, vlan));
- }
-
- /**
- * Get the port that a MAC/VLAN pair is associated with
- * @param sw The switch to get the mapping from
- * @param mac The MAC address to get
- * @param vlan The VLAN number to get
- * @return The port the host is on
- */
- public Short getFromPortMap(IOFSwitch sw, long mac, short vlan) {
- if (vlan == (short) 0xffff) {
- vlan = 0;
- }
- Map<MacVlanPair,Short> swMap = macVlanToSwitchPortMap.get(sw);
- if (swMap != null)
- return swMap.get(new MacVlanPair(mac, vlan));
-
- // if none found
- return null;
- }
-
- /**
- * Clears the MAC/VLAN -> SwitchPort map for all switches
- */
- public void clearLearnedTable() {
- macVlanToSwitchPortMap.clear();
- }
-
- /**
- * Clears the MAC/VLAN -> SwitchPort map for a single switch
- * @param sw The switch to clear the mapping for
- */
- public void clearLearnedTable(IOFSwitch sw) {
- Map<MacVlanPair, Short> swMap = macVlanToSwitchPortMap.get(sw);
- if (swMap != null)
- swMap.clear();
- }
-
- @Override
- public synchronized Map<IOFSwitch, Map<MacVlanPair,Short>> getTable() {
- return macVlanToSwitchPortMap;
- }
-
- /**
- * Writes a OFFlowMod to a switch.
- * @param sw The switch tow rite the flowmod to.
- * @param command The FlowMod actions (add, delete, etc).
- * @param bufferId The buffer ID if the switch has buffered the packet.
- * @param match The OFMatch structure to write.
- * @param outPort The switch port to output it to.
- */
- private void writeFlowMod(IOFSwitch sw, short command, int bufferId,
- OFMatch match, short outPort) {
- // from openflow 1.0 spec - need to set these on a struct ofp_flow_mod:
- // struct ofp_flow_mod {
- // struct ofp_header header;
- // struct ofp_match match; /* Fields to match */
- // uint64_t cookie; /* Opaque controller-issued identifier. */
- //
- // /* Flow actions. */
- // uint16_t command; /* One of OFPFC_*. */
- // uint16_t idle_timeout; /* Idle time before discarding (seconds). */
- // uint16_t hard_timeout; /* Max time before discarding (seconds). */
- // uint16_t priority; /* Priority level of flow entry. */
- // uint32_t buffer_id; /* Buffered packet to apply to (or -1).
- // Not meaningful for OFPFC_DELETE*. */
- // uint16_t out_port; /* For OFPFC_DELETE* commands, require
- // matching entries to include this as an
- // output port. A value of OFPP_NONE
- // indicates no restriction. */
- // uint16_t flags; /* One of OFPFF_*. */
- // struct ofp_action_header actions[0]; /* The action length is inferred
- // from the length field in the
- // header. */
- // };
-
- OFFlowMod flowMod = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
- flowMod.setMatch(match);
- flowMod.setCookie(LearningSwitch.LEARNING_SWITCH_COOKIE);
- flowMod.setCommand(command);
- flowMod.setIdleTimeout(LearningSwitch.IDLE_TIMEOUT_DEFAULT);
- flowMod.setHardTimeout(LearningSwitch.HARD_TIMEOUT_DEFAULT);
- flowMod.setPriority(LearningSwitch.PRIORITY_DEFAULT);
- flowMod.setBufferId(bufferId);
- flowMod.setOutPort((command == OFFlowMod.OFPFC_DELETE) ? outPort : OFPort.OFPP_NONE.getValue());
- flowMod.setFlags((command == OFFlowMod.OFPFC_DELETE) ? 0 : (short) (1 << 0)); // OFPFF_SEND_FLOW_REM
-
- // set the ofp_action_header/out actions:
- // from the openflow 1.0 spec: need to set these on a struct ofp_action_output:
- // uint16_t type; /* OFPAT_OUTPUT. */
- // uint16_t len; /* Length is 8. */
- // uint16_t port; /* Output port. */
- // uint16_t max_len; /* Max length to send to controller. */
- // type/len are set because it is OFActionOutput,
- // and port, max_len are arguments to this constructor
- flowMod.setActions(Arrays.asList((OFAction) new OFActionOutput(outPort, (short) 0xffff)));
- flowMod.setLength((short) (OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH));
-
- if (log.isTraceEnabled()) {
- log.trace("{} {} flow mod {}",
- new Object[]{ sw, (command == OFFlowMod.OFPFC_DELETE) ? "deleting" : "adding", flowMod });
- }
-
- counterStore.updatePktOutFMCounterStore(sw, flowMod);
-
- // and write it out
- try {
- sw.write(flowMod, null);
- } catch (IOException e) {
- log.error("Failed to write {} to switch {}", new Object[]{ flowMod, sw }, e);
- }
- }
-
- /**
- * Writes an OFPacketOut message to a switch.
- * @param sw The switch to write the PacketOut to.
- * @param packetInMessage The corresponding PacketIn.
- * @param egressPort The switchport to output the PacketOut.
- */
- private void writePacketOutForPacketIn(IOFSwitch sw,
- OFPacketIn packetInMessage,
- short egressPort) {
- // from openflow 1.0 spec - need to set these on a struct ofp_packet_out:
- // uint32_t buffer_id; /* ID assigned by datapath (-1 if none). */
- // uint16_t in_port; /* Packet's input port (OFPP_NONE if none). */
- // uint16_t actions_len; /* Size of action array in bytes. */
- // struct ofp_action_header actions[0]; /* Actions. */
- /* uint8_t data[0]; */ /* Packet data. The length is inferred
- from the length field in the header.
- (Only meaningful if buffer_id == -1.) */
-
- OFPacketOut packetOutMessage = (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
- short packetOutLength = (short)OFPacketOut.MINIMUM_LENGTH; // starting length
-
- // Set buffer_id, in_port, actions_len
- packetOutMessage.setBufferId(packetInMessage.getBufferId());
- packetOutMessage.setInPort(packetInMessage.getInPort());
- packetOutMessage.setActionsLength((short)OFActionOutput.MINIMUM_LENGTH);
- packetOutLength += OFActionOutput.MINIMUM_LENGTH;
-
- // set actions
- List<OFAction> actions = new ArrayList<OFAction>(1);
- actions.add(new OFActionOutput(egressPort, (short) 0));
- packetOutMessage.setActions(actions);
-
- // set data - only if buffer_id == -1
- if (packetInMessage.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
- byte[] packetData = packetInMessage.getPacketData();
- packetOutMessage.setPacketData(packetData);
- packetOutLength += (short)packetData.length;
- }
-
- // finally, set the total length
- packetOutMessage.setLength(packetOutLength);
-
- // and write it out
- try {
- counterStore.updatePktOutFMCounterStore(sw, packetOutMessage);
- sw.write(packetOutMessage, null);
- } catch (IOException e) {
- log.error("Failed to write {} to switch {}: {}", new Object[]{ packetOutMessage, sw, e });
- }
- }
-
- /**
- * Processes a OFPacketIn message. If the switch has learned the MAC/VLAN to port mapping
- * for the pair it will write a FlowMod for. If the mapping has not been learned the
- * we will flood the packet.
- * @param sw
- * @param pi
- * @param cntx
- * @return
- */
- private Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
- // Read in packet data headers by using OFMatch
- OFMatch match = new OFMatch();
- match.loadFromPacket(pi.getPacketData(), pi.getInPort());
- Long sourceMac = Ethernet.toLong(match.getDataLayerSource());
- Long destMac = Ethernet.toLong(match.getDataLayerDestination());
- Short vlan = match.getDataLayerVirtualLan();
- if ((destMac & 0xfffffffffff0L) == 0x0180c2000000L) {
- if (log.isTraceEnabled()) {
- log.trace("ignoring packet addressed to 802.1D/Q reserved addr: switch {} vlan {} dest MAC {}",
- new Object[]{ sw, vlan, HexString.toHexString(destMac) });
- }
- return Command.STOP;
- }
- if ((sourceMac & 0x010000000000L) == 0) {
- // If source MAC is a unicast address, learn the port for this MAC/VLAN
- this.addToPortMap(sw, sourceMac, vlan, pi.getInPort());
- }
-
- // Now output flow-mod and/or packet
- Short outPort = getFromPortMap(sw, destMac, vlan);
- if (outPort == null) {
- // If we haven't learned the port for the dest MAC/VLAN, flood it
- // Don't flood broadcast packets if the broadcast is disabled.
- // XXX For LearningSwitch this doesn't do much. The sourceMac is removed
- // from port map whenever a flow expires, so you would still see
- // a lot of floods.
- this.writePacketOutForPacketIn(sw, pi, OFPort.OFPP_FLOOD.getValue());
- } else if (outPort == match.getInputPort()) {
- log.trace("ignoring packet that arrived on same port as learned destination:"
- + " switch {} vlan {} dest MAC {} port {}",
- new Object[]{ sw, vlan, HexString.toHexString(destMac), outPort });
- } else {
- // Add flow table entry matching source MAC, dest MAC, VLAN and input port
- // that sends to the port we previously learned for the dest MAC/VLAN. Also
- // add a flow table entry with source and destination MACs reversed, and
- // input and output ports reversed. When either entry expires due to idle
- // timeout, remove the other one. This ensures that if a device moves to
- // a different port, a constant stream of packets headed to the device at
- // its former location does not keep the stale entry alive forever.
- // FIXME: current HP switches ignore DL_SRC and DL_DST fields, so we have to match on
- // NW_SRC and NW_DST as well
- match.setWildcards(((Integer)sw.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).intValue()
- & ~OFMatch.OFPFW_IN_PORT
- & ~OFMatch.OFPFW_DL_VLAN & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_DL_DST
- & ~OFMatch.OFPFW_NW_SRC_MASK & ~OFMatch.OFPFW_NW_DST_MASK);
- this.writeFlowMod(sw, OFFlowMod.OFPFC_ADD, pi.getBufferId(), match, outPort);
- if (LEARNING_SWITCH_REVERSE_FLOW) {
- this.writeFlowMod(sw, OFFlowMod.OFPFC_ADD, -1, match.clone()
- .setDataLayerSource(match.getDataLayerDestination())
- .setDataLayerDestination(match.getDataLayerSource())
- .setNetworkSource(match.getNetworkDestination())
- .setNetworkDestination(match.getNetworkSource())
- .setTransportSource(match.getTransportDestination())
- .setTransportDestination(match.getTransportSource())
- .setInputPort(outPort),
- match.getInputPort());
- }
- }
- return Command.CONTINUE;
- }
-
- /**
- * Processes a flow removed message. We will delete the learned MAC/VLAN mapping from
- * the switch's table.
- * @param sw The switch that sent the flow removed message.
- * @param flowRemovedMessage The flow removed message.
- * @return Whether to continue processing this message or stop.
- */
- private Command processFlowRemovedMessage(IOFSwitch sw, OFFlowRemoved flowRemovedMessage) {
- if (flowRemovedMessage.getCookie() != LearningSwitch.LEARNING_SWITCH_COOKIE) {
- return Command.CONTINUE;
- }
- if (log.isTraceEnabled()) {
- log.trace("{} flow entry removed {}", sw, flowRemovedMessage);
- }
- OFMatch match = flowRemovedMessage.getMatch();
- // When a flow entry expires, it means the device with the matching source
- // MAC address and VLAN either stopped sending packets or moved to a different
- // port. If the device moved, we can't know where it went until it sends
- // another packet, allowing us to re-learn its port. Meanwhile we remove
- // it from the macVlanToPortMap to revert to flooding packets to this device.
- this.removeFromPortMap(sw, Ethernet.toLong(match.getDataLayerSource()),
- match.getDataLayerVirtualLan());
-
- // Also, if packets keep coming from another device (e.g. from ping), the
- // corresponding reverse flow entry will never expire on its own and will
- // send the packets to the wrong port (the matching input port of the
- // expired flow entry), so we must delete the reverse entry explicitly.
- this.writeFlowMod(sw, OFFlowMod.OFPFC_DELETE, -1, match.clone()
- .setWildcards(((Integer)sw.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).intValue()
- & ~OFMatch.OFPFW_DL_VLAN & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_DL_DST
- & ~OFMatch.OFPFW_NW_SRC_MASK & ~OFMatch.OFPFW_NW_DST_MASK)
- .setDataLayerSource(match.getDataLayerDestination())
- .setDataLayerDestination(match.getDataLayerSource())
- .setNetworkSource(match.getNetworkDestination())
- .setNetworkDestination(match.getNetworkSource())
- .setTransportSource(match.getTransportDestination())
- .setTransportDestination(match.getTransportSource()),
- match.getInputPort());
- return Command.CONTINUE;
- }
-
- // IOFMessageListener
-
- @Override
- public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
- switch (msg.getType()) {
- case PACKET_IN:
- return this.processPacketInMessage(sw, (OFPacketIn) msg, cntx);
- case FLOW_REMOVED:
- return this.processFlowRemovedMessage(sw, (OFFlowRemoved) msg);
- case ERROR:
- log.info("received an error {} from switch {}", (OFError) msg, sw);
- return Command.CONTINUE;
- default:
- break;
- }
- log.error("received an unexpected message {} from switch {}", msg, sw);
- return Command.CONTINUE;
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return false;
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return false;
- }
-
- // IFloodlightModule
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(ILearningSwitchService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- m.put(ILearningSwitchService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>>
- getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(ICounterStoreService.class);
- l.add(IRestApiService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- macVlanToSwitchPortMap =
- new ConcurrentHashMap<IOFSwitch, Map<MacVlanPair,Short>>();
- floodlightProvider =
- context.getServiceImpl(IFloodlightProviderService.class);
- counterStore =
- context.getServiceImpl(ICounterStoreService.class);
- restApi =
- context.getServiceImpl(IRestApiService.class);
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- floodlightProvider.addOFMessageListener(OFType.FLOW_REMOVED, this);
- floodlightProvider.addOFMessageListener(OFType.ERROR, this);
- restApi.addRestletRoutable(new LearningSwitchWebRoutable());
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchTable.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchTable.java
deleted file mode 100644
index 19f8bf5..0000000
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchTable.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package net.floodlightcontroller.learningswitch;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.types.MacVlanPair;
-
-import org.openflow.util.HexString;
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class LearningSwitchTable extends ServerResource {
- protected static Logger log = LoggerFactory.getLogger(LearningSwitchTable.class);
-
- protected Map<String, Object> formatTableEntry(MacVlanPair key, short port) {
- Map<String, Object> entry = new HashMap<String, Object>();
- entry.put("mac", HexString.toHexString(key.mac));
- entry.put("vlan", key.vlan);
- entry.put("port", port);
- return entry;
- }
-
- protected List<Map<String, Object>> getOneSwitchTable(Map<MacVlanPair, Short> switchMap) {
- List<Map<String, Object>> switchTable = new ArrayList<Map<String, Object>>();
- for (Entry<MacVlanPair, Short> entry : switchMap.entrySet()) {
- switchTable.add(formatTableEntry(entry.getKey(), entry.getValue()));
- }
- return switchTable;
- }
-
- @Get("json")
- public Map<String, List<Map<String, Object>>> getSwitchTableJson() {
- ILearningSwitchService lsp =
- (ILearningSwitchService)getContext().getAttributes().
- get(ILearningSwitchService.class.getCanonicalName());
-
- Map<IOFSwitch, Map<MacVlanPair,Short>> table = lsp.getTable();
- Map<String, List<Map<String, Object>>> allSwitchTableJson = new HashMap<String, List<Map<String, Object>>>();
-
- String switchId = (String) getRequestAttributes().get("switch");
- if (switchId.toLowerCase().equals("all")) {
- for (IOFSwitch sw : table.keySet()) {
- allSwitchTableJson.put(HexString.toHexString(sw.getId()), getOneSwitchTable(table.get(sw)));
- }
- } else {
- try {
- IFloodlightProviderService floodlightProvider =
- (IFloodlightProviderService)getContext().getAttributes().
- get(IFloodlightProviderService.class.getCanonicalName());
- long dpid = HexString.toLong(switchId);
- IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
- allSwitchTableJson.put(HexString.toHexString(sw.getId()), getOneSwitchTable(table.get(sw)));
- } catch (NumberFormatException e) {
- log.error("Could not decode switch ID = " + switchId);
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
- }
- }
-
- return allSwitchTableJson;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchWebRoutable.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchWebRoutable.java
deleted file mode 100644
index 76c30cb..0000000
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchWebRoutable.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package net.floodlightcontroller.learningswitch;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-public class LearningSwitchWebRoutable implements RestletRoutable {
-
- @Override
- public Restlet getRestlet(Context context) {
- Router router = new Router(context);
- router.attach("/table/{switch}/json", LearningSwitchTable.class);
- return router;
- }
-
- @Override
- public String basePath() {
- return "/wm/learningswitch";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
deleted file mode 100644
index d62d65b..0000000
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
+++ /dev/null
@@ -1,270 +0,0 @@
-package net.floodlightcontroller.linkdiscovery.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoSwitchService;
-import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
-import net.floodlightcontroller.linkdiscovery.ILinkStorage;
-import net.floodlightcontroller.linkdiscovery.LinkInfo;
-import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.GraphDBConnection.Transaction;
-
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.thinkaurelius.titan.core.TitanException;
-import com.tinkerpop.blueprints.Direction;
-import com.tinkerpop.blueprints.Edge;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-import com.tinkerpop.pipes.PipeFunction;
-import com.tinkerpop.pipes.transform.PathPipe;
-
-public class LinkStorageImpl implements ILinkStorage {
-
- protected static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
- protected String conf;
-
- @Override
- public void update(Link link, DM_OPERATION op) {
- update(link, (LinkInfo)null, op);
- }
-
- @Override
- public void update(List<Link> links, DM_OPERATION op) {
- for (Link lt: links) {
- update(lt, (LinkInfo)null, op);
- }
- }
-
- @Override
- public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
- switch (op) {
- case UPDATE:
- case CREATE:
- case INSERT:
- addOrUpdateLink(link, linkinfo, op);
- break;
- case DELETE:
- deleteLink(link);
- break;
- }
- }
-
- public void addOrUpdateLink(Link lt, LinkInfo linkinfo, DM_OPERATION op) {
- GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
- IPortObject vportSrc = null, vportDst = null;
-
- log.trace("addOrUpdateLink(): op {} {} {}", new Object[]{op, lt, linkinfo});
-
- try {
- // get source port vertex
- String dpid = HexString.toHexString(lt.getSrc());
- short port = lt.getSrcPort();
- vportSrc = conn.utils().searchPort(conn, dpid, port);
-
- // get dest port vertex
- dpid = HexString.toHexString(lt.getDst());
- port = lt.getDstPort();
- vportDst = conn.utils().searchPort(conn, dpid, port);
-
- if (vportSrc != null && vportDst != null) {
-
- // check if the link exists
-
- Iterable<IPortObject> currPorts = vportSrc.getLinkedPorts();
- List<IPortObject> currLinks = new ArrayList<IPortObject>();
- for (IPortObject V : currPorts) {
- currLinks.add(V);
- }
-
- if (currLinks.contains(vportDst)) {
- // TODO: update linkinfo
- if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
- log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
- new Object[]{op, lt, vportSrc, vportDst});
- }
- } else {
- vportSrc.setLinkPort(vportDst);
-
- conn.endTx(Transaction.COMMIT);
- log.debug("addOrUpdateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
- }
- } else {
- log.error("addOrUpdateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
- // conn.endTx(Transaction.ROLLBACK);
- }
- } catch (TitanException e) {
- /*
- * retry till we succeed?
- */
- e.printStackTrace();
- log.error("addOrUpdateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
- }
- }
-
- @Override
- public void deleteLinks(List<Link> links) {
-
- for (Link lt : links) {
- deleteLink(lt);
- }
- }
-
-
- @Override
- public void deleteLink(Link lt) {
- GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
- IPortObject vportSrc = null, vportDst = null;
- int count = 0;
-
- log.debug("deleteLink(): {}", lt);
-
- try {
- // get source port vertex
- String dpid = HexString.toHexString(lt.getSrc());
- short port = lt.getSrcPort();
- vportSrc = conn.utils().searchPort(conn, dpid, port);
-
- // get dst port vertex
- dpid = HexString.toHexString(lt.getDst());
- port = lt.getDstPort();
- vportDst = conn.utils().searchPort(conn, dpid, port);
- // FIXME: This needs to remove all edges
-
- if (vportSrc != null && vportDst != null) {
-
- /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
- log.debug("deleteLink(): {} in {} out {}",
- new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
- if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
- graph.removeEdge(e);
- count++;
- }
- }*/
- vportSrc.removeLink(vportDst);
- conn.endTx(Transaction.COMMIT);
- log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
- lt, vportSrc, vportDst});
-
- } else {
- log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
-// conn.endTx(Transaction.ROLLBACK);
- }
-
- } catch (TitanException e) {
- /*
- * retry till we succeed?
- */
- log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
- e.printStackTrace();
- }
- }
-
- // TODO: Fix me
- @Override
- public List<Link> getLinks(Long dpid, short port) {
- GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
- IPortObject vportSrc, vportDst;
- List<Link> links = null;
- Link lt;
-
- vportSrc = conn.utils().searchPort(conn, HexString.toHexString(dpid), port);
- if (vportSrc != null) {
-
- for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
- if (e.getLabel().equals("link")) {
- break;
- }
- }
- }
- return null;
- }
-
- @Override
- public void init(String conf) {
- //TODO extract the DB location from properties
-
- this.conf = conf;
-
- }
-
- @Override
- public void deleteLinksOnPort(Long dpid, short port) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public List<Link> getLinks(String dpid) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public List<Link> getActiveLinks() {
-
- GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
-
- Iterable<ISwitchObject> switches = conn.utils().getActiveSwitches(conn);
-
- List<Link> links = new ArrayList<Link>();
- for (ISwitchObject sw : switches) {
- GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
- ExtractLink extractor = new ExtractLink();
-
- pipe.start(sw.asVertex());
- pipe.enablePath(true);
- pipe.out("on").out("link").in("on").path().step(extractor);
-
- while (pipe.hasNext() ) {
- Link l = pipe.next();
- links.add(l);
- }
-
- }
- return links;
- }
-
- static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
-
- @Override
- public Link compute(PathPipe<Vertex> pipe ) {
- // TODO Auto-generated method stub
- long s_dpid = 0;
- long d_dpid = 0;
- short s_port = 0;
- short d_port = 0;
- List<Vertex> V = new ArrayList<Vertex>();
- V = pipe.next();
- Vertex src_sw = V.get(0);
- Vertex dest_sw = V.get(3);
- Vertex src_port = V.get(1);
- Vertex dest_port = V.get(2);
- s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
- d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
- s_port = (Short) src_port.getProperty("number");
- d_port = (Short) dest_port.getProperty("number");
-
- Link l = new Link(s_dpid,s_port,d_dpid,d_port);
-
- return l;
- }
- }
-
- public void finalize() {
- close();
- }
-
- @Override
- public void close() {
- // TODO Auto-generated method stub
-// graph.shutdown();
- }
-
-
-}
diff --git a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerClient.java b/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerClient.java
deleted file mode 100644
index abed853..0000000
--- a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerClient.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package net.floodlightcontroller.packetstreamer;
-
-import net.floodlightcontroller.packetstreamer.thrift.*;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import org.apache.thrift.TException;
-import org.apache.thrift.transport.TFramedTransport;
-import org.apache.thrift.transport.TTransport;
-import org.apache.thrift.transport.TSocket;
-import org.apache.thrift.transport.TTransportException;
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.protocol.TProtocol;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The PacketStreamer Sample Client.
- */
-public class PacketStreamerClient {
- protected static Logger log = LoggerFactory.getLogger(PacketStreamerClient.class);
-
- /**
- * Main function entry point;
- * @param args
- */
- public static void main(String [] args) {
- try {
- int serverPort = Integer.parseInt(System.getProperty("net.floodlightcontroller.packetstreamer.port", "9090"));
- TTransport transport;
- transport = new TFramedTransport(new TSocket("localhost", serverPort));
- transport.open();
-
-
- TProtocol protocol = new TBinaryProtocol(transport);
- PacketStreamer.Client client = new PacketStreamer.Client(protocol);
-
- sendPackets(client, (short)2, OFMessageType.PACKET_IN, true);
- log.debug("Terminate session1");
- client.terminateSession("session1");
-
- transport.close();
- } catch (TException x) {
- x.printStackTrace();
- }
- }
-
- /**
- * Send test packets of the given OFMessageType to the packetstreamer server;
- * @param client Packetstreamer client object
- * @param numPackets number of test packets to be sent
- * @param ofType OFMessageType of the test packets
- * @param sync true if send with synchronous interface, false for asynchronous interface
- * @throws TException
- */
- private static void sendPackets(PacketStreamer.Client client, short numPackets, OFMessageType ofType, boolean sync)
- throws TException {
- while (numPackets-- > 0) {
- Message msg = new Message();
- Packet packet = new Packet();
-
- List<String> sids = new ArrayList<String>();
- sids.add("session1");
- sids.add("session2");
- msg.setSessionIDs(sids);
- packet.setMessageType(ofType);
- long sw_dpid = numPackets/40 + 1;
- packet.setSwPortTuple(new SwitchPortTuple(sw_dpid, (short)(numPackets - (sw_dpid-1)*40)));
-
- String strData = "New data, sequence " + numPackets;
- packet.setData(strData.getBytes());
- msg.setPacket(packet);
-
- try {
- if (sync) {
- client.pushMessageSync(msg);
- log.debug("Send packet sync: " + msg.toString());
- } else {
- client.pushMessageAsync(msg);
- log.debug("Send packet sync: " + msg.toString());
- }
- } catch (TTransportException e) {
- log.error(e.toString());
- }
-
- try {
- Thread.sleep(100);
- } catch (Exception e) {}
- }
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerHandler.java b/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerHandler.java
deleted file mode 100644
index 903295e..0000000
--- a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerHandler.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package net.floodlightcontroller.packetstreamer;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.annotations.LogMessageDocs;
-import net.floodlightcontroller.packetstreamer.thrift.*;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The PacketStreamer handler class that implements the service APIs.
- */
-@LogMessageCategory("OpenFlow Message Tracing")
-public class PacketStreamerHandler implements PacketStreamer.Iface {
-
- /**
- * The queue wrapper class that contains the queue for the streamed packets.
- */
- protected class SessionQueue {
- protected BlockingQueue<ByteBuffer> pQueue;
-
- /**
- * The queue wrapper constructor
- */
- public SessionQueue() {
- this.pQueue = new LinkedBlockingQueue<ByteBuffer>();
- }
-
- /**
- * The access method to get to the internal queue.
- */
- public BlockingQueue<ByteBuffer> getQueue() {
- return this.pQueue;
- }
- }
-
- /**
- * The class logger object
- */
- protected static Logger log =
- LoggerFactory.getLogger(PacketStreamerServer.class);
-
- /**
- * A sessionId-to-queue mapping
- */
- protected Map<String, SessionQueue> msgQueues;
-
- /**
- * The handler's constructor
- */
- public PacketStreamerHandler() {
- this.msgQueues = new ConcurrentHashMap<String, SessionQueue>();
- }
-
- /**
- * The implementation for getPackets() function.
- * This is a blocking API.
- *
- * @param sessionid
- * @return A list of packets associated with the session
- */
- @Override
- @LogMessageDocs({
- @LogMessageDoc(level="ERROR",
- message="Interrupted while waiting for session start",
- explanation="The thread was interrupted waiting " +
- "for the packet streamer session to start",
- recommendation=LogMessageDoc.CHECK_CONTROLLER),
- @LogMessageDoc(level="ERROR",
- message="Interrupted while waiting for packets",
- explanation="The thread was interrupted waiting " +
- "for packets",
- recommendation=LogMessageDoc.CHECK_CONTROLLER)
- })
- public List<ByteBuffer> getPackets(String sessionid)
- throws org.apache.thrift.TException {
- List<ByteBuffer> packets = new ArrayList<ByteBuffer>();
- int count = 0;
-
- while (!msgQueues.containsKey(sessionid) && count++ < 100) {
- log.debug("Queue for session {} doesn't exist yet.", sessionid);
- try {
- Thread.sleep(100); // Wait 100 ms to check again.
- } catch (InterruptedException e) {
- log.error("Interrupted while waiting for session start");
- }
- }
-
- if (count < 100) {
- SessionQueue pQueue = msgQueues.get(sessionid);
- BlockingQueue<ByteBuffer> queue = pQueue.getQueue();
- // Block if queue is empty
- try {
- packets.add(queue.take());
- queue.drainTo(packets);
- } catch (InterruptedException e) {
- log.error("Interrupted while waiting for packets");
- }
- }
-
- return packets;
- }
-
- /**
- * The implementation for pushMessageSync() function.
- *
- * @param msg
- * @return 1 for success, 0 for failure
- * @throws TException
- */
- @Override
- @LogMessageDocs({
- @LogMessageDoc(level="ERROR",
- message="Could not push empty message",
- explanation="An empty message was sent to the packet streamer",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG),
- @LogMessageDoc(level="ERROR",
- message="queue for session {sessionId} is null",
- explanation="The queue for the packet streamer session " +
- "is missing",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
- })
-
- public int pushMessageSync(Message msg)
- throws org.apache.thrift.TException {
-
- if (msg == null) {
- log.error("Could not push empty message");
- return 0;
- }
-
- List<String> sessionids = msg.getSessionIDs();
- for (String sid : sessionids) {
- SessionQueue pQueue = null;
-
- if (!msgQueues.containsKey(sid)) {
- pQueue = new SessionQueue();
- msgQueues.put(sid, pQueue);
- } else {
- pQueue = msgQueues.get(sid);
- }
-
- log.debug("pushMessageSync: SessionId: " + sid +
- " Receive a message, " + msg.toString() + "\n");
- ByteBuffer bb = ByteBuffer.wrap(msg.getPacket().getData());
- //ByteBuffer dst = ByteBuffer.wrap(msg.getPacket().toString().getBytes());
- BlockingQueue<ByteBuffer> queue = pQueue.getQueue();
- if (queue != null) {
- if (!queue.offer(bb)) {
- log.error("Failed to queue message for session: " + sid);
- } else {
- log.debug("insert a message to session: " + sid);
- }
- } else {
- log.error("queue for session {} is null", sid);
- }
- }
-
- return 1;
- }
-
- /**
- * The implementation for pushMessageAsync() function.
- *
- * @param msg
- * @throws TException
- */
- @Override
- public void pushMessageAsync(Message msg)
- throws org.apache.thrift.TException {
- pushMessageSync(msg);
- return;
- }
-
- /**
- * The implementation for terminateSession() function.
- * It removes the session to queue association.
- * @param sessionid
- * @throws TException
- */
- @Override
- public void terminateSession(String sessionid)
- throws org.apache.thrift.TException {
- if (!msgQueues.containsKey(sessionid)) {
- return;
- }
-
- SessionQueue pQueue = msgQueues.get(sessionid);
-
- log.debug("terminateSession: SessionId: " + sessionid + "\n");
- String data = "FilterTimeout";
- ByteBuffer bb = ByteBuffer.wrap(data.getBytes());
- BlockingQueue<ByteBuffer> queue = pQueue.getQueue();
- if (queue != null) {
- if (!queue.offer(bb)) {
- log.error("Failed to queue message for session: " + sessionid);
- }
- msgQueues.remove(sessionid);
- } else {
- log.error("queue for session {} is null", sessionid);
- }
- }
-}
-
diff --git a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerServer.java b/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerServer.java
deleted file mode 100644
index 4a425e0..0000000
--- a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerServer.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package net.floodlightcontroller.packetstreamer;
-
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.server.TServer;
-import org.apache.thrift.server.THsHaServer;
-import org.apache.thrift.transport.TFramedTransport;
-import org.apache.thrift.transport.TNonblockingServerSocket;
-import org.apache.thrift.transport.TNonblockingServerTransport;
-
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-// Generated code
-import net.floodlightcontroller.packetstreamer.thrift.*;
-
-/**
- * The PacketStreamer Server that brokers the packet streaming service.
- */
-@LogMessageCategory("OpenFlow Message Tracing")
-public class PacketStreamerServer {
- protected static Logger log = LoggerFactory.getLogger(PacketStreamerServer.class);
- protected static int port = 9090;
- protected static PacketStreamerHandler handler;
- protected static PacketStreamer.Processor<PacketStreamerHandler> processor;
-
-
- /**
- * Main function entry point;
- * @param args
- */
- public static void main(String [] args) {
- try {
- port = Integer.parseInt(System.getProperty("net.floodlightcontroller.packetstreamer.port", "9090"));
-
- handler = new PacketStreamerHandler();
- processor = new PacketStreamer.Processor<PacketStreamerHandler>(handler);
-
- Runnable simple = new Runnable() {
- public void run() {
- hshaServer(processor);
- }
- };
-
- new Thread(simple).start();
- } catch (Exception x) {
- x.printStackTrace();
- }
- }
-
-
- /**
- * The function to create a thrift Half-Sync and Half-Async Server.
- * @param processor
- */
- public static void hshaServer(PacketStreamer.Processor<PacketStreamerHandler> processor) {
- try {
- TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(port);
- THsHaServer.Args args = new THsHaServer.Args(serverTransport);
- args.processor(processor);
- args.transportFactory(new TFramedTransport.Factory());
- args.protocolFactory(new TBinaryProtocol.Factory(true, true));
- TServer server = new THsHaServer(args);
-
- log.info("Starting the packetstreamer hsha server on port {} ...", port);
- server.serve();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/restclient/RestClient.java b/src/main/java/net/floodlightcontroller/restclient/RestClient.java
deleted file mode 100644
index 541b42d..0000000
--- a/src/main/java/net/floodlightcontroller/restclient/RestClient.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package net.floodlightcontroller.restclient;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-import net.sf.json.JSONSerializer;
-
-
-public class RestClient {
-
- public static void get (String str) {
-
- if (str == null)
- return;
-
- try {
-
- URL url = new URL(str);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- conn.setRequestProperty("Accept", "application/json");
-
- if (conn.getResponseCode() != 200) {
- throw new RuntimeException("Failed : HTTP error code : "
- + conn.getResponseCode());
- }
-
- if (conn.getContentType().equals("application/json"))
- { }else{
- System.out.print("The content received is not json format!");
- }
-
- BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
- StringBuffer res = new StringBuffer();
- String line;
- while ((line = br.readLine()) != null) {
- res.append(line);
- }
-
- String res2=res.toString().replaceAll("\"", "'");
- JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(res2);
- JSONArray rib_json_array = jsonObj.getJSONArray("rib");
- String router_id = jsonObj.getString("router-id");
-
- int size = rib_json_array.size();
- System.out.print("size:"+size+"\n");
- for (int j = 0; j < size; j++) {
- JSONObject second_json_object = rib_json_array.getJSONObject(j);
- String prefix = second_json_object.getString("prefix");
- String nexthop = second_json_object.getString("nexthop");
-
- //insert each rib entry into the local rib;
- RestClient.post("http://127.0.0.1:8090/wm/bgp/"+router_id+"/"+prefix+"/"+nexthop);
-
-
-
- }
- br.close();
- conn.disconnect();
-
- } catch (MalformedURLException e) {
-
- e.printStackTrace();
-
- } catch (IOException e) {
-
- e.printStackTrace();
-
- }
- }
-
-public static void post (String str) {
-
- if (str == null)
- return;
-
- try {
-
- URL url = new URL(str);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setDoOutput(true);
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Content-Type", "application/json");
-
- if (conn.getResponseCode() != 200) {
- throw new RuntimeException("Failed : HTTP error code : "
- + conn.getResponseCode());
- }
-
- conn.disconnect();
-
- } catch (MalformedURLException e) {
-
- e.printStackTrace();
-
- } catch (IOException e) {
-
- e.printStackTrace();
-
- }
- }
-
-
-public static void delete (String str) {
-
- if (str == null)
- return;
-
- try {
-
- URL url = new URL(str);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("DELETE");
- conn.setRequestProperty("Accept", "application/json");
-
-
- if (conn.getResponseCode() != 200) {
- throw new RuntimeException("Failed : HTTP error code : "
- + conn.getResponseCode());
- }
-
- conn.disconnect();
-
- } catch (MalformedURLException e) {
-
- e.printStackTrace();
-
- } catch (IOException e) {
-
- e.printStackTrace();
-
- }
-}
-
-
-}
diff --git a/src/main/java/net/floodlightcontroller/restserver/RestApiServer.java b/src/main/java/net/floodlightcontroller/restserver/RestApiServer.java
index 2ca8483..c158fdd 100644
--- a/src/main/java/net/floodlightcontroller/restserver/RestApiServer.java
+++ b/src/main/java/net/floodlightcontroller/restserver/RestApiServer.java
@@ -6,12 +6,18 @@
import java.util.List;
import java.util.Map;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+
import org.restlet.Application;
import org.restlet.Component;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
+import org.restlet.Server;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Status;
@@ -24,17 +30,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
public class RestApiServer
implements IFloodlightModule, IRestApiService {
protected static Logger logger = LoggerFactory.getLogger(RestApiServer.class);
protected List<RestletRoutable> restlets;
protected FloodlightModuleContext fmlContext;
protected int restPort = 8080;
+ protected String numThreads = null;
// ***********
// Application
@@ -98,7 +100,11 @@
// Start listening for REST requests
try {
final Component component = new Component();
- component.getServers().add(Protocol.HTTP, restPort);
+ Server server = component.getServers().add(Protocol.HTTP, restPort);
+ if (numThreads != null){
+ logger.debug("Setting number of REST API threads to {}", numThreads);
+ server.getContext().getParameters().add("defaultThreads", numThreads);
+ }
component.getClients().add(Protocol.CLAP);
component.getDefaultHost().attach(this);
component.start();
@@ -179,6 +185,11 @@
restPort = Integer.parseInt(port);
}
logger.debug("REST port set to {}", restPort);
+
+ String numThreads = configOptions.get("dispatcherthreads");
+ if (numThreads != null) {
+ this.numThreads = numThreads;
+ }
}
@Override
diff --git a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
index cc62e82..31032c9 100644
--- a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
+++ b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
@@ -5,7 +5,7 @@
import java.util.Set;
import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
public interface ITopologyService extends IFloodlightService {
diff --git a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
index 6ac8f29..4983529 100644
--- a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
+++ b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
@@ -18,16 +18,6 @@
protected short portId; // switch port id
/**
- * A copy constructor for NodePortTuple.
- *
- * @param other the object to copy the state from.
- */
- public NodePortTuple(NodePortTuple other) {
- this.nodeId = other.nodeId;
- this.portId = other.portId;
- }
-
- /**
* Creates a NodePortTuple
* @param nodeId The DPID of the switch
* @param portId The port of the switch
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
index ba17483..a47a5f2 100644
--- a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
@@ -28,8 +28,6 @@
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.core.util.SingletonTask;
import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
import net.floodlightcontroller.packet.BSN;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.LLDP;
@@ -39,6 +37,8 @@
import net.floodlightcontroller.routing.Route;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.topology.web.TopologyWebRoutable;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
@@ -871,7 +871,8 @@
if (log.isTraceEnabled()) {
log.trace("Applying update: {}", update);
}
- if (update.getOperation() == UpdateOperation.LINK_UPDATED) {
+ if (update.getOperation() == UpdateOperation.LINK_UPDATED ||
+ update.getOperation() == UpdateOperation.LINK_ADDED ) {
addOrUpdateLink(update.getSrc(), update.getSrcPort(),
update.getDst(), update.getDstPort(),
update.getType());
diff --git a/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java b/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
index 7989413..4f844b2 100644
--- a/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
@@ -3,8 +3,9 @@
import org.restlet.Context;
import org.restlet.routing.Router;
-import net.floodlightcontroller.linkdiscovery.web.LinksResource;
import net.floodlightcontroller.restserver.RestletRoutable;
+import net.onrc.onos.ofcontroller.linkdiscovery.web.LinksResource;
+import net.onrc.onos.ofcontroller.topology.web.RouteResource;
public class TopologyWebRoutable implements RestletRoutable {
/**
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
deleted file mode 100644
index 1fc1783..0000000
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
+++ /dev/null
@@ -1,1015 +0,0 @@
-package net.floodlightcontroller.util;
-
-import net.floodlightcontroller.util.IPv4;
-import net.floodlightcontroller.util.MACAddress;
-import net.floodlightcontroller.util.Port;
-
-import org.codehaus.jackson.annotate.JsonProperty;
-
-/**
- * The class representing a single Flow Entry action.
- *
- * A set of Flow Entry actions need to be applied to each packet.
- */
-public class FlowEntryAction {
- /**
- * Special action values.
- *
- * Those values are taken as-is from the OpenFlow-v1.0.0 specification
- * (pp 21-22).
- */
- public enum ActionValues {
- ACTION_OUTPUT ((short)0x0), // Output to switch port
- ACTION_SET_VLAN_VID ((short)0x1), // Set the 802.1q VLAN id
- ACTION_SET_VLAN_PCP ((short)0x2), // Set the 802.1q priority
- ACTION_STRIP_VLAN ((short)0x3), // Strip the 802.1q header
- ACTION_SET_DL_SRC ((short)0x4), // Ethernet source address
- ACTION_SET_DL_DST ((short)0x5), // Ethernet destination address
- ACTION_SET_NW_SRC ((short)0x6), // IP source address
- ACTION_SET_NW_DST ((short)0x7), // IP destination address
- ACTION_SET_NW_TOS ((short)0x8), // IP ToS (DSCP field, 6 bits)
- ACTION_SET_TP_SRC ((short)0x9), // TCP/UDP source port
- ACTION_SET_TP_DST ((short)0xa), // TCP/UDP destination port
- ACTION_ENQUEUE ((short)0xb), // Output to queue on port
- ACTION_VENDOR ((short)0xffff); // Vendor-specific
-
- private final short value; // The value
-
- /**
- * Constructor for a given value.
- *
- * @param value the value to use for the initialization.
- */
- private ActionValues(short value) {
- this.value = value;
- }
- }
-
- /**
- * Action structure for ACTION_OUTPUT: Output to switch port.
- */
- public class ActionOutput {
- private Port port; // Output port
- private short maxLen; // Max. length (in bytes) to send to controller
- // if the port is set to PORT_CONTROLLER
-
- /**
- * Default constructor.
- */
- public ActionOutput() {
- this.port = null;
- this.maxLen = 0;
- }
-
-
- /**
- * Constructor for a given output port and maximum length.
- *
- * @param port the output port to set.
- * @param maxLen the maximum length (in bytes) to send to controller
- * if the port is set to PORT_CONTROLLER.
- */
- public ActionOutput(Port port, short maxLen) {
- this.port = port;
- this.maxLen = maxLen;
- }
-
- /**
- * Constructor for a given output port.
- *
- * @param port the output port to set.
- */
- public ActionOutput(Port port) {
- this.port = port;
- this.maxLen = 0;
- }
-
- /**
- * Get the output port.
- *
- * @return the output port.
- */
- @JsonProperty("port")
- public Port port() {
- return this.port;
- }
-
- /**
- * Get the maximum length (in bytes) to send to controller if the
- * port is set to PORT_CONTROLLER.
- *
- * @return the maximum length (in bytes) to send to controller if the
- * port is set to PORT_CONTROLLER.
- */
- @JsonProperty("maxLen")
- public short maxLen() {
- return this.maxLen;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [port=XXX maxLen=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "port=" + port.toString();
- ret += " maxLen=" + maxLen;
- ret += "]";
-
- return ret;
- }
- }
-
- /**
- * Action structure for ACTION_SET_VLAN_VID: Set the 802.1q VLAN id
- */
- public class ActionSetVlanId {
- private short vlanId; // The VLAN ID to set
-
- /**
- * Default constructor.
- */
- public ActionSetVlanId() {
- this.vlanId = 0;
- }
-
- /**
- * Constructor for a given VLAN ID.
- *
- * @param vlanId the VLAN ID to set.
- */
- public ActionSetVlanId(short vlanId) {
- this.vlanId = vlanId;
- }
-
- /**
- * Get the VLAN ID.
- *
- * @return the VLAN ID.
- */
- @JsonProperty("vlanId")
- public short vlanId() {
- return this.vlanId;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [vlanId=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "vlanId=" + this.vlanId;
- ret += "]";
-
- return ret;
- }
- }
-
- /**
- * Action structure for ACTION_SET_VLAN_PCP: Set the 802.1q priority
- */
- public class ActionSetVlanPriority {
- private byte vlanPriority; // The VLAN priority to set
-
- /**
- * Default constructor.
- */
- public ActionSetVlanPriority() {
- this.vlanPriority = 0;
- }
-
- /**
- * Constructor for a given VLAN priority.
- *
- * @param vlanPriority the VLAN priority to set.
- */
- public ActionSetVlanPriority(byte vlanPriority) {
- this.vlanPriority = vlanPriority;
- }
-
- /**
- * Get the VLAN priority.
- *
- * @return the VLAN priority.
- */
- @JsonProperty("vlanPriority")
- public byte vlanPriority() {
- return this.vlanPriority;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [vlanPriority=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "vlanPriority=" + this.vlanPriority;
- ret += "]";
-
- return ret;
- }
- }
-
- /**
- * Action structure for ACTION_STRIP_VLAN: Strip the 802.1q header
- */
- public class ActionStripVlan {
- private boolean stripVlan; // If true, strip the VLAN header
-
- /**
- * Default constructor.
- */
- public ActionStripVlan() {
- this.stripVlan = false;
- }
-
- /**
- * Constructor for a given boolean flag.
- *
- * @param stripVlan if true, strip the VLAN header.
- */
- public ActionStripVlan(boolean stripVlan) {
- this.stripVlan = stripVlan;
- }
-
- /**
- * Get the boolean flag whether the VLAN header should be stripped.
- *
- * @return the boolean flag whether the VLAN header should be stripped.
- */
- @JsonProperty("stripVlan")
- public boolean stripVlan() {
- return this.stripVlan;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [stripVlan=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "stripVlan=" + this.stripVlan;
- ret += "]";
-
- return ret;
- }
- }
-
- /**
- * Action structure for ACTION_SET_DL_SRC and ACTION_SET_DL_DST:
- * Set the Ethernet source/destination address.
- */
- public class ActionSetEthernetAddr {
- private MACAddress addr; // The MAC address to set
-
- /**
- * Default constructor.
- */
- public ActionSetEthernetAddr() {
- this.addr = null;
- }
-
- /**
- * Constructor for a given MAC address.
- *
- * @param addr the MAC address to set.
- */
- public ActionSetEthernetAddr(MACAddress addr) {
- this.addr = addr;
- }
-
- /**
- * Get the MAC address.
- *
- * @return the MAC address.
- */
- @JsonProperty("addr")
- public MACAddress addr() {
- return this.addr;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [addr=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "addr=" + addr.toString();
- ret += "]";
-
- return ret;
- }
- }
-
- /**
- * Action structure for ACTION_SET_NW_SRC and ACTION_SET_NW_DST:
- * Set the IPv4 source/destination address.
- */
- public class ActionSetIPv4Addr {
- private IPv4 addr; // The IPv4 address to set
-
- /**
- * Default constructor.
- */
- public ActionSetIPv4Addr() {
- this.addr = null;
- }
-
- /**
- * Constructor for a given IPv4 address.
- *
- * @param addr the IPv4 address to set.
- */
- public ActionSetIPv4Addr(IPv4 addr) {
- this.addr = addr;
- }
-
- /**
- * Get the IPv4 address.
- *
- * @return the IPv4 address.
- */
- @JsonProperty("addr")
- public IPv4 addr() {
- return this.addr;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [addr=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "addr=" + addr.toString();
- ret += "]";
-
- return ret;
- }
- }
-
- /**
- * Action structure for ACTION_SET_NW_TOS:
- * Set the IP ToS (DSCP field, 6 bits).
- */
- public class ActionSetIpToS {
- private byte ipToS; // The IP ToS to set DSCP field, 6 bits)
-
- /**
- * Default constructor.
- */
- public ActionSetIpToS() {
- this.ipToS = 0;
- }
-
- /**
- * Constructor for a given IP ToS (DSCP field, 6 bits).
- *
- * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
- */
- public ActionSetIpToS(byte ipToS) {
- this.ipToS = ipToS;
- }
-
- /**
- * Get the IP ToS (DSCP field, 6 bits).
- *
- * @return the IP ToS (DSCP field, 6 bits).
- */
- @JsonProperty("ipToS")
- public byte ipToS() {
- return this.ipToS;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [ipToS=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "ipToS=" + ipToS;
- ret += "]";
-
- return ret;
- }
- }
-
- /**
- * Action structure for ACTION_SET_TP_SRC and ACTION_SET_TP_DST:
- * Set the TCP/UDP source/destination port.
- */
- public class ActionSetTcpUdpPort {
- private short port; // The TCP/UDP port to set
-
- /**
- * Default constructor.
- */
- public ActionSetTcpUdpPort() {
- this.port = 0;
- }
-
- /**
- * Constructor for a given TCP/UDP port.
- *
- * @param port the TCP/UDP port to set.
- */
- public ActionSetTcpUdpPort(short port) {
- this.port = port;
- }
-
- /**
- * Get the TCP/UDP port.
- *
- * @return the TCP/UDP port.
- */
- @JsonProperty("port")
- public short port() {
- return this.port;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [port=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "port=" + port;
- ret += "]";
-
- return ret;
- }
- }
-
- /**
- * Action structure for ACTION_ENQUEUE: Output to queue on port.
- */
- public class ActionEnqueue {
- private Port port; // Port that queue belongs. Should
- // refer to a valid physical port
- // (i.e. < PORT_MAX) or PORT_IN_PORT
- private int queueId; // Where to enqueue the packets
-
- /**
- * Default constructor.
- */
- public ActionEnqueue() {
- this.port = null;
- this.queueId = 0;
- }
-
- /**
- * Constructor for a given port and queue ID.
- *
- * @param port the port to set.
- * @param queueId the queue ID on the port.
- */
- public ActionEnqueue(Port port, int queueId) {
- this.port = port;
- this.queueId = queueId;
- }
-
- /**
- * Get the port.
- *
- * @return the port.
- */
- @JsonProperty("port")
- public Port port() {
- return this.port;
- }
-
- /**
- * Get the queue ID.
- *
- * @return the queue ID.
- */
- @JsonProperty("queueId")
- public int queueId() {
- return this.queueId;
- }
-
- /**
- * Convert the action to a string.
- *
- * The string has the following form:
- * [port=XXX queueId=XXX]
- *
- * @return the action as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "port=" + port.toString();
- ret += " queueId=" + queueId;
- ret += "]";
-
- return ret;
- }
- }
-
- private ActionValues actionType; // The action type
-
- //
- // The actions.
- // NOTE: Only one action should be set.
- //
- private ActionOutput actionOutput;
- private ActionSetVlanId actionSetVlanId;
- private ActionSetVlanPriority actionSetVlanPriority;
- private ActionStripVlan actionStripVlan;
- private ActionSetEthernetAddr actionSetEthernetSrcAddr;
- private ActionSetEthernetAddr actionSetEthernetDstAddr;
- private ActionSetIPv4Addr actionSetIPv4SrcAddr;
- private ActionSetIPv4Addr actionSetIPv4DstAddr;
- private ActionSetIpToS actionSetIpToS;
- private ActionSetTcpUdpPort actionSetTcpUdpSrcPort;
- private ActionSetTcpUdpPort actionSetTcpUdpDstPort;
- private ActionEnqueue actionEnqueue;
-
- /**
- * Default constructor.
- */
- public FlowEntryAction() {
- actionType = ActionValues.ACTION_VENDOR; // XXX: Initial value
- }
-
- /**
- * Get the action type.
- *
- * @return the action type.
- */
- @JsonProperty("actionType")
- public ActionValues actionType() { return actionType; }
-
- /**
- * Get the output action.
- *
- * @return the output action.
- */
- @JsonProperty("actionOutput")
- public ActionOutput actionOutput() { return actionOutput; }
-
- /**
- * Set the output action on a port.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionOutput")
- public void setActionOutput(ActionOutput action) {
- actionOutput = action;
- actionType = ActionValues.ACTION_OUTPUT;
- }
-
- /**
- * Set the output action on a port.
- *
- * @param port the output port to set.
- */
- public void setActionOutput(Port port) {
- actionOutput = new ActionOutput(port);
- actionType = ActionValues.ACTION_OUTPUT;
- }
-
- /**
- * Set the output action to controller.
- *
- * @param maxLen the maximum length (in bytes) to send to controller.
- */
- public void setActionOutputToController(short maxLen) {
- Port port = new Port(Port.PortValues.PORT_CONTROLLER);
- actionOutput = new ActionOutput(port, maxLen);
- actionType = ActionValues.ACTION_OUTPUT;
- }
-
- /**
- * Get the action to set the VLAN ID.
- *
- * @return the action to set the VLAN ID.
- */
- @JsonProperty("actionSetVlanId")
- public ActionSetVlanId actionSetVlanId() { return actionSetVlanId; }
-
- /**
- * Set the action to set the VLAN ID.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetVlanId")
- public void setActionSetVlanId(ActionSetVlanId action) {
- actionSetVlanId = action;
- actionType = ActionValues.ACTION_SET_VLAN_VID;
- }
-
- /**
- * Set the action to set the VLAN ID.
- *
- * @param vlanId the VLAN ID to set.
- */
- public void setActionSetVlanId(short vlanId) {
- actionSetVlanId = new ActionSetVlanId(vlanId);
- actionType = ActionValues.ACTION_SET_VLAN_VID;
- }
-
- /**
- * Get the action to set the VLAN priority.
- *
- * @return the action to set the VLAN priority.
- */
- @JsonProperty("actionSetVlanPriority")
- public ActionSetVlanPriority actionSetVlanPriority() {
- return actionSetVlanPriority;
- }
-
- /**
- * Set the action to set the VLAN priority.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetVlanPriority")
- public void setActionSetVlanPriority(ActionSetVlanPriority action) {
- actionSetVlanPriority = action;
- actionType = ActionValues.ACTION_SET_VLAN_PCP;
- }
-
- /**
- * Set the action to set the VLAN priority.
- *
- * @param vlanPriority the VLAN priority to set.
- */
- public void setActionSetVlanPriority(byte vlanPriority) {
- actionSetVlanPriority = new ActionSetVlanPriority(vlanPriority);
- actionType = ActionValues.ACTION_SET_VLAN_PCP;
- }
-
- /**
- * Get the action to strip the VLAN header.
- *
- * @return the action to strip the VLAN header.
- */
- @JsonProperty("actionStripVlan")
- public ActionStripVlan actionStripVlan() {
- return actionStripVlan;
- }
-
- /**
- * Set the action to strip the VLAN header.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionStripVlan")
- public void setActionStripVlan(ActionStripVlan action) {
- actionStripVlan = action;
- actionType = ActionValues.ACTION_STRIP_VLAN;
- }
-
- /**
- * Set the action to strip the VLAN header.
- *
- * @param stripVlan if true, strip the VLAN header.
- */
- public void setActionStripVlan(boolean stripVlan) {
- actionStripVlan = new ActionStripVlan(stripVlan);
- actionType = ActionValues.ACTION_STRIP_VLAN;
- }
-
- /**
- * Get the action to set the Ethernet source address.
- *
- * @return the action to set the Ethernet source address.
- */
- @JsonProperty("actionSetEthernetSrcAddr")
- public ActionSetEthernetAddr actionSetEthernetSrcAddr() {
- return actionSetEthernetSrcAddr;
- }
-
- /**
- * Set the action to set the Ethernet source address.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetEthernetSrcAddr")
- public void setActionSetEthernetSrcAddr(ActionSetEthernetAddr action) {
- actionSetEthernetSrcAddr = action;
- actionType = ActionValues.ACTION_SET_DL_SRC;
- }
-
- /**
- * Set the action to set the Ethernet source address.
- *
- * @param addr the MAC address to set as the Ethernet source address.
- */
- public void setActionSetEthernetSrcAddr(MACAddress addr) {
- actionSetEthernetSrcAddr = new ActionSetEthernetAddr(addr);
- actionType = ActionValues.ACTION_SET_DL_SRC;
- }
-
- /**
- * Get the action to set the Ethernet destination address.
- *
- * @return the action to set the Ethernet destination address.
- */
- @JsonProperty("actionSetEthernetDstAddr")
- public ActionSetEthernetAddr actionSetEthernetDstAddr() {
- return actionSetEthernetDstAddr;
- }
-
- /**
- * Set the action to set the Ethernet destination address.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetEthernetDstAddr")
- public void setActionSetEthernetDstAddr(ActionSetEthernetAddr action) {
- actionSetEthernetDstAddr = action;
- actionType = ActionValues.ACTION_SET_DL_DST;
- }
-
- /**
- * Set the action to set the Ethernet destination address.
- *
- * @param addr the MAC address to set as the Ethernet destination address.
- */
- public void setActionSetEthernetDstAddr(MACAddress addr) {
- actionSetEthernetDstAddr = new ActionSetEthernetAddr(addr);
- actionType = ActionValues.ACTION_SET_DL_DST;
- }
-
- /**
- * Get the action to set the IPv4 source address.
- *
- * @return the action to set the IPv4 source address.
- */
- @JsonProperty("actionSetIPv4SrcAddr")
- public ActionSetIPv4Addr actionSetIPv4SrcAddr() {
- return actionSetIPv4SrcAddr;
- }
-
- /**
- * Set the action to set the IPv4 source address.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetIPv4SrcAddr")
- public void setActionSetIPv4SrcAddr(ActionSetIPv4Addr action) {
- actionSetIPv4SrcAddr = action;
- actionType = ActionValues.ACTION_SET_NW_SRC;
- }
-
- /**
- * Set the action to set the IPv4 source address.
- *
- * @param addr the IPv4 address to set as the IPv4 source address.
- */
- public void setActionSetIPv4SrcAddr(IPv4 addr) {
- actionSetIPv4SrcAddr = new ActionSetIPv4Addr(addr);
- actionType = ActionValues.ACTION_SET_NW_SRC;
- }
-
- /**
- * Get the action to set the IPv4 destination address.
- *
- * @return the action to set the IPv4 destination address.
- */
- @JsonProperty("actionSetIPv4DstAddr")
- public ActionSetIPv4Addr actionSetIPv4DstAddr() {
- return actionSetIPv4DstAddr;
- }
-
- /**
- * Set the action to set the IPv4 destination address.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetIPv4DstAddr")
- public void setActionSetIPv4DstAddr(ActionSetIPv4Addr action) {
- actionSetIPv4DstAddr = action;
- actionType = ActionValues.ACTION_SET_NW_DST;
- }
-
- /**
- * Set the action to set the IPv4 destination address.
- *
- * @param addr the IPv4 address to set as the IPv4 destination address.
- */
- public void setActionSetIPv4DstAddr(IPv4 addr) {
- actionSetIPv4DstAddr = new ActionSetIPv4Addr(addr);
- actionType = ActionValues.ACTION_SET_NW_DST;
- }
-
- /**
- * Get the action to set the IP ToS (DSCP field, 6 bits).
- *
- * @return the action to set the IP ToS (DSCP field, 6 bits).
- */
- @JsonProperty("actionSetIpToS")
- public ActionSetIpToS actionSetIpToS() {
- return actionSetIpToS;
- }
-
- /**
- * Set the action to set the IP ToS (DSCP field, 6 bits).
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetIpToS")
- public void setActionSetIpToS(ActionSetIpToS action) {
- actionSetIpToS = action;
- actionType = ActionValues.ACTION_SET_NW_TOS;
- }
-
- /**
- * Set the action to set the IP ToS (DSCP field, 6 bits).
- *
- * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
- */
- public void setActionSetIpToS(byte ipToS) {
- actionSetIpToS = new ActionSetIpToS(ipToS);
- actionType = ActionValues.ACTION_SET_NW_TOS;
- }
-
- /**
- * Get the action to set the TCP/UDP source port.
- *
- * @return the action to set the TCP/UDP source port.
- */
- @JsonProperty("actionSetTcpUdpSrcPort")
- public ActionSetTcpUdpPort actionSetTcpUdpSrcPort() {
- return actionSetTcpUdpSrcPort;
- }
-
- /**
- * Set the action to set the TCP/UDP source port.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetTcpUdpSrcPort")
- public void setActionSetTcpUdpSrcPort(ActionSetTcpUdpPort action) {
- actionSetTcpUdpSrcPort = action;
- actionType = ActionValues.ACTION_SET_TP_SRC;
- }
-
- /**
- * Set the action to set the TCP/UDP source port.
- *
- * @param port the TCP/UDP port to set as the TCP/UDP source port.
- */
- public void setActionSetTcpUdpSrcPort(short port) {
- actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(port);
- actionType = ActionValues.ACTION_SET_TP_SRC;
- }
-
- /**
- * Get the action to set the TCP/UDP destination port.
- *
- * @return the action to set the TCP/UDP destination port.
- */
- @JsonProperty("actionSetTcpUdpDstPort")
- public ActionSetTcpUdpPort actionSetTcpUdpDstPort() {
- return actionSetTcpUdpDstPort;
- }
-
- /**
- * Set the action to set the TCP/UDP destination port.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionSetTcpUdpDstPort")
- public void setActionSetTcpUdpDstPort(ActionSetTcpUdpPort action) {
- actionSetTcpUdpDstPort = action;
- actionType = ActionValues.ACTION_SET_TP_DST;
- }
-
- /**
- * Set the action to set the TCP/UDP destination port.
- *
- * @param port the TCP/UDP port to set as the TCP/UDP destination port.
- */
- public void setActionSetTcpUdpDstPort(short port) {
- actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(port);
- actionType = ActionValues.ACTION_SET_TP_DST;
- }
-
- /**
- * Get the action to output to queue on a port.
- *
- * @return the action to output to queue on a port.
- */
- @JsonProperty("actionEnqueue")
- public ActionEnqueue actionEnqueue() { return actionEnqueue; }
-
- /**
- * Set the action to output to queue on a port.
- *
- * @param action the action to set.
- */
- @JsonProperty("actionEnqueue")
- public void setActionEnqueue(ActionEnqueue action) {
- actionEnqueue = action;
- actionType = ActionValues.ACTION_ENQUEUE;
- }
-
- /**
- * Set the action to output to queue on a port.
- *
- * @param port the port to set.
- * @param int queueId the queue ID to set.
- */
- public void setActionEnqueue(Port port, int queueId) {
- actionEnqueue = new ActionEnqueue(port, queueId);
- actionType = ActionValues.ACTION_ENQUEUE;
- }
-
- /**
- * Convert the set of actions to a string.
- *
- * The string has the following form:
- * [type=XXX action=XXX]
- *
- * @return the set of actions as a string.
- */
- @Override
- public String toString() {
- String ret = "[";
- ret += "type=" + actionType;
- switch (actionType) {
- case ACTION_OUTPUT:
- ret += " action=" + actionOutput.toString();
- break;
- case ACTION_SET_VLAN_VID:
- ret += " action=" + actionSetVlanId.toString();
- break;
- case ACTION_SET_VLAN_PCP:
- ret += " action=" + actionSetVlanPriority.toString();
- break;
- case ACTION_STRIP_VLAN:
- ret += " action=" + actionStripVlan.toString();
- break;
- case ACTION_SET_DL_SRC:
- ret += " action=" + actionSetEthernetSrcAddr.toString();
- break;
- case ACTION_SET_DL_DST:
- ret += " action=" + actionSetEthernetDstAddr.toString();
- break;
- case ACTION_SET_NW_SRC:
- ret += " action=" + actionSetIPv4SrcAddr.toString();
- break;
- case ACTION_SET_NW_DST:
- ret += " action=" + actionSetIPv4DstAddr.toString();
- break;
- case ACTION_SET_NW_TOS:
- ret += " action=" + actionSetIpToS.toString();
- break;
- case ACTION_SET_TP_SRC:
- ret += " action=" + actionSetTcpUdpSrcPort.toString();
- break;
- case ACTION_SET_TP_DST:
- ret += " action=" + actionSetTcpUdpDstPort.toString();
- break;
- case ACTION_ENQUEUE:
- ret += " action=" + actionEnqueue.toString();
- break;
- }
- ret += "]";
-
- return ret;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/util/FlowPath.java b/src/main/java/net/floodlightcontroller/util/FlowPath.java
deleted file mode 100644
index b171b88..0000000
--- a/src/main/java/net/floodlightcontroller/util/FlowPath.java
+++ /dev/null
@@ -1,223 +0,0 @@
-package net.floodlightcontroller.util;
-
-import java.util.ArrayList;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.floodlightcontroller.util.CallerId;
-import net.floodlightcontroller.util.DataPath;
-import net.floodlightcontroller.util.FlowEntryMatch;
-import net.floodlightcontroller.util.FlowId;
-
-import org.codehaus.jackson.annotate.JsonProperty;
-
-/**
- * The class representing the Flow Path.
- */
-public class FlowPath implements Comparable<FlowPath> {
- private FlowId flowId; // The Flow ID
- private CallerId installerId; // The Caller ID of the path installer
- private DataPath dataPath; // The data path
- private FlowEntryMatch flowEntryMatch; // Common Flow Entry Match for all
- // Flow Entries
-
- /**
- * Default constructor.
- */
- public FlowPath() {
- dataPath = new DataPath();
- }
-
- /**
- * Constructor to instantiate from object in Network Map
- */
- public FlowPath(IFlowPath flowObj) {
- dataPath = new DataPath();
- this.setFlowId(new FlowId(flowObj.getFlowId()));
- this.setInstallerId(new CallerId(flowObj.getInstallerId()));
- this.dataPath().srcPort().setDpid(new Dpid(flowObj.getSrcSwitch()));
- this.dataPath().srcPort().setPort(new Port(flowObj.getSrcPort()));
- this.dataPath().dstPort().setDpid(new Dpid(flowObj.getDstSwitch()));
- this.dataPath().dstPort().setPort(new Port(flowObj.getDstPort()));
- //
- // Extract the match conditions that are common for all Flow Entries
- //
- {
- FlowEntryMatch match = new FlowEntryMatch();
- Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType != null)
- match.enableEthernetFrameType(matchEthernetFrameType);
- String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net != null)
- match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
- String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net != null)
- match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
- String matchSrcMac = flowObj.getMatchSrcMac();
- if (matchSrcMac != null)
- match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
- String matchDstMac = flowObj.getMatchDstMac();
- if (matchDstMac != null)
- match.enableDstMac(MACAddress.valueOf(matchDstMac));
- this.setFlowEntryMatch(match);
- }
-
- //
- // Extract all Flow Entries
- //
- Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
- for (IFlowEntry flowEntryObj : flowEntries) {
- FlowEntry flowEntry = new FlowEntry();
- flowEntry.setFlowEntryId(new FlowEntryId(flowEntryObj.getFlowEntryId()));
- flowEntry.setDpid(new Dpid(flowEntryObj.getSwitchDpid()));
-
- //
- // Extract the match conditions
- //
- FlowEntryMatch match = new FlowEntryMatch();
- Short matchInPort = flowEntryObj.getMatchInPort();
- if (matchInPort != null)
- match.enableInPort(new Port(matchInPort));
- Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType != null)
- match.enableEthernetFrameType(matchEthernetFrameType);
- String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net != null)
- match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
- String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net != null)
- match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
- String matchSrcMac = flowEntryObj.getMatchSrcMac();
- if (matchSrcMac != null)
- match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
- String matchDstMac = flowEntryObj.getMatchDstMac();
- if (matchDstMac != null)
- match.enableDstMac(MACAddress.valueOf(matchDstMac));
- flowEntry.setFlowEntryMatch(match);
-
- //
- // Extract the actions
- //
- ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
- Short actionOutputPort = flowEntryObj.getActionOutput();
- if (actionOutputPort != null) {
- FlowEntryAction action = new FlowEntryAction();
- action.setActionOutput(new Port(actionOutputPort));
- actions.add(action);
- }
- flowEntry.setFlowEntryActions(actions);
-
- String userState = flowEntryObj.getUserState();
- flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
- String switchState = flowEntryObj.getSwitchState();
- flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
- //
- // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
- // and FlowEntryErrorState.
- //
- this.dataPath().flowEntries().add(flowEntry);
- }
- }
-
- /**
- * Get the flow path Flow ID.
- *
- * @return the flow path Flow ID.
- */
- @JsonProperty("flowId")
- public FlowId flowId() { return flowId; }
-
- /**
- * Set the flow path Flow ID.
- *
- * @param flowId the flow path Flow ID to set.
- */
- @JsonProperty("flowId")
- public void setFlowId(FlowId flowId) {
- this.flowId = flowId;
- }
-
- /**
- * Get the Caller ID of the flow path installer.
- *
- * @return the Caller ID of the flow path installer.
- */
- @JsonProperty("installerId")
- public CallerId installerId() { return installerId; }
-
- /**
- * Set the Caller ID of the flow path installer.
- *
- * @param installerId the Caller ID of the flow path installer.
- */
- @JsonProperty("installerId")
- public void setInstallerId(CallerId installerId) {
- this.installerId = installerId;
- }
-
- /**
- * Get the flow path's data path.
- *
- * @return the flow path's data path.
- */
- @JsonProperty("dataPath")
- public DataPath dataPath() { return dataPath; }
-
- /**
- * Set the flow path's data path.
- *
- * @param dataPath the flow path's data path to set.
- */
- @JsonProperty("dataPath")
- public void setDataPath(DataPath dataPath) {
- this.dataPath = dataPath;
- }
-
- /**
- * Get the flow path's match conditions common for all Flow Entries.
- *
- * @return the flow path's match conditions common for all Flow Entries.
- */
- @JsonProperty("flowEntryMatch")
- public FlowEntryMatch flowEntryMatch() { return flowEntryMatch; }
-
- /**
- * Set the flow path's match conditions common for all Flow Entries.
- *
- * @param flowEntryMatch the flow path's match conditions common for all
- * Flow Entries.
- */
- @JsonProperty("flowEntryMatch")
- public void setFlowEntryMatch(FlowEntryMatch flowEntryMatch) {
- this.flowEntryMatch = flowEntryMatch;
- }
-
- /**
- * Convert the flow path to a string.
- *
- * The string has the following form:
- * [flowId=XXX installerId=XXX dataPath=XXX]
- *
- * @return the flow path as a string.
- */
- @Override
- public String toString() {
- String ret = "[flowId=" + this.flowId.toString();
- ret += " installerId=" + this.installerId.toString();
- if (dataPath != null)
- ret += " dataPath=" + this.dataPath.toString();
- if (flowEntryMatch != null)
- ret += " flowEntryMatch=" + this.flowEntryMatch.toString();
- ret += "]";
- return ret;
- }
-
- /**
- * CompareTo method to order flowPath by Id
- */
- @Override
- public int compareTo(FlowPath f) {
- return (int) (this.flowId.value() - f.flowId.value());
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/util/MACAddress.java b/src/main/java/net/floodlightcontroller/util/MACAddress.java
index 743dc5b..88dbda2 100644
--- a/src/main/java/net/floodlightcontroller/util/MACAddress.java
+++ b/src/main/java/net/floodlightcontroller/util/MACAddress.java
@@ -2,10 +2,9 @@
import java.util.Arrays;
-import net.floodlightcontroller.util.serializers.MACAddressDeserializer;
-import net.floodlightcontroller.util.serializers.MACAddressSerializer;
+import net.onrc.onos.ofcontroller.util.serializers.MACAddressDeserializer;
+import net.onrc.onos.ofcontroller.util.serializers.MACAddressSerializer;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java
deleted file mode 100644
index 6021e3d..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-
-import net.floodlightcontroller.util.MACAddress;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.data.Status;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Put;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class HostResource extends org.restlet.resource.ServerResource {
- protected static Logger log = LoggerFactory.getLogger(HostResource.class);
-
- public class HostDefinition {
- String port = null; // Logical port name
- String guid = null; // Network ID
- String mac = null; // MAC Address
- String attachment = null; // Attachment name
- }
-
- protected void jsonToHostDefinition(String json, HostDefinition host) throws IOException {
- MappingJsonFactory f = new MappingJsonFactory();
- JsonParser jp;
-
- try {
- jp = f.createJsonParser(json);
- } catch (JsonParseException e) {
- throw new IOException(e);
- }
-
- jp.nextToken();
- if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected START_OBJECT");
- }
-
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
- throw new IOException("Expected FIELD_NAME");
- }
-
- String n = jp.getCurrentName();
- jp.nextToken();
- if (jp.getText().equals(""))
- continue;
- else if (n.equals("attachment")) {
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- String field = jp.getCurrentName();
- if (field.equals("id")) {
- host.attachment = jp.getText();
- } else if (field.equals("mac")) {
- host.mac = jp.getText();
- }
- }
- }
- }
-
- jp.close();
- }
-
- @Put
- public String addHost(String postData) {
- IVirtualNetworkService vns =
- (IVirtualNetworkService)getContext().getAttributes().
- get(IVirtualNetworkService.class.getCanonicalName());
- HostDefinition host = new HostDefinition();
- host.port = (String) getRequestAttributes().get("port");
- host.guid = (String) getRequestAttributes().get("network");
- try {
- jsonToHostDefinition(postData, host);
- } catch (IOException e) {
- log.error("Could not parse JSON {}", e.getMessage());
- }
- vns.addHost(MACAddress.valueOf(host.mac), host.guid, host.port);
- setStatus(Status.SUCCESS_OK);
- return "{\"status\":\"ok\"}";
- }
-
-
- @Delete
- public String deleteHost() {
- String port = (String) getRequestAttributes().get("port");
- IVirtualNetworkService vns =
- (IVirtualNetworkService)getContext().getAttributes().
- get(IVirtualNetworkService.class.getCanonicalName());
- vns.deleteHost(null, port);
- setStatus(Status.SUCCESS_OK);
- return "{\"status\":\"ok\"}";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java b/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java
deleted file mode 100644
index 4304a33..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.util.Collection;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.util.MACAddress;
-
-public interface IVirtualNetworkService extends IFloodlightService {
- /**
- * Creates a new virtual network. This can also be called
- * to modify a virtual network. To update a network you specify the GUID
- * and the fields you want to update.
- * @param network The network name. Must be unique.
- * @param guid The ID of the network. Must be unique.
- * @param gateway The IP address of the network gateway, null if none.
- */
- public void createNetwork(String guid, String network, Integer gateway);
-
- /**
- * Deletes a virtual network.
- * @param guid The ID (not name) of virtual network to delete.
- */
- public void deleteNetwork(String guid);
-
- /**
- * Adds a host to a virtual network. If a mapping already exists the
- * new one will override the old mapping.
- * @param mac The MAC address of the host to add.
- * @param network The network to add the host to.
- * @param port The logical port name to attach the host to. Must be unique.
- */
- public void addHost(MACAddress mac, String network, String port);
-
- /**
- * Deletes a host from a virtual network. Either the MAC or Port must
- * be specified.
- * @param mac The MAC address to delete.
- * @param port The logical port the host is attached to.
- */
- public void deleteHost(MACAddress mac, String port);
-
- /**
- * Return list of all virtual networks.
- * @return Collection <VirtualNetwork>
- */
- public Collection <VirtualNetwork> listNetworks();
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
deleted file mode 100644
index 2efe52a..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.Collection;
-
-import net.floodlightcontroller.packet.IPv4;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.data.Status;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Get;
-import org.restlet.resource.Post;
-import org.restlet.resource.Put;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetworkResource extends ServerResource {
- protected static Logger log = LoggerFactory.getLogger(NetworkResource.class);
-
- public class NetworkDefinition {
- public String name = null;
- public String guid = null;
- public String gateway = null;
- }
-
- protected void jsonToNetworkDefinition(String json, NetworkDefinition network) throws IOException {
- MappingJsonFactory f = new MappingJsonFactory();
- JsonParser jp;
-
- try {
- jp = f.createJsonParser(json);
- } catch (JsonParseException e) {
- throw new IOException(e);
- }
-
- jp.nextToken();
- if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected START_OBJECT");
- }
-
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
- throw new IOException("Expected FIELD_NAME");
- }
-
- String n = jp.getCurrentName();
- jp.nextToken();
- if (jp.getText().equals(""))
- continue;
- else if (n.equals("network")) {
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- String field = jp.getCurrentName();
- if (field.equals("name")) {
- network.name = jp.getText();
- } else if (field.equals("gateway")) {
- String gw = jp.getText();
- if ((gw != null) && (!gw.equals("null")))
- network.gateway = gw;
- } else if (field.equals("id")) {
- network.guid = jp.getText();
- } else {
- log.warn("Unrecognized field {} in " +
- "parsing network definition",
- jp.getText());
- }
- }
- }
- }
-
- jp.close();
- }
-
- @Get("json")
- public Collection <VirtualNetwork> retrieve() {
- IVirtualNetworkService vns =
- (IVirtualNetworkService)getContext().getAttributes().
- get(IVirtualNetworkService.class.getCanonicalName());
-
- return vns.listNetworks();
- }
-
- @Put
- @Post
- public String createNetwork(String postData) {
- NetworkDefinition network = new NetworkDefinition();
- try {
- jsonToNetworkDefinition(postData, network);
- } catch (IOException e) {
- log.error("Could not parse JSON {}", e.getMessage());
- }
-
- // We try to get the ID from the URI only if it's not
- // in the POST data
- if (network.guid == null) {
- String guid = (String) getRequestAttributes().get("network");
- if ((guid != null) && (!guid.equals("null")))
- network.guid = guid;
- }
-
- IVirtualNetworkService vns =
- (IVirtualNetworkService)getContext().getAttributes().
- get(IVirtualNetworkService.class.getCanonicalName());
-
- Integer gw = null;
- if (network.gateway != null) {
- try {
- gw = IPv4.toIPv4Address(network.gateway);
- } catch (IllegalArgumentException e) {
- log.warn("Could not parse gateway {} as IP for network {}, setting as null",
- network.gateway, network.name);
- network.gateway = null;
- }
- }
- vns.createNetwork(network.guid, network.name, gw);
- setStatus(Status.SUCCESS_OK);
- return "{\"status\":\"ok\"}";
- }
-
- @Delete
- public String deleteNetwork() {
- IVirtualNetworkService vns =
- (IVirtualNetworkService)getContext().getAttributes().
- get(IVirtualNetworkService.class.getCanonicalName());
- String guid = (String) getRequestAttributes().get("network");
- vns.deleteNetwork(guid);
- setStatus(Status.SUCCESS_OK);
- return "{\"status\":\"ok\"}";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
deleted file mode 100644
index a184a95..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.Post;
-import org.restlet.resource.Put;
-import org.restlet.resource.ServerResource;
-
-public class NoOp extends ServerResource {
- /**
- * Does nothing and returns 200 OK with a status message
- * @return status: ok
- */
- @Get
- @Put
- @Post
- public String noOp(String postdata) {
- setStatus(Status.SUCCESS_OK);
- return "{\"status\":\"ok\"}";
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java
deleted file mode 100644
index f5dfb21..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-
-import net.floodlightcontroller.util.MACAddress;
-
-/**
- * Data structure for storing and outputing information of a virtual network created
- * by VirtualNetworkFilter
- *
- * @author KC Wang
- */
-
-@JsonSerialize(using=VirtualNetworkSerializer.class)
-public class VirtualNetwork{
- protected String name; // network name
- protected String guid; // network id
- protected String gateway; // network gateway
- protected Collection<MACAddress> hosts; // array of hosts explicitly added to this network
-
- /**
- * Constructor requires network name and id
- * @param name: network name
- * @param guid: network id
- */
- public VirtualNetwork(String name, String guid) {
- this.name = name;
- this.guid = guid;
- this.gateway = null;
- this.hosts = new ArrayList<MACAddress>();
- return;
- }
-
- /**
- * Sets network name
- * @param gateway: IP address as String
- */
- public void setName(String name){
- this.name = name;
- return;
- }
-
- /**
- * Sets network gateway IP address
- * @param gateway: IP address as String
- */
- public void setGateway(String gateway){
- this.gateway = gateway;
- return;
- }
-
- /**
- * Adds a host to this network record
- * @param host: MAC address as MACAddress
- */
- public void addHost(MACAddress host){
- this.hosts.add(host);
- return;
- }
-
- /**
- * Removes a host from this network record
- * @param host: MAC address as MACAddress
- * @return boolean: true: removed, false: host not found
- */
- public boolean removeHost(MACAddress host){
- Iterator<MACAddress> iter = this.hosts.iterator();
- while(iter.hasNext()){
- MACAddress element = iter.next();
- if(element.equals(host) ){
- //assuming MAC address for host is unique
- iter.remove();
- return true;
- }
- }
- return false;
- }
-
- /**
- * Removes all hosts from this network record
- */
- public void clearHosts(){
- this.hosts.clear();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
deleted file mode 100644
index 012dfb6..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
+++ /dev/null
@@ -1,521 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceListener;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.packet.DHCP;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.ForwardingBase;
-import net.floodlightcontroller.util.MACAddress;
-
-/**
- * A simple Layer 2 (MAC based) network virtualization module. This module allows
- * you to create simple L2 networks (host + gateway) and will drop traffic if
- * they are not on the same virtual network.
- *
- * LIMITATIONS
- * - This module does not allow overlapping of IPs or MACs
- * - You can only have 1 gateway per virtual network (can be shared)
- * - There is filtering of multicast/broadcast traffic
- * - All DHCP traffic will be allowed, regardless of unicast/broadcast
- *
- * @author alexreimers
- */
-public class VirtualNetworkFilter
- implements IFloodlightModule, IVirtualNetworkService, IOFMessageListener, IDeviceListener {
- protected static Logger log = LoggerFactory.getLogger(VirtualNetworkFilter.class);
-
- private final short APP_ID = 20;
-
- // Our dependencies
- IFloodlightProviderService floodlightProvider;
- IRestApiService restApi;
- IDeviceService deviceService;
-
- // Our internal state
- protected Map<String, VirtualNetwork> vNetsByGuid; // List of all created virtual networks
- protected Map<String, String> nameToGuid; // Logical name -> Network ID
- protected Map<String, Integer> guidToGateway; // Network ID -> Gateway IP
- protected Map<Integer, Set<String>> gatewayToGuid; // Gateway IP -> Network ID
- protected Map<MACAddress, Integer> macToGateway; // Gateway MAC -> Gateway IP
- protected Map<MACAddress, String> macToGuid; // Host MAC -> Network ID
- protected Map<String, MACAddress> portToMac; // Host MAC -> logical port name
-
- /**
- * Adds a gateway to a virtual network.
- * @param guid The ID (not name) of the network.
- * @param ip The IP addresses of the gateway.
- */
- protected void addGateway(String guid, Integer ip) {
- if (ip.intValue() != 0) {
- if (log.isDebugEnabled())
- log.debug("Adding {} as gateway for GUID {}",
- IPv4.fromIPv4Address(ip), guid);
-
- guidToGateway.put(guid, ip);
- if (vNetsByGuid.get(guid) != null)
- vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(ip));
- if (gatewayToGuid.containsKey(ip)) {
- Set<String> gSet = gatewayToGuid.get(ip);
- gSet.add(guid);
- } else {
- Set<String> gSet = Collections.synchronizedSet(new HashSet<String>());
- gSet.add(guid);
- gatewayToGuid.put(ip, gSet);
- }
- }
- }
-
- /**
- * Deletes a gateway for a virtual network.
- * @param guid The ID (not name) of the network to delete
- * the gateway for.
- */
- protected void deleteGateway(String guid) {
- Integer gwIp = guidToGateway.remove(guid);
- if (gwIp == null) return;
- Set<String> gSet = gatewayToGuid.get(gwIp);
- gSet.remove(guid);
- if(vNetsByGuid.get(guid)!=null)
- vNetsByGuid.get(guid).setGateway(null);
- }
-
- // IVirtualNetworkService
-
- @Override
- public void createNetwork(String guid, String network, Integer gateway) {
- if (log.isDebugEnabled()) {
- String gw = null;
- try {
- gw = IPv4.fromIPv4Address(gateway);
- } catch (Exception e) {
- // fail silently
- }
- log.debug("Creating network {} with ID {} and gateway {}",
- new Object[] {network, guid, gw});
- }
-
- if (!nameToGuid.isEmpty()) {
- // We have to iterate all the networks to handle name/gateway changes
- for (Entry<String, String> entry : nameToGuid.entrySet()) {
- if (entry.getValue().equals(guid)) {
- nameToGuid.remove(entry.getKey());
- break;
- }
- }
- }
- nameToGuid.put(network, guid);
- if (vNetsByGuid.containsKey(guid))
- vNetsByGuid.get(guid).setName(network); //network already exists, just updating name
- else
- vNetsByGuid.put(guid, new VirtualNetwork(network, guid)); //new network
-
- // If they don't specify a new gateway the old one will be preserved
- if ((gateway != null) && (gateway != 0)) {
- addGateway(guid, gateway);
- if(vNetsByGuid.get(guid)!=null)
- vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(gateway));
- }
- }
-
- @Override
- public void deleteNetwork(String guid) {
- String name = null;
- if (nameToGuid.isEmpty()) {
- log.warn("Could not delete network with ID {}, network doesn't exist",
- guid);
- return;
- }
- for (Entry<String, String> entry : nameToGuid.entrySet()) {
- if (entry.getValue().equals(guid)) {
- name = entry.getKey();
- break;
- }
- log.warn("Could not delete network with ID {}, network doesn't exist",
- guid);
- }
-
- if (log.isDebugEnabled())
- log.debug("Deleting network with name {} ID {}", name, guid);
-
- nameToGuid.remove(name);
- deleteGateway(guid);
- if(vNetsByGuid.get(guid)!=null){
- vNetsByGuid.get(guid).clearHosts();
- vNetsByGuid.remove(guid);
- }
- Collection<MACAddress> deleteList = new ArrayList<MACAddress>();
- for (MACAddress host : macToGuid.keySet()) {
- if (macToGuid.get(host).equals(guid)) {
- deleteList.add(host);
- }
- }
- for (MACAddress mac : deleteList) {
- if (log.isDebugEnabled()) {
- log.debug("Removing host {} from network {}",
- HexString.toHexString(mac.toBytes()), guid);
- }
- macToGuid.remove(mac);
- for (Entry<String, MACAddress> entry : portToMac.entrySet()) {
- if (entry.getValue().equals(mac)) {
- portToMac.remove(entry.getKey());
- break;
- }
- }
- }
- }
-
- @Override
- public void addHost(MACAddress mac, String guid, String port) {
- if (guid != null) {
- if (log.isDebugEnabled()) {
- log.debug("Adding {} to network ID {} on port {}",
- new Object[] {mac, guid, port});
- }
- // We ignore old mappings
- macToGuid.put(mac, guid);
- portToMac.put(port, mac);
- if(vNetsByGuid.get(guid)!=null)
- vNetsByGuid.get(guid).addHost(new MACAddress(mac.toBytes()));
- } else {
- log.warn("Could not add MAC {} to network ID {} on port {}, the network does not exist",
- new Object[] {mac, guid, port});
- }
- }
-
- @Override
- public void deleteHost(MACAddress mac, String port) {
- if (log.isDebugEnabled()) {
- log.debug("Removing host {} from port {}", mac, port);
- }
- if (mac == null && port == null) return;
- if (port != null) {
- MACAddress host = portToMac.remove(port);
- if(vNetsByGuid.get(macToGuid.get(host)) != null)
- vNetsByGuid.get(macToGuid.get(host)).removeHost(host);
- macToGuid.remove(host);
- } else if (mac != null) {
- if (!portToMac.isEmpty()) {
- for (Entry<String, MACAddress> entry : portToMac.entrySet()) {
- if (entry.getValue().equals(mac)) {
- if(vNetsByGuid.get(macToGuid.get(entry.getValue())) != null)
- vNetsByGuid.get(macToGuid.get(entry.getValue())).removeHost(entry.getValue());
- portToMac.remove(entry.getKey());
- macToGuid.remove(entry.getValue());
- return;
- }
- }
- }
- }
- }
-
- // IFloodlightModule
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IVirtualNetworkService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- m.put(IVirtualNetworkService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(IRestApiService.class);
- l.add(IDeviceService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
- restApi = context.getServiceImpl(IRestApiService.class);
- deviceService = context.getServiceImpl(IDeviceService.class);
-
- vNetsByGuid = new ConcurrentHashMap<String, VirtualNetwork>();
- nameToGuid = new ConcurrentHashMap<String, String>();
- guidToGateway = new ConcurrentHashMap<String, Integer>();
- gatewayToGuid = new ConcurrentHashMap<Integer, Set<String>>();
- macToGuid = new ConcurrentHashMap<MACAddress, String>();
- portToMac = new ConcurrentHashMap<String, MACAddress>();
- macToGateway = new ConcurrentHashMap<MACAddress, Integer>();
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- restApi.addRestletRoutable(new VirtualNetworkWebRoutable());
- deviceService.addListener(this);
- }
-
- // IOFMessageListener
-
- @Override
- public String getName() {
- return "virtualizer";
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- // Link discovery should go before us so we don't block LLDPs
- return (type.equals(OFType.PACKET_IN) &&
- (name.equals("linkdiscovery") || (name.equals("devicemanager"))));
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- // We need to go before forwarding
- return (type.equals(OFType.PACKET_IN) && name.equals("forwarding"));
- }
-
- @Override
- public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
- switch (msg.getType()) {
- case PACKET_IN:
- return processPacketIn(sw, (OFPacketIn)msg, cntx);
- default:
- break;
- }
- log.warn("Received unexpected message {}", msg);
- return Command.CONTINUE;
- }
-
- /**
- * Checks whether the frame is destined to or from a gateway.
- * @param frame The ethernet frame to check.
- * @return True if it is to/from a gateway, false otherwise.
- */
- protected boolean isDefaultGateway(Ethernet frame) {
- if (macToGateway.containsKey(frame.getSourceMAC()))
- return true;
-
- Integer gwIp = macToGateway.get(frame.getDestinationMAC());
- if (gwIp != null) {
- MACAddress host = frame.getSourceMAC();
- String srcNet = macToGuid.get(host);
- if (srcNet != null) {
- Integer gwIpSrcNet = guidToGateway.get(srcNet);
- if ((gwIpSrcNet != null) && (gwIp.equals(gwIpSrcNet)))
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Checks to see if two MAC Addresses are on the same network.
- * @param m1 The first MAC.
- * @param m2 The second MAC.
- * @return True if they are on the same virtual network,
- * false otherwise.
- */
- protected boolean oneSameNetwork(MACAddress m1, MACAddress m2) {
- String net1 = macToGuid.get(m1);
- String net2 = macToGuid.get(m2);
- if (net1 == null) return false;
- if (net2 == null) return false;
- return net1.equals(net2);
- }
-
- /**
- * Checks to see if an Ethernet frame is a DHCP packet.
- * @param frame The Ethernet frame.
- * @return True if it is a DHCP frame, false otherwise.
- */
- protected boolean isDhcpPacket(Ethernet frame) {
- IPacket payload = frame.getPayload(); // IP
- if (payload == null) return false;
- IPacket p2 = payload.getPayload(); // TCP or UDP
- if (p2 == null) return false;
- IPacket p3 = p2.getPayload(); // Application
- if ((p3 != null) && (p3 instanceof DHCP)) return true;
- return false;
- }
-
- /**
- * Processes an OFPacketIn message and decides if the OFPacketIn should be dropped
- * or the processing should continue.
- * @param sw The switch the PacketIn came from.
- * @param msg The OFPacketIn message from the switch.
- * @param cntx The FloodlightContext for this message.
- * @return Command.CONTINUE if processing should be continued, Command.STOP otherwise.
- */
- protected Command processPacketIn(IOFSwitch sw, OFPacketIn msg, FloodlightContext cntx) {
- Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
- Command ret = Command.STOP;
- String srcNetwork = macToGuid.get(eth.getSourceMAC());
- // If the host is on an unknown network we deny it.
- // We make exceptions for ARP and DHCP.
- if (eth.isBroadcast() || eth.isMulticast() || isDefaultGateway(eth) || isDhcpPacket(eth)) {
- ret = Command.CONTINUE;
- } else if (srcNetwork == null) {
- log.trace("Blocking traffic from host {} because it is not attached to any network.",
- HexString.toHexString(eth.getSourceMACAddress()));
- ret = Command.STOP;
- } else if (oneSameNetwork(eth.getSourceMAC(), eth.getDestinationMAC())) {
- // if they are on the same network continue
- ret = Command.CONTINUE;
- }
-
- if (log.isTraceEnabled())
- log.trace("Results for flow between {} and {} is {}",
- new Object[] {eth.getSourceMAC(), eth.getDestinationMAC(), ret});
- /*
- * TODO - figure out how to still detect gateways while using
- * drop mods
- if (ret == Command.STOP) {
- if (!(eth.getPayload() instanceof ARP))
- doDropFlow(sw, msg, cntx);
- }
- */
- return ret;
- }
-
- /**
- * Writes a FlowMod to a switch that inserts a drop flow.
- * @param sw The switch to write the FlowMod to.
- * @param pi The corresponding OFPacketIn. Used to create the OFMatch structure.
- * @param cntx The FloodlightContext that gets passed to the switch.
- */
- protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
- if (log.isTraceEnabled()) {
- log.trace("doDropFlow pi={} srcSwitch={}",
- new Object[] { pi, sw });
- }
-
- if (sw == null) {
- log.warn("Switch is null, not installing drop flowmod for PacketIn {}", pi);
- return;
- }
-
- // Create flow-mod based on packet-in and src-switch
- OFFlowMod fm =
- (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
- OFMatch match = new OFMatch();
- match.loadFromPacket(pi.getPacketData(), pi.getInPort());
- List<OFAction> actions = new ArrayList<OFAction>(); // no actions = drop
- long cookie = AppCookie.makeCookie(APP_ID, 0);
- fm.setCookie(cookie)
- .setIdleTimeout(ForwardingBase.FLOWMOD_DEFAULT_IDLE_TIMEOUT)
- .setHardTimeout(ForwardingBase.FLOWMOD_DEFAULT_HARD_TIMEOUT)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH);
- fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
- try {
- if (log.isTraceEnabled()) {
- log.trace("write drop flow-mod srcSwitch={} match={} " +
- "pi={} flow-mod={}",
- new Object[] {sw, match, pi, fm});
- }
- sw.write(fm, cntx);
- } catch (IOException e) {
- log.error("Failure writing drop flow mod", e);
- }
- return;
- }
-
- // IDeviceListener
-
- @Override
- public void deviceAdded(IDevice device) {
- if (device.getIPv4Addresses() == null) return;
- for (Integer i : device.getIPv4Addresses()) {
- if (gatewayToGuid.containsKey(i)) {
- MACAddress mac = MACAddress.valueOf(device.getMACAddress());
- if (log.isDebugEnabled())
- log.debug("Adding MAC {} with IP {} a a gateway",
- HexString.toHexString(mac.toBytes()),
- IPv4.fromIPv4Address(i));
- macToGateway.put(mac, i);
- }
- }
- }
-
- @Override
- public void deviceRemoved(IDevice device) {
- // if device is a gateway remove
- MACAddress mac = MACAddress.valueOf(device.getMACAddress());
- if (macToGateway.containsKey(mac)) {
- if (log.isDebugEnabled())
- log.debug("Removing MAC {} as a gateway",
- HexString.toHexString(mac.toBytes()));
- macToGateway.remove(mac);
- }
- }
-
- @Override
- public void deviceIPV4AddrChanged(IDevice device) {
- // add or remove entry as gateway
- deviceAdded(device);
- }
-
- @Override
- public void deviceMoved(IDevice device) {
- // ignore
- }
-
- @Override
- public void deviceVlanChanged(IDevice device) {
- // ignore
- }
-
- @Override
- public Collection <VirtualNetwork> listNetworks() {
- return vNetsByGuid.values();
-
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java
deleted file mode 100644
index 6902f6c..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.Iterator;
-
-import net.floodlightcontroller.util.MACAddress;
-
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.map.JsonSerializer;
-import org.codehaus.jackson.map.SerializerProvider;
-
-/**
- * Serialize a VirtualNetwork object
- * @author KC Wang
- */
-public class VirtualNetworkSerializer extends JsonSerializer<VirtualNetwork> {
-
- @Override
- public void serialize(VirtualNetwork vNet, JsonGenerator jGen,
- SerializerProvider serializer) throws IOException,
- JsonProcessingException {
- jGen.writeStartObject();
-
- jGen.writeStringField("name", vNet.name);
- jGen.writeStringField("guid", vNet.guid);
- jGen.writeStringField("gateway", vNet.gateway);
-
- jGen.writeArrayFieldStart("mac");
- Iterator<MACAddress> hit = vNet.hosts.iterator();
- while (hit.hasNext())
- jGen.writeString(hit.next().toString());
- jGen.writeEndArray();
-
- jGen.writeEndObject();
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
deleted file mode 100644
index 61769ec..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-public class VirtualNetworkWebRoutable implements RestletRoutable {
-
- @Override
- public Restlet getRestlet(Context context) {
- Router router = new Router(context);
- router.attach("/tenants/{tenant}/networks", NetworkResource.class); // GET
- router.attach("/tenants/{tenant}/networks/{network}", NetworkResource.class); // PUT, DELETE
- router.attach("/tenants/{tenant}/networks", NetworkResource.class); // POST
- router.attach("/tenants/{tenant}/networks/{network}/ports/{port}/attachment", HostResource.class);
- router.attachDefault(NoOp.class);
- return router;
- }
-
- @Override
- public String basePath() {
- return "/quantum/v1.0";
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java b/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
index b8b3303..2e2706c 100644
--- a/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
+++ b/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
@@ -17,27 +17,27 @@
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.util.DataPath;
-import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.FlowEntry;
-import net.floodlightcontroller.util.FlowEntryAction;
-import net.floodlightcontroller.util.FlowEntryMatch;
-import net.floodlightcontroller.util.FlowPath;
-import net.floodlightcontroller.util.Port;
-import net.floodlightcontroller.util.SwitchPort;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.LocalTopologyEventListener;
-import net.onrc.onos.util.GraphDBConnection.Transaction;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.LocalTopologyEventListener;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.FlowEntryAction;
+import net.onrc.onos.ofcontroller.util.FlowEntryActions;
+import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
public class FlowManagerImpl implements IFlowManager {
protected static Logger log = LoggerFactory.getLogger(LocalTopologyEventListener.class);
- protected static GraphDBConnection conn;
+ protected GraphDBOperation op;
@Override
public void createFlow(IPortObject src_port, IPortObject dest_port) {
@@ -87,8 +87,8 @@
Short dst_port = flow.getDstPort();
IPortObject src = null;
IPortObject dst = null;
- src = conn.utils().searchPort(conn, src_dpid, src_port);
- dst = conn.utils().searchPort(conn, dst_dpid, dst_port);
+ src = op.searchPort(src_dpid, src_port);
+ dst = op.searchPort(dst_dpid, dst_port);
if (src != null && dst != null) {
FlowPath newFlow = this.computeFlowPath(src,dst);
installFlow(newFlow);
@@ -133,16 +133,12 @@
flowEntry.setOutPort(new Port(src_port.getNumber()));
flowEntry.setFlowEntryMatch(new FlowEntryMatch());
flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
-
+
// Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
- }
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
dataPath.flowEntries().add(flowEntry);
FlowPath flowPath = new FlowPath();
@@ -255,14 +251,10 @@
flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
// Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
- }
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
dataPath.flowEntries().add(flowEntry);
continue;
}
@@ -277,14 +269,10 @@
flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
// Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
- }
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
dataPath.flowEntries().add(flowEntry);
dataPath.flowEntries().add(flowEntry);
}
diff --git a/src/main/java/net/onrc/onos/flow/IFlowManager.java b/src/main/java/net/onrc/onos/flow/IFlowManager.java
index 743f8fb..598da85 100644
--- a/src/main/java/net/onrc/onos/flow/IFlowManager.java
+++ b/src/main/java/net/onrc/onos/flow/IFlowManager.java
@@ -1,11 +1,9 @@
package net.onrc.onos.flow;
-import java.util.Map;
-
import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.util.FlowEntry;
-import net.floodlightcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.FlowPath;
public interface IFlowManager {
/**
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
new file mode 100644
index 0000000..f9f3b67
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
@@ -0,0 +1,161 @@
+package net.onrc.onos.graph;
+
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.TransactionalGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
+import com.tinkerpop.frames.FramedGraph;
+
+public class GraphDBConnection implements IDBConnection {
+ public enum Transaction {
+ COMMIT, ROLLBACK
+ }
+
+ public enum GenerateEvent {
+ TRUE, FALSE
+ }
+
+ class TransactionHandle {
+ protected TransactionalGraph tr;
+
+ public void create() {
+ tr = graph.newTransaction();
+ }
+ }
+
+ protected static Logger log = LoggerFactory
+ .getLogger(GraphDBConnection.class);
+ private static GraphDBConnection singleton = new GraphDBConnection();
+ private static TitanGraph graph;
+ private static EventTransactionalGraph<TitanGraph> eg;
+ private static String configFile;
+
+ /*
+ * A private Constructor prevents any other class from instantiating.
+ */
+ private GraphDBConnection() {
+ }
+
+ /* Static 'instance' method */
+ /**
+ * Get the instance of GraphDBConnection class.
+ * @param conf the path to the database configuration file.
+ * @return GraphDBConnection instance.
+ */
+ public static synchronized GraphDBConnection getInstance(final String conf) {
+ if (GraphDBConnection.configFile == null
+ || GraphDBConnection.configFile.isEmpty()) {
+ GraphDBConnection.configFile = conf;
+ log.debug("GraphDBConnection::Setting Config File {}",
+ GraphDBConnection.configFile);
+ }
+ if (!GraphDBConnection.configFile.isEmpty()
+ && (graph == null || graph.isOpen() == Boolean.FALSE)) {
+ graph = TitanFactory.open(GraphDBConnection.configFile);
+ // FIXME: Creation on Indexes should be done only once
+ Set<String> s = graph.getIndexedKeys(Vertex.class);
+ if (!s.contains("dpid")) {
+ graph.createKeyIndex("dpid", Vertex.class);
+ }
+ if (!s.contains("port_id")) {
+ graph.createKeyIndex("port_id", Vertex.class);
+ }
+ if (!s.contains("type")) {
+ graph.createKeyIndex("type", Vertex.class);
+ }
+ if (!s.contains("dl_addr")) {
+ graph.createKeyIndex("dl_addr", Vertex.class);
+ }
+ if (!s.contains("flow_id")) {
+ graph.createKeyIndex("flow_id", Vertex.class);
+ }
+ if (!s.contains("flow_entry_id")) {
+ graph.createKeyIndex("flow_entry_id", Vertex.class);
+ }
+ if (!s.contains("switch_state")) {
+ graph.createKeyIndex("switch_state", Vertex.class);
+ }
+ graph.commit();
+ eg = new EventTransactionalGraph<TitanGraph>(graph);
+ }
+ return singleton;
+ }
+
+ /**
+ * Get a FramedGraph instance of the graph.
+ */
+ public FramedGraph<TitanGraph> getFramedGraph() {
+ if (isValid()) {
+ FramedGraph<TitanGraph> fg = new FramedGraph<TitanGraph>(graph);
+ return fg;
+ } else {
+ log.error("new FramedGraph failed");
+ return null;
+ }
+ }
+
+ /**
+ * Get EventTransactionalGraph of the titan graph.
+ * @return EventTransactionalGraph of the titan graph
+ */
+ protected EventTransactionalGraph<TitanGraph> getEventGraph() {
+ if (isValid()) {
+ return eg;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Add LocalGraphChangedLister for the graph.
+ */
+ public void addEventListener(final LocalGraphChangedListener listener) {
+ EventTransactionalGraph<TitanGraph> eg = this.getEventGraph();
+ eg.addListener(listener);
+ log.debug("Registered listener {}", listener.getClass());
+ }
+
+ /**
+ * Return whether this connection is valid.
+ */
+ public Boolean isValid() {
+ return (graph != null || graph.isOpen());
+ }
+
+ /**
+ * Commit changes for the graph operations.
+ */
+ public void commit() {
+ try {
+ graph.commit();
+ }
+ catch (Exception e) {
+ log.error("{}", e.toString());
+ }
+ }
+
+ /**
+ * Rollback changes for the graph operations.
+ */
+ public void rollback() {
+ try {
+ graph.rollback();
+ }
+ catch (Exception e) {
+ log.error("{}", e.toString());
+ }
+ }
+
+ /**
+ * Close this database connection.
+ */
+ public void close() {
+ commit();
+ }
+}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
new file mode 100644
index 0000000..acfe43b
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
@@ -0,0 +1,361 @@
+package net.onrc.onos.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openflow.protocol.OFPhysicalPort;
+
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
+import com.google.common.base.Stopwatch;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.frames.FramedGraph;
+import com.tinkerpop.frames.structures.FramedVertexIterable;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+
+public class GraphDBOperation implements IDBOperation {
+ private GraphDBConnection conn;
+
+ /**
+ * Create a GraphDBOperation instance from specified GraphDBConnection's instance.
+ * @param dbConnection an instance of GraphDBConnection
+ */
+ public GraphDBOperation(GraphDBConnection dbConnection) {
+ this.conn = dbConnection;
+ }
+
+ /**
+ * Create a GraphDBOperation instance from database configuration path.
+ * @param dbConfPath a path for database configuration file.
+ */
+ public GraphDBOperation(final String dbConfPath) {
+ this.conn = GraphDBConnection.getInstance(dbConfPath);
+ }
+
+ /**
+ * Create a new switch and return the created switch object.
+ * @param dpid DPID of the switch
+ */
+ public ISwitchObject newSwitch(String dpid) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ ISwitchObject obj = fg.addVertex(null,ISwitchObject.class);
+ if (obj != null) {
+ obj.setType("switch");
+ obj.setDPID(dpid);
+ }
+ return obj;
+ }
+
+ /**
+ * Search and get a switch object with DPID.
+ * @param dpid DPID of the switch
+ */
+ public ISwitchObject searchSwitch(String dpid) {
+
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+
+ return (fg != null && fg.getVertices("dpid",dpid).iterator().hasNext()) ?
+ fg.getVertices("dpid",dpid,ISwitchObject.class).iterator().next() : null;
+
+ }
+
+ /**
+ * Search and get an active switch object with DPID.
+ * @param dpid DPID of the switch
+ */
+ public ISwitchObject searchActiveSwitch(String dpid) {
+
+ ISwitchObject sw = searchSwitch(dpid);
+ if ((sw != null) &&
+ sw.getState().equals(SwitchState.ACTIVE.toString())) {
+ return sw;
+ }
+ return null;
+ }
+
+ /**
+ * Get all switch objects.
+ */
+ public Iterable<ISwitchObject> getAllSwitches() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
+ return switches;
+ }
+
+ /**
+ * Get all active switch objects.
+ */
+ public Iterable<ISwitchObject> getActiveSwitches() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
+ List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
+
+ for (ISwitchObject sw: switches) {
+ if(sw.getState().equals(SwitchState.ACTIVE.toString())) {
+ activeSwitches.add(sw);
+ }
+ }
+ return activeSwitches;
+ }
+
+ /**
+ * Get all inactive switch objects.
+ */
+ public Iterable<ISwitchObject> getInactiveSwitches() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
+ List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();
+
+ for (ISwitchObject sw: switches) {
+ if(sw.getState().equals(SwitchState.INACTIVE.toString())) {
+ inactiveSwitches.add(sw);
+ }
+ }
+ return inactiveSwitches;
+ }
+
+ /**
+ * Get all flow entries' objects where their switches are not updated.
+ */
+ public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ //TODO: Should use an enum for flow_switch_state
+ return fg.getVertices("switch_state", "FE_SWITCH_NOT_UPDATED", IFlowEntry.class);
+ }
+
+ /**
+ * Remove specified switch.
+ * @param sw switch object to remove
+ */
+ public void removeSwitch(ISwitchObject sw) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ fg.removeVertex(sw.asVertex());
+ }
+
+ @Override
+ public IPortObject newPort(String dpid, Short portNumber) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ IPortObject obj = fg.addVertex(null,IPortObject.class);
+ if (obj != null) {
+ obj.setType("port");
+ String id = dpid + portNumber.toString();
+ obj.setPortId(id);
+ obj.setNumber(portNumber);
+ }
+ return obj;
+
+ }
+
+ /**
+ * Create a port having specified port number.
+ * @param portNumber port number
+ */
+ @Deprecated
+ public IPortObject newPort(Short portNumber) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ IPortObject obj = fg.addVertex(null,IPortObject.class);
+ if (obj != null) {
+ obj.setType("port");
+ obj.setNumber(portNumber);
+ }
+ return obj;
+ }
+
+ /**
+ * Search and get a port object of specified switch and port number.
+ * @param dpid DPID of a switch
+ * @param number port number of the switch's port
+ */
+ public IPortObject searchPort(String dpid, Short number) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ String id = dpid + number.toString();
+ return (fg != null && fg.getVertices("port_id",id).iterator().hasNext()) ?
+ fg.getVertices("port_id",id,IPortObject.class).iterator().next() : null;
+ }
+
+ /**
+ * Remove the specified switch port.
+ * @param port switch port object to remove
+ */
+ public void removePort(IPortObject port) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+// EventGraph<TitanGraph> eg = conn.getEventGraph();
+ if (fg != null) fg.removeVertex(port.asVertex());
+ }
+
+ /**
+ * Create and return a device object.
+ */
+ public IDeviceObject newDevice() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ IDeviceObject obj = fg.addVertex(null,IDeviceObject.class);
+ if (obj != null) obj.setType("device");
+ return obj;
+ }
+
+ /**
+ * Search and get a device object having specified MAC address.
+ * @param macAddr MAC address to search and get
+ */
+ public IDeviceObject searchDevice(String macAddr) {
+ // TODO Auto-generated method stub
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ return (fg != null && fg.getVertices("dl_addr",macAddr).iterator().hasNext()) ?
+ fg.getVertices("dl_addr",macAddr, IDeviceObject.class).iterator().next() : null;
+ }
+
+ /**
+ * Get all devices.
+ */
+ public Iterable<IDeviceObject> getDevices() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ return fg != null ? fg.getVertices("type","device",IDeviceObject.class) : null;
+ }
+
+ /**
+ * Remove the specified device.
+ * @param dev a device object to remove
+ */
+ public void removeDevice(IDeviceObject dev) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ if (fg != null) fg.removeVertex(dev.asVertex());
+ }
+
+ /**
+ * Create and return a flow path object.
+ */
+ public IFlowPath newFlowPath() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ IFlowPath flowPath = fg.addVertex(null, IFlowPath.class);
+ if (flowPath != null) flowPath.setType("flow");
+ return flowPath;
+ }
+
+ /**
+ * Search and get a flow path object with specified flow ID.
+ * @param flowId flow ID to search
+ */
+ public IFlowPath searchFlowPath(FlowId flowId) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+
+ return fg.getVertices("flow_id", flowId.toString()).iterator().hasNext() ?
+ fg.getVertices("flow_id", flowId.toString(),
+ IFlowPath.class).iterator().next() : null;
+ }
+
+ /**
+ * Get a flow path object with a flow entry.
+ * @param flowEntry flow entry object
+ */
+ public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
+ GremlinPipeline<Vertex, IFlowPath> pipe = new GremlinPipeline<Vertex, IFlowPath>();
+ pipe.start(flowEntry.asVertex());
+ pipe.out("flow");
+ FramedVertexIterable<IFlowPath> r = new FramedVertexIterable(conn.getFramedGraph(), (Iterable) pipe, IFlowPath.class);
+ return r.iterator().hasNext() ? r.iterator().next() : null;
+ }
+
+ /**
+ * Get all flow path objects.
+ */
+ public Iterable<IFlowPath> getAllFlowPaths() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ Iterable<IFlowPath> flowPaths = fg.getVertices("type", "flow", IFlowPath.class);
+
+ List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();
+
+ for (IFlowPath fp: flowPaths) {
+ if (fp.getFlowId() != null) {
+ nonNullFlows.add(fp);
+ }
+ }
+ return nonNullFlows;
+ }
+
+ /**
+ * Remove the specified flow path.
+ * @param flowPath flow path object to remove
+ */
+ public void removeFlowPath(IFlowPath flowPath) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ fg.removeVertex(flowPath.asVertex());
+ }
+
+ /**
+ * Create and return a flow entry object.
+ */
+ public IFlowEntry newFlowEntry() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ IFlowEntry flowEntry = fg.addVertex(null, IFlowEntry.class);
+ if (flowEntry != null) flowEntry.setType("flow_entry");
+ return flowEntry;
+ }
+
+ /**
+ * Search and get a flow entry object with flow entry ID.
+ * @param flowEntryId flow entry ID to search
+ */
+ public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+
+ return fg.getVertices("flow_entry_id", flowEntryId.toString()).iterator().hasNext() ?
+ fg.getVertices("flow_entry_id", flowEntryId.toString(),
+ IFlowEntry.class).iterator().next() : null;
+ }
+
+ /**
+ * Get all flow entry objects.
+ */
+ public Iterable<IFlowEntry> getAllFlowEntries() {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+
+ return fg.getVertices("type", "flow_entry", IFlowEntry.class);
+ }
+
+ /**
+ * Remove the specified flow entry.
+ * @param flowEntry flow entry object to remove
+ */
+ public void removeFlowEntry(IFlowEntry flowEntry) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ fg.removeVertex(flowEntry.asVertex());
+ }
+
+ /**
+ * Get the instance of GraphDBConnection assigned to this class.
+ */
+ public IDBConnection getDBConnection() {
+ return conn;
+ }
+
+ /**
+ * Commit changes for the graph.
+ */
+ public void commit() {
+ conn.commit();
+ }
+
+ /**
+ * Rollback changes for the graph.
+ */
+ public void rollback() {
+ conn.rollback();
+ }
+
+ /**
+ * Close the connection of the assigned GraphDBConnection.
+ */
+ public void close() {
+ conn.close();
+ }
+
+
+}
diff --git a/src/main/java/net/onrc/onos/graph/IDBConnection.java b/src/main/java/net/onrc/onos/graph/IDBConnection.java
new file mode 100644
index 0000000..82ebba2
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/IDBConnection.java
@@ -0,0 +1,13 @@
+package net.onrc.onos.graph;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.frames.FramedGraph;
+
+public interface IDBConnection {
+ public FramedGraph<TitanGraph> getFramedGraph();
+ public void addEventListener(final LocalGraphChangedListener listener);
+ public Boolean isValid();
+ public void commit();
+ public void rollback();
+ public void close();
+}
diff --git a/src/main/java/net/onrc/onos/graph/IDBOperation.java b/src/main/java/net/onrc/onos/graph/IDBOperation.java
new file mode 100644
index 0000000..f873f27
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/IDBOperation.java
@@ -0,0 +1,48 @@
+package net.onrc.onos.graph;
+
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
+public interface IDBOperation {
+ public ISwitchObject newSwitch(String dpid);
+ public ISwitchObject searchSwitch(String dpid);
+ public ISwitchObject searchActiveSwitch(String dpid);
+ public Iterable<ISwitchObject> getActiveSwitches();
+ public Iterable<ISwitchObject> getAllSwitches();
+ public Iterable<ISwitchObject> getInactiveSwitches();
+ public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries();
+ public void removeSwitch(ISwitchObject sw);
+
+ @Deprecated
+ public IPortObject newPort(Short portNumber);
+ public IPortObject newPort(String dpid, Short portNum);
+ public IPortObject searchPort(String dpid, Short number);
+ public void removePort(IPortObject port);
+
+ public IDeviceObject newDevice();
+ public IDeviceObject searchDevice(String macAddr);
+ public Iterable<IDeviceObject> getDevices();
+ public void removeDevice(IDeviceObject dev);
+
+ public IFlowPath newFlowPath();
+ public IFlowPath searchFlowPath(FlowId flowId);
+ public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry);
+ public Iterable<IFlowPath> getAllFlowPaths();
+ public void removeFlowPath(IFlowPath flowPath);
+
+ public IFlowEntry newFlowEntry();
+ public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId);
+ public Iterable<IFlowEntry> getAllFlowEntries();
+ public void removeFlowEntry(IFlowEntry flowEntry);
+
+ public IDBConnection getDBConnection();
+ public void commit();
+ public void rollback();
+ public void close();
+
+}
diff --git a/src/main/java/net/onrc/onos/util/LocalGraphChangedListener.java b/src/main/java/net/onrc/onos/graph/LocalGraphChangedListener.java
similarity index 84%
rename from src/main/java/net/onrc/onos/util/LocalGraphChangedListener.java
rename to src/main/java/net/onrc/onos/graph/LocalGraphChangedListener.java
index ac819f9..5f3bbf1 100644
--- a/src/main/java/net/onrc/onos/util/LocalGraphChangedListener.java
+++ b/src/main/java/net/onrc/onos/graph/LocalGraphChangedListener.java
@@ -1,4 +1,4 @@
-package net.onrc.onos.util;
+package net.onrc.onos.graph;
import com.tinkerpop.blueprints.util.wrappers.event.listener.GraphChangedListener;
diff --git a/src/main/java/net/onrc/onos/util/LocalTopologyEventListener.java b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
similarity index 96%
rename from src/main/java/net/onrc/onos/util/LocalTopologyEventListener.java
rename to src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
index 61f227d..f83e7c2 100644
--- a/src/main/java/net/onrc/onos/util/LocalTopologyEventListener.java
+++ b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
@@ -1,8 +1,8 @@
-package net.onrc.onos.util;
+package net.onrc.onos.graph;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.flow.FlowManagerImpl;
import net.onrc.onos.flow.IFlowManager;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpPeer.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpPeer.java
new file mode 100644
index 0000000..7425a07
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpPeer.java
@@ -0,0 +1,42 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.net.InetAddress;
+
+import net.floodlightcontroller.util.MACAddress;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import com.google.common.net.InetAddresses;
+
+public class BgpPeer {
+ private String interfaceName;
+ private InetAddress ipAddress;
+ private MACAddress macAddress;
+
+ public String getInterfaceName() {
+ return interfaceName;
+ }
+
+ @JsonProperty("interface")
+ public void setInterfaceName(String interfaceName) {
+ this.interfaceName = interfaceName;
+ }
+
+ public InetAddress getIpAddress() {
+ return ipAddress;
+ }
+
+ @JsonProperty("ipAddress")
+ public void setIpAddress(String ipAddress) {
+ this.ipAddress = InetAddresses.forString(ipAddress);
+ }
+
+ public MACAddress getMacAddress() {
+ return macAddress;
+ }
+
+ @JsonProperty("macAddress")
+ public void setMacAddress(String macAddress) {
+ this.macAddress = MACAddress.valueOf(macAddress);
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
new file mode 100644
index 0000000..acdf185
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -0,0 +1,1060 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IOFSwitchListener;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.core.util.SingletonTask;
+import net.floodlightcontroller.devicemanager.IDeviceService;
+import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.packet.IPv4;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.routing.Link;
+import net.floodlightcontroller.topology.ITopologyListener;
+import net.floodlightcontroller.topology.ITopologyService;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.onrc.onos.ofcontroller.core.internal.TopoLinkServiceImpl;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
+import net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+import net.sf.json.JSONSerializer;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFMatch;
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPort;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionDataLayerDestination;
+import org.openflow.protocol.action.OFActionOutput;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+public class BgpRoute implements IFloodlightModule, IBgpRouteService,
+ ITopologyListener, IOFSwitchListener {
+
+ protected static Logger log = LoggerFactory.getLogger(BgpRoute.class);
+
+ protected IFloodlightProviderService floodlightProvider;
+ protected ITopologyService topology;
+ protected ITopoRouteService topoRouteService;
+ protected IDeviceService devices;
+ protected IRestApiService restApi;
+
+ protected ProxyArpManager proxyArp;
+
+ protected static Ptree ptree;
+ protected BlockingQueue<RibUpdate> ribUpdates;
+
+ protected String bgpdRestIp;
+ protected String routerId;
+ protected String configFilename = "config.json";
+
+ //We need to identify our flows somehow. But like it says in LearningSwitch.java,
+ //the controller/OS should hand out cookie IDs to prevent conflicts.
+ protected final long APP_COOKIE = 0xa0000000000000L;
+ //Cookie for flows that do L2 forwarding within SDN domain to egress routers
+ protected final long L2_FWD_COOKIE = APP_COOKIE + 1;
+ //Cookie for flows in ingress switches that rewrite the MAC address
+ protected final long MAC_RW_COOKIE = APP_COOKIE + 2;
+ //Cookie for flows that setup BGP paths
+ protected final long BGP_COOKIE = APP_COOKIE + 3;
+ //Forwarding uses priority 0, and the mac rewrite entries in ingress switches
+ //need to be higher priority than this otherwise the rewrite may not get done
+ protected final short SDNIP_PRIORITY = 10;
+
+ protected final short BGP_PORT = 179;
+
+ protected final int TOPO_DETECTION_WAIT = 2; //seconds
+
+ //Configuration stuff
+ protected List<String> switches;
+ protected Map<String, Interface> interfaces;
+ protected Map<InetAddress, BgpPeer> bgpPeers;
+ protected SwitchPort bgpdAttachmentPoint;
+
+ //True when all switches have connected
+ protected volatile boolean switchesConnected = false;
+ //True when we have a full mesh of shortest paths between gateways
+ protected volatile boolean topologyReady = false;
+
+ protected ArrayList<LDUpdate> linkUpdates;
+ protected SingletonTask topologyChangeDetectorTask;
+
+ protected class TopologyChangeDetector implements Runnable {
+ @Override
+ public void run() {
+ log.debug("Running topology change detection task");
+ synchronized (linkUpdates) {
+ //This is the model the REST API uses to retrieve network graph info
+ ITopoLinkService topoLinkService = new TopoLinkServiceImpl();
+
+ List<Link> activeLinks = topoLinkService.getActiveLinks();
+ //for (Link l : activeLinks){
+ //log.debug("active link: {}", l);
+ //}
+
+ Iterator<LDUpdate> it = linkUpdates.iterator();
+ while (it.hasNext()){
+ LDUpdate ldu = it.next();
+ Link l = new Link(ldu.getSrc(), ldu.getSrcPort(),
+ ldu.getDst(), ldu.getDstPort());
+
+ if (activeLinks.contains(l)){
+ log.debug("Not found: {}", l);
+ it.remove();
+ }
+ }
+ }
+
+ if (linkUpdates.isEmpty()){
+ //All updates have been seen in network map.
+ //We can check if topology is ready
+ log.debug("No known changes outstanding. Checking topology now");
+ checkStatus();
+ }
+ else {
+ //We know of some link updates that haven't propagated to the database yet
+ log.debug("Some changes not found in network map - {} links missing", linkUpdates.size());
+ topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
+ }
+ }
+ }
+
+ private void readGatewaysConfiguration(String gatewaysFilename){
+ File gatewaysFile = new File(gatewaysFilename);
+ ObjectMapper mapper = new ObjectMapper();
+
+ try {
+ Configuration config = mapper.readValue(gatewaysFile, Configuration.class);
+
+ switches = config.getSwitches();
+ interfaces = new HashMap<String, Interface>();
+ for (Interface intf : config.getInterfaces()){
+ interfaces.put(intf.getName(), intf);
+ }
+ bgpPeers = new HashMap<InetAddress, BgpPeer>();
+ for (BgpPeer peer : config.getPeers()){
+ bgpPeers.put(peer.getIpAddress(), peer);
+ }
+
+ bgpdAttachmentPoint = new SwitchPort(
+ new Dpid(config.getBgpdAttachmentDpid()),
+ new Port(config.getBgpdAttachmentPort()));
+
+ } catch (JsonParseException e) {
+ log.error("Error in JSON file", e);
+ System.exit(1);
+ } catch (JsonMappingException e) {
+ log.error("Error in JSON file", e);
+ System.exit(1);
+ } catch (IOException e) {
+ log.error("Error reading JSON file", e);
+ System.exit(1);
+ }
+ }
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+ Collection<Class<? extends IFloodlightService>> l
+ = new ArrayList<Class<? extends IFloodlightService>>();
+ l.add(IBgpRouteService.class);
+ return l;
+ }
+
+ @Override
+ public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+ Map<Class<? extends IFloodlightService>, IFloodlightService> m
+ = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+ m.put(IBgpRouteService.class, this);
+ return m;
+ }
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+ Collection<Class<? extends IFloodlightService>> l
+ = new ArrayList<Class<? extends IFloodlightService>>();
+ l.add(IFloodlightProviderService.class);
+ l.add(ITopologyService.class);
+ l.add(IDeviceService.class);
+ l.add(IRestApiService.class);
+ return l;
+ }
+
+ @Override
+ public void init(FloodlightModuleContext context)
+ throws FloodlightModuleException {
+
+ ptree = new Ptree(32);
+
+ ribUpdates = new LinkedBlockingQueue<RibUpdate>();
+
+ // Register floodlight provider and REST handler.
+ floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+ topology = context.getServiceImpl(ITopologyService.class);
+ devices = context.getServiceImpl(IDeviceService.class);
+ restApi = context.getServiceImpl(IRestApiService.class);
+
+ //TODO We'll initialise this here for now, but it should really be done as
+ //part of the controller core
+ proxyArp = new ProxyArpManager(floodlightProvider, topology, devices);
+
+ linkUpdates = new ArrayList<LDUpdate>();
+ ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
+ topologyChangeDetectorTask = new SingletonTask(executor, new TopologyChangeDetector());
+
+ topoRouteService = new TopoRouteService("");
+
+ //Read in config values
+ bgpdRestIp = context.getConfigParams(this).get("BgpdRestIp");
+ if (bgpdRestIp == null){
+ log.error("BgpdRestIp property not found in config file");
+ System.exit(1);
+ }
+ else {
+ log.info("BgpdRestIp set to {}", bgpdRestIp);
+ }
+
+ routerId = context.getConfigParams(this).get("RouterId");
+ if (routerId == null){
+ log.error("RouterId property not found in config file");
+ System.exit(1);
+ }
+ else {
+ log.info("RouterId set to {}", routerId);
+ }
+
+ String configFilenameParameter = context.getConfigParams(this).get("configfile");
+ if (configFilenameParameter != null){
+ configFilename = configFilenameParameter;
+ }
+ log.debug("Config file set to {}", configFilename);
+
+ readGatewaysConfiguration(configFilename);
+ // Test.
+ //test();
+ }
+
+ public Ptree getPtree() {
+ return ptree;
+ }
+
+ public void clearPtree() {
+ //ptree = null;
+ ptree = new Ptree(32);
+ }
+
+ public String getBGPdRestIp() {
+ return bgpdRestIp;
+ }
+
+ public String getRouterId() {
+ return routerId;
+ }
+
+ // Return nexthop address as byte array.
+ public Rib lookupRib(byte[] dest) {
+ if (ptree == null) {
+ log.debug("lookupRib: ptree null");
+ return null;
+ }
+
+ PtreeNode node = ptree.match(dest, 32);
+ if (node == null) {
+ log.debug("lookupRib: ptree node null");
+ return null;
+ }
+
+ if (node.rib == null) {
+ log.debug("lookupRib: ptree rib null");
+ return null;
+ }
+
+ ptree.delReference(node);
+
+ return node.rib;
+ }
+
+ //TODO looks like this should be a unit test
+ @SuppressWarnings("unused")
+ private void test() throws UnknownHostException {
+ System.out.println("Here it is");
+ Prefix p = new Prefix("128.0.0.0", 8);
+ Prefix q = new Prefix("8.0.0.0", 8);
+ Prefix r = new Prefix("10.0.0.0", 24);
+ Prefix a = new Prefix("10.0.0.1", 32);
+
+ ptree.acquire(p.getAddress(), p.getPrefixLength());
+ ptree.acquire(q.getAddress(), q.getPrefixLength());
+ ptree.acquire(r.getAddress(), r.getPrefixLength());
+
+ System.out.println("Traverse start");
+ for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
+ Prefix p_result = new Prefix(node.key, node.keyBits);
+ }
+
+ PtreeNode n = ptree.match(a.getAddress(), a.getPrefixLength());
+ if (n != null) {
+ System.out.println("Matched prefix for 10.0.0.1:");
+ Prefix x = new Prefix(n.key, n.keyBits);
+ ptree.delReference(n);
+ }
+
+ n = ptree.lookup(p.getAddress(), p.getPrefixLength());
+ if (n != null) {
+ ptree.delReference(n);
+ ptree.delReference(n);
+ }
+ System.out.println("Traverse start");
+ for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
+ Prefix p_result = new Prefix(node.key, node.keyBits);
+ }
+
+ n = ptree.lookup(q.getAddress(), q.getPrefixLength());
+ if (n != null) {
+ ptree.delReference(n);
+ ptree.delReference(n);
+ }
+ System.out.println("Traverse start");
+ for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
+ Prefix p_result = new Prefix(node.key, node.keyBits);
+ }
+
+ n = ptree.lookup(r.getAddress(), r.getPrefixLength());
+ if (n != null) {
+ ptree.delReference(n);
+ ptree.delReference(n);
+ }
+ System.out.println("Traverse start");
+ for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
+ Prefix p_result = new Prefix(node.key, node.keyBits);
+ }
+
+ }
+
+ private String getPrefixFromPtree(PtreeNode node){
+ InetAddress address = null;
+ try {
+ address = InetAddress.getByAddress(node.key);
+ } catch (UnknownHostException e1) {
+ //Should never happen is the reverse conversion has already been done
+ log.error("Malformed IP address");
+ return "";
+ }
+ return address.toString() + "/" + node.rib.masklen;
+ }
+
+ private void retrieveRib(){
+ String url = "http://" + bgpdRestIp + "/wm/bgp/" + routerId;
+ String response = RestClient.get(url);
+
+ if (response.equals("")){
+ return;
+ }
+
+ response = response.replaceAll("\"", "'");
+ JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(response);
+ JSONArray rib_json_array = jsonObj.getJSONArray("rib");
+ String router_id = jsonObj.getString("router-id");
+
+ int size = rib_json_array.size();
+
+ log.info("Retrived RIB of {} entries from BGPd", size);
+
+ for (int j = 0; j < size; j++) {
+ JSONObject second_json_object = rib_json_array.getJSONObject(j);
+ String prefix = second_json_object.getString("prefix");
+ String nexthop = second_json_object.getString("nexthop");
+
+ //insert each rib entry into the local rib;
+ String[] substring = prefix.split("/");
+ String prefix1 = substring[0];
+ String mask1 = substring[1];
+
+ Prefix p;
+ try {
+ p = new Prefix(prefix1, Integer.valueOf(mask1));
+ } catch (NumberFormatException e) {
+ log.warn("Wrong mask format in RIB JSON: {}", mask1);
+ continue;
+ } catch (UnknownHostException e1) {
+ log.warn("Wrong prefix format in RIB JSON: {}", prefix1);
+ continue;
+ }
+
+ PtreeNode node = ptree.acquire(p.getAddress(), p.getPrefixLength());
+ Rib rib = new Rib(router_id, nexthop, p.getPrefixLength());
+
+ if (node.rib != null) {
+ node.rib = null;
+ ptree.delReference(node);
+ }
+
+ node.rib = rib;
+
+ prefixAdded(node);
+ }
+ }
+
+ @Override
+ public void newRibUpdate(RibUpdate update) {
+ ribUpdates.add(update);
+ }
+
+ //TODO temporary
+ public void wrapPrefixAdded(RibUpdate update) {
+ Prefix prefix = update.getPrefix();
+
+ PtreeNode node = ptree.acquire(prefix.getAddress(), prefix.getPrefixLength());
+
+ if (node.rib != null) {
+ node.rib = null;
+ ptree.delReference(node);
+ }
+ node.rib = update.getRibEntry();
+
+ prefixAdded(node);
+ }
+
+ //TODO temporary
+ public void wrapPrefixDeleted(RibUpdate update) {
+ Prefix prefix = update.getPrefix();
+
+ PtreeNode node = ptree.lookup(prefix.getAddress(), prefix.getPrefixLength());
+
+ /*
+ * Remove the flows from the switches before the rib is lost
+ * Theory: we could get a delete for a prefix not in the Ptree.
+ * This would result in a null node being returned. We could get a delete for
+ * a node that's not actually there, but is a aggregate node. This would result
+ * in a non-null node with a null rib. Only a non-null node with a non-null
+ * rib is an actual prefix in the Ptree.
+ */
+ if (node != null && node.rib != null){
+ prefixDeleted(node);
+ }
+
+ if (node != null && node.rib != null) {
+ if (update.getRibEntry().equals(node.rib)) {
+ node.rib = null;
+ ptree.delReference(node);
+ }
+ }
+ }
+
+ @Override
+ public void prefixAdded(PtreeNode node) {
+ if (!topologyReady){
+ return;
+ }
+
+ String prefix = getPrefixFromPtree(node);
+
+ log.debug("New prefix {} added, next hop {}, routerId {}",
+ new Object[] {prefix, node.rib.nextHop.toString(),
+ node.rib.routerId.getHostAddress()});
+
+ //TODO this is wrong, we shouldn't be dealing with BGP peers here.
+ //We need to figure out where the device is attached and what its
+ //mac address is by learning.
+ //The next hop is not necessarily the peer, and the peer's attachment
+ //point is not necessarily the next hop's attachment point.
+ BgpPeer peer = bgpPeers.get(node.rib.nextHop);
+
+ if (peer == null){
+ //TODO local router isn't in peers list so this will get thrown
+ //Need to work out what to do about local prefixes with next hop 0.0.0.0.
+
+ //The other scenario is this is a route server route. In that
+ //case the next hop is not in our configuration
+ log.error("Couldn't find next hop router in router {} in config"
+ , node.rib.nextHop.toString());
+ return; //just quit out here? This is probably a configuration error
+ }
+
+ Interface peerInterface = interfaces.get(peer.getInterfaceName());
+
+ //Add a flow to rewrite mac for this prefix to all border switches
+ for (Interface srcInterface : interfaces.values()) {
+ if (srcInterface == peerInterface) {
+ //Don't push a flow for the switch where this peer is attached
+ continue;
+ }
+
+ DataPath shortestPath = topoRouteService.getShortestPath(
+ srcInterface.getSwitchPort(),
+ peerInterface.getSwitchPort());
+
+ if (shortestPath == null){
+ log.debug("Shortest path between {} and {} not found",
+ srcInterface.getSwitchPort(),
+ peerInterface.getSwitchPort());
+ return; // just quit here?
+ }
+
+ //TODO check the shortest path against the cached version we
+ //calculated before. If they don't match up that's a problem
+
+ //Set up the flow mod
+ OFFlowMod fm =
+ (OFFlowMod) floodlightProvider.getOFMessageFactory()
+ .getMessage(OFType.FLOW_MOD);
+
+ fm.setIdleTimeout((short)0)
+ .setHardTimeout((short)0)
+ .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+ .setCookie(MAC_RW_COOKIE)
+ .setCommand(OFFlowMod.OFPFC_ADD)
+ .setPriority(SDNIP_PRIORITY)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH
+ + OFActionDataLayerDestination.MINIMUM_LENGTH
+ + OFActionOutput.MINIMUM_LENGTH);
+
+ OFMatch match = new OFMatch();
+ match.setDataLayerType(Ethernet.TYPE_IPv4);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+
+ //match.setDataLayerSource(ingressRouter.getRouterMac().toBytes());
+ //match.setDataLayerSource(peer.getMacAddress().toBytes());
+ //match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
+
+ InetAddress address = null;
+ try {
+ address = InetAddress.getByAddress(node.key);
+ } catch (UnknownHostException e1) {
+ //Should never happen is the reverse conversion has already been done
+ log.error("Malformed IP address");
+ return;
+ }
+
+ match.setFromCIDR(address.getHostAddress() + "/" + node.rib.masklen, OFMatch.STR_NW_DST);
+ fm.setMatch(match);
+
+ //Set up MAC rewrite action
+ OFActionDataLayerDestination macRewriteAction = new OFActionDataLayerDestination();
+ //TODO use ARP module rather than configured mac addresses
+ //TODO the peer's mac address is not necessarily the next hop's...
+ macRewriteAction.setDataLayerAddress(peer.getMacAddress().toBytes());
+
+ //Set up output action
+ OFActionOutput outputAction = new OFActionOutput();
+ outputAction.setMaxLength((short)0xffff);
+
+ Port outputPort = shortestPath.flowEntries().get(0).outPort();
+ outputAction.setPort(outputPort.value());
+
+ List<OFAction> actions = new ArrayList<OFAction>();
+ actions.add(macRewriteAction);
+ actions.add(outputAction);
+ fm.setActions(actions);
+
+ //Write to switch
+ IOFSwitch sw = floodlightProvider.getSwitches()
+ .get(srcInterface.getDpid());
+
+ if (sw == null){
+ log.warn("Switch not found when pushing flow mod");
+ continue;
+ }
+
+ List<OFMessage> msglist = new ArrayList<OFMessage>();
+ msglist.add(fm);
+ try {
+ sw.write(msglist, null);
+ sw.flush();
+ } catch (IOException e) {
+ log.error("Failure writing flow mod", e);
+ }
+ }
+ }
+
+ //TODO this is largely untested
+ @Override
+ public void prefixDeleted(PtreeNode node) {
+ if (!topologyReady) {
+ return;
+ }
+
+ String prefix = getPrefixFromPtree(node);
+
+ log.debug("Prefix {} deleted, next hop {}",
+ prefix, node.rib.nextHop.toString());
+
+ //Remove MAC rewriting flows from other border switches
+ BgpPeer peer = bgpPeers.get(node.rib.nextHop);
+ if (peer == null){
+ //either a router server route or local route. Can't handle right now
+ return;
+ }
+
+ Interface peerInterface = interfaces.get(peer.getInterfaceName());
+
+ for (Interface srcInterface : interfaces.values()) {
+ if (srcInterface == peerInterface) {
+ continue;
+ }
+
+ //Set up the flow mod
+ OFFlowMod fm =
+ (OFFlowMod) floodlightProvider.getOFMessageFactory()
+ .getMessage(OFType.FLOW_MOD);
+
+ fm.setIdleTimeout((short)0)
+ .setHardTimeout((short)0)
+ .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+ .setCookie(MAC_RW_COOKIE)
+ .setCommand(OFFlowMod.OFPFC_DELETE)
+ .setOutPort(OFPort.OFPP_NONE)
+ .setPriority(SDNIP_PRIORITY)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH);
+ //+ OFActionDataLayerDestination.MINIMUM_LENGTH
+ //+ OFActionOutput.MINIMUM_LENGTH);
+
+ OFMatch match = new OFMatch();
+ match.setDataLayerType(Ethernet.TYPE_IPv4);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+
+ //match.setDataLayerSource(ingressRouter.getRouterMac().toBytes());
+ //match.setDataLayerSource(peer.getMacAddress().toBytes());
+ //match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
+
+ InetAddress address = null;
+ try {
+ address = InetAddress.getByAddress(node.key);
+ } catch (UnknownHostException e1) {
+ //Should never happen is the reverse conversion has already been done
+ log.error("Malformed IP address");
+ return;
+ }
+
+ match.setFromCIDR(address.getHostAddress() + "/" + node.rib.masklen, OFMatch.STR_NW_DST);
+ fm.setMatch(match);
+
+ //Write to switch
+ IOFSwitch sw = floodlightProvider.getSwitches()
+ .get(srcInterface.getDpid());
+
+ if (sw == null){
+ log.warn("Switch not found when pushing flow mod");
+ continue;
+ }
+
+ List<OFMessage> msglist = new ArrayList<OFMessage>();
+ msglist.add(fm);
+ try {
+ sw.write(msglist, null);
+ sw.flush();
+ } catch (IOException e) {
+ log.error("Failure writing flow mod", e);
+ }
+ }
+ }
+
+ /*
+ * On startup we need to calculate a full mesh of paths between all gateway
+ * switches
+ */
+ private void setupFullMesh(){
+ //For each border router, calculate and install a path from every other
+ //border switch to said border router. However, don't install the entry
+ //in to the first hop switch, as we need to install an entry to rewrite
+ //for each prefix received. This will be done later when prefixes have
+ //actually been received.
+
+ for (BgpPeer peer : bgpPeers.values()) {
+ Interface peerInterface = interfaces.get(peer.getInterfaceName());
+ //for (Map.Entry<String, Interface> intfEntry : interfaces.entrySet()) {
+ for (Interface srcInterface : interfaces.values()) {
+ //Interface srcInterface = intfEntry.getValue();
+ //if (peer.getInterfaceName().equals(intfEntry.getKey())){
+ if (peer.getInterfaceName().equals(srcInterface.getName())){
+ continue;
+ }
+
+ DataPath shortestPath = topoRouteService.getShortestPath(
+ srcInterface.getSwitchPort(), peerInterface.getSwitchPort());
+
+ if (shortestPath == null){
+ log.debug("Shortest path between {} and {} not found",
+ srcInterface.getSwitchPort(), peerInterface.getSwitchPort());
+ return; // just quit here?
+ }
+
+ //install flows
+ installPath(shortestPath.flowEntries(), peer);
+ }
+ }
+ }
+
+ private void installPath(List<FlowEntry> flowEntries, BgpPeer peer){
+ //Set up the flow mod
+ OFFlowMod fm =
+ (OFFlowMod) floodlightProvider.getOFMessageFactory()
+ .getMessage(OFType.FLOW_MOD);
+
+ OFActionOutput action = new OFActionOutput();
+ action.setMaxLength((short)0xffff);
+ List<OFAction> actions = new ArrayList<OFAction>();
+ actions.add(action);
+
+ fm.setIdleTimeout((short)0)
+ .setHardTimeout((short)0)
+ .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+ .setCookie(L2_FWD_COOKIE)
+ .setCommand(OFFlowMod.OFPFC_ADD)
+ .setActions(actions)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+
+ //Don't push the first flow entry. We need to push entries in the
+ //first switch based on IP prefix which we don't know yet.
+ for (int i = 1; i < flowEntries.size(); i++){
+ FlowEntry flowEntry = flowEntries.get(i);
+
+ OFMatch match = new OFMatch();
+ //TODO Again using MAC address from configuration
+ match.setDataLayerDestination(peer.getMacAddress().toBytes());
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
+ ((OFActionOutput) fm.getActions().get(0)).setPort(flowEntry.outPort().value());
+
+ fm.setMatch(match);
+
+ IOFSwitch sw = floodlightProvider.getSwitches().get(flowEntry.dpid().value());
+
+ if (sw == null){
+ log.warn("Switch not found when pushing flow mod");
+ continue;
+ }
+
+ List<OFMessage> msglist = new ArrayList<OFMessage>();
+ msglist.add(fm);
+ try {
+ sw.write(msglist, null);
+ sw.flush();
+ } catch (IOException e) {
+ log.error("Failure writing flow mod", e);
+ }
+
+ try {
+ fm = fm.clone();
+ } catch (CloneNotSupportedException e1) {
+ log.error("Failure cloning flow mod", e1);
+ }
+ }
+ }
+
+ private void setupBgpPaths(){
+ for (BgpPeer bgpPeer : bgpPeers.values()){
+ Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
+
+ DataPath path = topoRouteService.getShortestPath(
+ peerInterface.getSwitchPort(), bgpdAttachmentPoint);
+
+ if (path == null){
+ log.debug("Unable to compute path for BGP traffic for {}",
+ bgpPeer.getIpAddress());
+ continue;
+ }
+
+ //Set up the flow mod
+ OFFlowMod fm =
+ (OFFlowMod) floodlightProvider.getOFMessageFactory()
+ .getMessage(OFType.FLOW_MOD);
+
+ OFActionOutput action = new OFActionOutput();
+ action.setMaxLength((short)0xffff);
+ List<OFAction> actions = new ArrayList<OFAction>();
+ actions.add(action);
+
+ fm.setIdleTimeout((short)0)
+ .setHardTimeout((short)0)
+ .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+ .setCookie(BGP_COOKIE)
+ .setCommand(OFFlowMod.OFPFC_ADD)
+ .setPriority(SDNIP_PRIORITY)
+ .setActions(actions)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+
+ //Forward = gateway -> bgpd, reverse = bgpd -> gateway
+ OFMatch forwardMatchSrc = new OFMatch();
+
+
+ String interfaceCidrAddress = peerInterface.getIpAddress().getHostAddress()
+ + "/32";
+ String peerCidrAddress = bgpPeer.getIpAddress().getHostAddress()
+ + "/32";
+
+ //Common match fields
+ forwardMatchSrc.setDataLayerType(Ethernet.TYPE_IPv4);
+ //forwardMatch.setWildcards(forwardMatch.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+ forwardMatchSrc.setNetworkProtocol(IPv4.PROTOCOL_TCP);
+ forwardMatchSrc.setTransportDestination(BGP_PORT);
+ forwardMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_IN_PORT
+ & ~OFMatch.OFPFW_DL_TYPE & ~OFMatch.OFPFW_NW_PROTO);
+
+
+ OFMatch reverseMatchSrc = forwardMatchSrc.clone();
+
+ forwardMatchSrc.setFromCIDR(peerCidrAddress, OFMatch.STR_NW_SRC);
+ forwardMatchSrc.setFromCIDR(interfaceCidrAddress, OFMatch.STR_NW_DST);
+
+ OFMatch forwardMatchDst = forwardMatchSrc.clone();
+
+ forwardMatchSrc.setTransportSource(BGP_PORT);
+ forwardMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
+ forwardMatchDst.setTransportDestination(BGP_PORT);
+ forwardMatchDst.setWildcards(forwardMatchDst.getWildcards() & ~OFMatch.OFPFW_TP_DST);
+
+ reverseMatchSrc.setFromCIDR(interfaceCidrAddress, OFMatch.STR_NW_SRC);
+ reverseMatchSrc.setFromCIDR(peerCidrAddress, OFMatch.STR_NW_DST);
+
+ OFMatch reverseMatchDst = reverseMatchSrc.clone();
+
+ reverseMatchSrc.setTransportSource(BGP_PORT);
+ reverseMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
+ reverseMatchDst.setTransportDestination(BGP_PORT);
+ reverseMatchDst.setWildcards(forwardMatchDst.getWildcards() & ~OFMatch.OFPFW_TP_DST);
+
+ fm.setMatch(forwardMatchSrc);
+
+ for (FlowEntry flowEntry : path.flowEntries()){
+ OFFlowMod forwardFlowModSrc, forwardFlowModDst;
+ OFFlowMod reverseFlowModSrc, reverseFlowModDst;
+ try {
+ forwardFlowModSrc = fm.clone();
+ forwardFlowModDst = fm.clone();
+ reverseFlowModSrc = fm.clone();
+ reverseFlowModDst = fm.clone();
+ } catch (CloneNotSupportedException e) {
+ log.warn("Clone failed", e);
+ continue;
+ }
+
+ forwardMatchSrc.setInputPort(flowEntry.inPort().value());
+ forwardFlowModSrc.setMatch(forwardMatchSrc);
+ ((OFActionOutput)forwardFlowModSrc.getActions().get(0))
+ .setPort(flowEntry.outPort().value());
+
+ forwardMatchDst.setInputPort(flowEntry.inPort().value());
+ forwardFlowModDst.setMatch(forwardMatchDst);
+ ((OFActionOutput)forwardFlowModDst.getActions().get(0))
+ .setPort(flowEntry.outPort().value());
+
+ reverseMatchSrc.setInputPort(flowEntry.outPort().value());
+ reverseFlowModSrc.setMatch(reverseMatchSrc);
+ ((OFActionOutput)reverseFlowModSrc.getActions().get(0))
+ .setPort(flowEntry.inPort().value());
+
+ reverseMatchDst.setInputPort(flowEntry.outPort().value());
+ reverseFlowModDst.setMatch(reverseMatchDst);
+ ((OFActionOutput)reverseFlowModDst.getActions().get(0))
+ .setPort(flowEntry.inPort().value());
+
+ IOFSwitch sw = floodlightProvider.getSwitches().get(flowEntry.dpid().value());
+
+ //Hopefully the switch is there
+ List<OFMessage> msgList = new ArrayList<OFMessage>(2);
+ msgList.add(forwardFlowModSrc);
+ msgList.add(forwardFlowModDst);
+ msgList.add(reverseFlowModSrc);
+ msgList.add(reverseFlowModDst);
+
+ try {
+ sw.write(msgList, null);
+ sw.flush();
+ } catch (IOException e) {
+ log.error("Failure writing flow mod", e);
+ }
+ }
+ }
+ }
+
+ private void beginRouting(){
+ log.debug("Topology is now ready, beginning routing function");
+ setupBgpPaths();
+ setupFullMesh();
+
+ //Traverse ptree and create flows for all routes
+ for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)){
+ if (node.rib != null){
+ prefixAdded(node);
+ }
+ }
+ }
+
+ private void checkSwitchesConnected(){
+ for (String dpid : switches){
+ if (floodlightProvider.getSwitches().get(HexString.toLong(dpid)) == null){
+ log.debug("Not all switches are here yet");
+ return;
+ }
+ }
+ switchesConnected = true;
+ }
+
+ //Actually we only need to go half way round to verify full mesh connectivity
+ //(n^2)/2
+ private void checkTopologyReady(){
+ for (Interface dstInterface : interfaces.values()) {
+ for (Interface srcInterface : interfaces.values()) {
+ if (dstInterface == srcInterface) {
+ continue;
+ }
+
+ DataPath shortestPath = topoRouteService.getShortestPath(
+ srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
+
+ if (shortestPath == null){
+ log.debug("Shortest path between {} and {} not found",
+ srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
+ return;
+ }
+ }
+ }
+ topologyReady = true;
+ }
+
+ private void checkStatus(){
+ log.debug("In checkStatus, swC {}, toRe {}", switchesConnected, topologyReady);
+
+ if (!switchesConnected){
+ checkSwitchesConnected();
+ }
+ boolean oldTopologyReadyStatus = topologyReady;
+ if (switchesConnected && !topologyReady){
+ checkTopologyReady();
+ }
+ if (!oldTopologyReadyStatus && topologyReady){
+ beginRouting();
+ }
+ }
+
+ @Override
+ public void startUp(FloodlightModuleContext context) {
+ restApi.addRestletRoutable(new BgpRouteWebRoutable());
+ floodlightProvider.addOFSwitchListener(this);
+ topology.addListener(this);
+
+ floodlightProvider.addOFMessageListener(OFType.PACKET_IN, proxyArp);
+
+ ExecutorService e = Executors.newSingleThreadExecutor(
+ new ThreadFactoryBuilder().setNameFormat("bgp-updates-%d").build());
+
+
+ e.execute(new Runnable() {
+ @Override
+ public void run() {
+ doUpdatesThread();
+ }
+ });
+
+ //Retrieve the RIB from BGPd during startup
+ retrieveRib();
+ }
+
+ private void doUpdatesThread() {
+ boolean interrupted = false;
+ try {
+ while (true) {
+ try {
+ RibUpdate update = ribUpdates.take();
+ switch (update.getOperation()){
+ case UPDATE:
+ wrapPrefixAdded(update);
+ break;
+ case DELETE:
+ wrapPrefixDeleted(update);
+ break;
+ }
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ } finally {
+ if (interrupted) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ @Override
+ public void topologyChanged() {
+ //There seems to be more topology events than there should be. Lots of link
+ //updated, port up and switch updated on what should be a fairly static topology
+
+ boolean refreshNeeded = false;
+ for (LDUpdate ldu : topology.getLastLinkUpdates()){
+ if (!ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_UPDATED)){
+ //We don't need to recalculate anything for just link updates
+ //They happen way too frequently (may be a bug in our link discovery)
+ refreshNeeded = true;
+ }
+
+ log.debug("Topo change {}", ldu.getOperation());
+
+ if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_ADDED)){
+ synchronized (linkUpdates) {
+ linkUpdates.add(ldu);
+ }
+ }
+ }
+
+ if (refreshNeeded){
+ topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
+ }
+ }
+
+ //TODO determine whether we need to listen for switch joins
+ @Override
+ public void addedSwitch(IOFSwitch sw) {
+ //checkStatus();
+ }
+
+ @Override
+ public void removedSwitch(IOFSwitch sw) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void switchPortChanged(Long switchId) {}
+
+ @Override
+ public String getName() {
+ return "BgpRoute";
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
new file mode 100644
index 0000000..19b44c8
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
@@ -0,0 +1,233 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.net.UnknownHostException;
+
+import net.onrc.onos.ofcontroller.bgproute.RibUpdate.Operation;
+
+import org.restlet.resource.Delete;
+import org.restlet.resource.Get;
+import org.restlet.resource.Post;
+import org.restlet.resource.ServerResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BgpRouteResource extends ServerResource {
+
+ protected static Logger log = LoggerFactory.getLogger(BgpRouteResource.class);
+
+ private String addrToString(byte [] addr) {
+ String str = "";
+
+ for (int i = 0; i < 4; i++) {
+ int val = (addr[i] & 0xff);
+ str += val;
+ if (i != 3)
+ str += ".";
+ }
+
+ return str;
+ }
+
+ //@SuppressWarnings("unused")
+ @Get
+ public String get(String fmJson) {
+ String dest = (String) getRequestAttributes().get("dest");
+ String output = "";
+ IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
+ get(IBgpRouteService.class.getCanonicalName());
+
+ if (dest != null) {
+ //TODO Needs to be changed to use the new RestClient.get().
+
+
+ //Prefix p;
+ //try {
+ // p = new Prefix(dest, 32);
+ //} catch (UnknownHostException e) {
+ //if (p == null) {
+ // return "[GET]: dest address format is wrong";
+ //}
+
+ // the dest here refers to router-id
+ //bgpdRestIp includes port number, such as 1.1.1.1:8080
+ String BGPdRestIp = bgpRoute.getBGPdRestIp();
+ String url="http://"+BGPdRestIp+"/wm/bgp/"+dest;
+
+ RestClient.get(url);
+
+ output="Get rib from bgpd finished!\n";
+ return output;
+ }
+ else {
+ Ptree ptree = bgpRoute.getPtree();
+ output += "{\n \"rib\": [\n";
+ boolean printed = false;
+
+ for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
+ if (node.rib == null) {
+ continue;
+ }
+ if (printed == true) {
+ output += ",\n";
+ }
+ output += " {\"prefix\": \"" + addrToString(node.key) + "/" + node.keyBits +"\", ";
+ output += "\"nexthop\": \"" + addrToString(node.rib.nextHop.getAddress()) +"\"}";
+ printed = true;
+ }
+ //output += "{\"router_id\": \"" + addrToString(node.rib.routerId.getAddress()) +"\"}\n";
+ output += "\n ]\n}\n";
+ }
+
+ return output;
+ }
+
+ //unused?
+ /*
+ public static ByteBuffer toByteBuffer(String value) throws UnsupportedEncodingException {
+ return ByteBuffer.wrap(value.getBytes("UTF-8"));
+ }
+ */
+
+ //unused?
+ /*
+ public static String toString(ByteBuffer buffer) throws UnsupportedEncodingException {
+ byte[] bytes = new byte[buffer.remaining()];
+ buffer.get(bytes);
+ return new String(bytes, "UTF-8");
+ }
+ */
+
+ @Post
+ public String store(String fmJson) {
+ IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
+ get(IBgpRouteService.class.getCanonicalName());
+
+ //Ptree ptree = bgpRoute.getPtree();
+
+ String routerId = (String) getRequestAttributes().get("routerid");
+ String prefix = (String) getRequestAttributes().get("prefix");
+ String mask = (String) getRequestAttributes().get("mask");
+ String nexthop = (String) getRequestAttributes().get("nexthop");
+ String capability = (String) getRequestAttributes().get("capability");
+
+ String reply = "";
+
+ if (capability == null) {
+ // this is a prefix add
+ Prefix p;
+ try {
+ p = new Prefix(prefix, Integer.valueOf(mask));
+ } catch (NumberFormatException e) {
+ reply = "[POST: mask format is wrong]";
+ log.info(reply);
+ return reply + "\n";
+ } catch (UnknownHostException e1) {
+ reply = "[POST: prefix format is wrong]";
+ log.info(reply);
+ return reply + "\n";
+ }
+
+ Rib rib = new Rib(routerId, nexthop, p.getPrefixLength());
+
+ bgpRoute.newRibUpdate(new RibUpdate(Operation.UPDATE, p, rib));
+
+ /*
+ PtreeNode node = ptree.acquire(p.getAddress(), p.getPrefixLength());
+
+ if (node.rib != null) {
+ node.rib = null;
+ ptree.delReference(node);
+ }
+ node.rib = rib;
+
+ bgpRoute.prefixAdded(node);
+ */
+
+ reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "]";
+ log.info(reply);
+ }
+ else if(capability.equals("1")) {
+ reply = "[POST-capability: " + capability + "]\n";
+ log.info(reply);
+ // to store the number in the top node of the Ptree
+ }
+ else {
+ reply = "[POST-capability: " + capability + "]\n";
+ log.info(reply);
+ // to store the number in the top node of the Ptree
+ }
+
+ return reply + "\n";
+ }
+
+ @Delete
+ public String delete(String fmJson) {
+ IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
+ get(IBgpRouteService.class.getCanonicalName());
+
+ //Ptree ptree = bgpRoute.getPtree();
+
+ String routerId = (String) getRequestAttributes().get("routerid");
+ String prefix = (String) getRequestAttributes().get("prefix");
+ String mask = (String) getRequestAttributes().get("mask");
+ String nextHop = (String) getRequestAttributes().get("nexthop");
+ String capability = (String) getRequestAttributes().get("capability");
+
+ String reply = "";
+
+ if (capability == null) {
+ // this is a prefix delete
+ Prefix p;
+ try {
+ p = new Prefix(prefix, Integer.valueOf(mask));
+ } catch (NumberFormatException e) {
+ reply = "[DELE: mask format is wrong]";
+ log.info(reply);
+ return reply + "\n";
+ } catch (UnknownHostException e1) {
+ reply = "[DELE: prefix format is wrong]";
+ log.info(reply);
+ return reply + "\n";
+ }
+
+ Rib r = new Rib(routerId, nextHop, p.getPrefixLength());
+
+ bgpRoute.newRibUpdate(new RibUpdate(Operation.DELETE, p, r));
+
+ /*
+ PtreeNode node = ptree.lookup(p.getAddress(), p.getPrefixLength());
+
+ //Remove the flows from the switches before the rib is lost
+ //Theory: we could get a delete for a prefix not in the Ptree.
+ //This would result in a null node being returned. We could get a delete for
+ //a node that's not actually there, but is a aggregate node. This would result
+ //in a non-null node with a null rib. Only a non-null node with a non-null
+ //rib is an actual prefix in the Ptree.
+ if (node != null && node.rib != null){
+ bgpRoute.prefixDeleted(node);
+ }
+
+
+
+ if (node != null && node.rib != null) {
+ if (r.equals(node.rib)) {
+ node.rib = null;
+ ptree.delReference(node);
+ }
+ }
+ */
+
+ reply =reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "]";
+ }
+ else {
+ // clear the local rib: Ptree
+ bgpRoute.clearPtree();
+ reply = "[DELE-capability: " + capability + "; The local Rib is cleared!]\n";
+
+ // to store the number in the top node of the Ptree
+ }
+
+ log.info(reply);
+ return reply + "\n";
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/bgproute/BgpRouteResourceSynch.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResourceSynch.java
similarity index 92%
rename from src/main/java/net/floodlightcontroller/bgproute/BgpRouteResourceSynch.java
rename to src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResourceSynch.java
index d0c337a..543827d 100644
--- a/src/main/java/net/floodlightcontroller/bgproute/BgpRouteResourceSynch.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResourceSynch.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.bgproute;
+package net.onrc.onos.ofcontroller.bgproute;
import org.restlet.resource.Post;
@@ -6,7 +6,6 @@
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import net.floodlightcontroller.restclient.RestClient;
public class BgpRouteResourceSynch extends ServerResource {
@@ -29,7 +28,7 @@
String BGPdRestIp = bgpRoute.getBGPdRestIp();
- //BGPdRestIp includes port number, such as 1.1.1.1:8080
+ //bgpdRestIp includes port number, such as 1.1.1.1:8080
RestClient.post("http://"+BGPdRestIp+"/wm/bgp/"+router_id+"/"+prefix+"/"+mask+"/"+nexthop);
}catch(Exception e)
{e.printStackTrace();}
diff --git a/src/main/java/net/floodlightcontroller/bgproute/BgpRouteWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteWebRoutable.java
similarity index 94%
rename from src/main/java/net/floodlightcontroller/bgproute/BgpRouteWebRoutable.java
rename to src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteWebRoutable.java
index a18c550..669c385 100644
--- a/src/main/java/net/floodlightcontroller/bgproute/BgpRouteWebRoutable.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteWebRoutable.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.bgproute;
+package net.onrc.onos.ofcontroller.bgproute;
import org.restlet.Context;
import org.restlet.Restlet;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java
new file mode 100644
index 0000000..c3c8cbb
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java
@@ -0,0 +1,75 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.openflow.util.HexString;
+
+public class Configuration {
+ private long bgpdAttachmentDpid;
+ private short bgpdAttachmentPort;
+ private List<String> switches;
+ private List<Interface> interfaces;
+ private List<BgpPeer> peers;
+ //private Map<String, GatewayRouter> gateways;
+
+ public Configuration() {
+ // TODO Auto-generated constructor stub
+ }
+
+ public long getBgpdAttachmentDpid() {
+ return bgpdAttachmentDpid;
+ }
+
+ @JsonProperty("bgpdAttachmentDpid")
+ public void setBgpdAttachmentDpid(String bgpdAttachmentDpid) {
+ this.bgpdAttachmentDpid = HexString.toLong(bgpdAttachmentDpid);
+ }
+
+ public short getBgpdAttachmentPort() {
+ return bgpdAttachmentPort;
+ }
+
+ @JsonProperty("bgpdAttachmentPort")
+ public void setBgpdAttachmentPort(short bgpdAttachmentPort) {
+ this.bgpdAttachmentPort = bgpdAttachmentPort;
+ }
+
+ public List<String> getSwitches() {
+ return switches;
+ }
+
+ @JsonProperty("switches")
+ public void setSwitches(List<String> switches) {
+ this.switches = switches;
+ }
+
+ public List<Interface> getInterfaces() {
+ return interfaces;
+ }
+
+ @JsonProperty("interfaces")
+ public void setInterfaces(List<Interface> interfaces) {
+ this.interfaces = interfaces;
+ }
+
+ public List<BgpPeer> getPeers() {
+ return peers;
+ }
+
+ @JsonProperty("bgpPeers")
+ public void setPeers(List<BgpPeer> peers) {
+ this.peers = peers;
+ }
+
+ /*
+ public Map<String, GatewayRouter> getGateways() {
+ return gateways;
+ }
+
+ @JsonProperty("gateways")
+ public void setGateways(Map<String, GatewayRouter> gateways) {
+ this.gateways = gateways;
+ }*/
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/GatewayRouter.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/GatewayRouter.java
new file mode 100644
index 0000000..e893acf
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/GatewayRouter.java
@@ -0,0 +1,72 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.IPv4;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.openflow.util.HexString;
+
+public class GatewayRouter {
+ private SwitchPort attachmentPoint = null;
+ private long dpid;
+ private short port;
+ private MACAddress routerMac;
+ private IPv4 routerIp;
+ private IPv4 myIpAddress;
+
+
+ public SwitchPort getAttachmentPoint() {
+ if (attachmentPoint == null){
+ attachmentPoint = new SwitchPort(new Dpid(dpid), new Port(port));
+ }
+ return attachmentPoint;
+ }
+
+ public long getDpid() {
+ return dpid;
+ }
+
+ @JsonProperty("attachmentDpid")
+ public void setDpid(String dpid) {
+ this.dpid = HexString.toLong(dpid);
+ }
+
+ public short getPort() {
+ return port;
+ }
+
+ @JsonProperty("attachmentPort")
+ public void setPort(short port) {
+ this.port = port;
+ }
+
+ public MACAddress getRouterMac() {
+ return routerMac;
+ }
+
+ @JsonProperty("macAddress")
+ public void setRouterMac(String routerMac) {
+ this.routerMac = MACAddress.valueOf(routerMac);;
+ }
+
+ public IPv4 getRouterIp() {
+ return routerIp;
+ }
+
+ @JsonProperty("ipAddress")
+ public void setRouterIp(String routerIp) {
+ this.routerIp = new IPv4(routerIp);
+ }
+
+ public IPv4 getMyIpAddress() {
+ return myIpAddress;
+ }
+
+ @JsonProperty("myIpAddress")
+ public void setMyIpAddress(String myIpAddress) {
+ this.myIpAddress = new IPv4(myIpAddress);
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/IBgpRouteService.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/IBgpRouteService.java
new file mode 100644
index 0000000..3dbc940
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/IBgpRouteService.java
@@ -0,0 +1,26 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+public interface IBgpRouteService extends IFloodlightService {
+
+ public Rib lookupRib(byte[] dest);
+
+ public Ptree getPtree();
+
+ public String getBGPdRestIp();
+
+ public String getRouterId();
+
+ public void clearPtree();
+
+ /**
+ * Pass a RIB update to the {@link IBgpRouteService}
+ * @param update
+ */
+ public void newRibUpdate(RibUpdate update);
+
+ //TODO This functionality should be provided by some sort of Ptree listener framework
+ public void prefixAdded(PtreeNode node);
+ public void prefixDeleted(PtreeNode node);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java
new file mode 100644
index 0000000..088c18e
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java
@@ -0,0 +1,73 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.net.InetAddress;
+
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.openflow.util.HexString;
+
+import com.google.common.net.InetAddresses;
+
+public class Interface {
+ private String name;
+ private SwitchPort switchPort = null;
+ private long dpid;
+ private short port;
+ private InetAddress ipAddress;
+ private int prefixLength;
+
+ public String getName() {
+ return name;
+ }
+
+ @JsonProperty("name")
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public synchronized SwitchPort getSwitchPort() {
+ if (switchPort == null){
+ switchPort = new SwitchPort(new Dpid(dpid), new Port(port));
+ }
+ return switchPort;
+ }
+
+ public long getDpid() {
+ return dpid;
+ }
+
+ @JsonProperty("dpid")
+ public void setDpid(String dpid) {
+ this.dpid = HexString.toLong(dpid);
+ }
+
+ public short getPort() {
+ return port;
+ }
+
+ @JsonProperty("port")
+ public void setPort(short port) {
+ this.port = port;
+ }
+
+ public InetAddress getIpAddress() {
+ return ipAddress;
+ }
+
+ @JsonProperty("ipAddress")
+ public void setIpAddress(String ipAddress) {
+ this.ipAddress = InetAddresses.forString(ipAddress);
+ }
+
+ public int getPrefixLength() {
+ return prefixLength;
+ }
+
+ @JsonProperty("prefixLength")
+ public void setPrefixLength(int prefixLength) {
+ this.prefixLength = prefixLength;
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java
new file mode 100644
index 0000000..4d7c53a
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java
@@ -0,0 +1,43 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class Prefix {
+ private int prefixLength;
+ private InetAddress address;
+
+ public Prefix(byte[] addr, int prefixLength) throws UnknownHostException {
+ //try {
+ address = InetAddress.getByAddress(addr);
+ //} catch (UnknownHostException e) {
+ // System.out.println("InetAddress exception");
+ // return;
+ //}
+ this.prefixLength = prefixLength;
+ //System.out.println(address.toString() + "/" + prefixLength);
+ }
+
+ public Prefix(String str, int prefixLength) throws UnknownHostException {
+ //try {
+ address = InetAddress.getByName(str);
+ //} catch (UnknownHostException e) {
+ // System.out.println("InetAddress exception");
+ // return;
+ //}
+ this.prefixLength = prefixLength;
+ }
+
+ public int getPrefixLength() {
+ return prefixLength;
+ }
+
+ public byte[] getAddress() {
+ return address.getAddress();
+ }
+
+ @Override
+ public String toString() {
+ return address.getHostAddress() + "/" + prefixLength;
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/bgproute/Ptree.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Ptree.java
similarity index 80%
rename from src/main/java/net/floodlightcontroller/bgproute/Ptree.java
rename to src/main/java/net/onrc/onos/ofcontroller/bgproute/Ptree.java
index dcb6e83..041061c 100644
--- a/src/main/java/net/floodlightcontroller/bgproute/Ptree.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Ptree.java
@@ -1,24 +1,33 @@
-package net.floodlightcontroller.bgproute;
+package net.onrc.onos.ofcontroller.bgproute;
+/*
+ * TODO This Ptree needs to be refactored if we're going to use it permenantly.
+ *
+ * The biggest problem is it leaks PTreeNode references - these need to stay within
+ * the Ptree as they contain data fundamental to the structure of the tree.
+ * You should put RIB entries in and get RIB entries out.
+ * Also we need to get rid of the referencing scheme to determine when to delete nodes.
+ * Deletes should be explicit, and there's no need to keep track of references if
+ * we don't leak them out the the Ptree.
+ */
public class Ptree {
- int maxKeyBits;
- int maxKeyOctets;
- int refCount;
- PtreeNode top;
- byte maskBits[] = { (byte)0x00, (byte)0x80, (byte)0xc0, (byte)0xe0, (byte)0xf0, (byte)0xf8, (byte)0xfc, (byte)0xfe, (byte)0xff };
+ private int maxKeyBits;
+ private int maxKeyOctets;
+ //private int refCount;
+ private PtreeNode top;
+ private byte maskBits[] = { (byte)0x00, (byte)0x80, (byte)0xc0, (byte)0xe0, (byte)0xf0, (byte)0xf8, (byte)0xfc, (byte)0xfe, (byte)0xff };
- // Constructor.
- Ptree(int max_key_bits) {
+ public Ptree(int max_key_bits) {
maxKeyBits = max_key_bits;
maxKeyOctets = bit_to_octet(max_key_bits);
- refCount = 0;
+ //refCount = 0;
}
- public PtreeNode acquire(byte [] key) {
+ public synchronized PtreeNode acquire(byte [] key) {
return acquire(key, maxKeyBits);
}
- public PtreeNode acquire(byte [] key, int key_bits) {
+ public synchronized PtreeNode acquire(byte [] key, int key_bits) {
if (key_bits > maxKeyBits) {
return null;
}
@@ -76,7 +85,7 @@
return addReference(add);
}
- public PtreeNode lookup(byte [] key, int key_bits) {
+ public synchronized PtreeNode lookup(byte [] key, int key_bits) {
if (key_bits > maxKeyBits) {
return null;
}
@@ -99,7 +108,7 @@
return null;
}
- public PtreeNode match(byte [] key, int key_bits) {
+ public synchronized PtreeNode match(byte [] key, int key_bits) {
if (key_bits > maxKeyBits) {
return null;
}
@@ -127,14 +136,14 @@
return null;
}
- public PtreeNode begin() {
+ public synchronized PtreeNode begin() {
if (top == null) {
return null;
}
return addReference(top);
}
- public PtreeNode next(PtreeNode node) {
+ public synchronized PtreeNode next(PtreeNode node) {
PtreeNode next;
if (node.left != null) {
@@ -175,7 +184,7 @@
return node;
}
- public void delReference(PtreeNode node) {
+ public synchronized void delReference(PtreeNode node) {
if (node.refCount > 0) {
node.refCount--;
}
@@ -278,10 +287,6 @@
return add;
}
- //add by linpp
- private void clear() {
-
- }
private void node_remove(PtreeNode node) {
PtreeNode child;
diff --git a/src/main/java/net/floodlightcontroller/bgproute/PtreeNode.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/PtreeNode.java
similarity index 95%
rename from src/main/java/net/floodlightcontroller/bgproute/PtreeNode.java
rename to src/main/java/net/onrc/onos/ofcontroller/bgproute/PtreeNode.java
index 4d2c265..a4d6996 100644
--- a/src/main/java/net/floodlightcontroller/bgproute/PtreeNode.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/PtreeNode.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.bgproute;
+package net.onrc.onos.ofcontroller.bgproute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java
new file mode 100644
index 0000000..f6f1a03
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java
@@ -0,0 +1,104 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class RestClient {
+ protected static Logger log = LoggerFactory.getLogger(RestClient.class);
+
+ public static String get(String str) {
+ StringBuilder response = new StringBuilder();
+
+ try {
+
+ URL url = new URL(str);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setConnectTimeout(2 * 1000); //2 seconds
+ conn.setRequestMethod("GET");
+ conn.setRequestProperty("Accept", "application/json");
+
+ if (conn.getResponseCode() != 200) {
+ throw new RuntimeException("Failed : HTTP error code : "
+ + conn.getResponseCode());
+ }
+
+ if (!conn.getContentType().equals("application/json")){
+ log.warn("The content received from {} is not json", str);
+ }
+
+ BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
+ String line;
+ while ((line = br.readLine()) != null) {
+ response.append(line);
+ }
+
+ br.close();
+ conn.disconnect();
+
+ } catch (MalformedURLException e) {
+ log.error("Malformed URL for GET request", e);
+ } catch (ConnectTimeoutException e) {
+ log.warn("Couldn't connect remote REST server");
+ } catch (IOException e) {
+ log.warn("Couldn't connect remote REST server");
+ }
+
+ return response.toString();
+ }
+
+ public static void post (String str) {
+
+ try {
+ URL url = new URL(str);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setDoOutput(true);
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-Type", "application/json");
+
+ if (conn.getResponseCode() != 200) {
+ throw new RuntimeException("Failed : HTTP error code : "
+ + conn.getResponseCode());
+ }
+
+ conn.disconnect();
+
+ } catch (MalformedURLException e) {
+ log.error("Malformed URL for GET request", e);
+ } catch (IOException e) {
+ log.warn("Couldn't connect remote REST server");
+ }
+ }
+
+
+ public static void delete (String str) {
+
+ try {
+ URL url = new URL(str);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setRequestMethod("DELETE");
+ conn.setRequestProperty("Accept", "application/json");
+
+
+ if (conn.getResponseCode() != 200) {
+ throw new RuntimeException("Failed : HTTP error code : "
+ + conn.getResponseCode());
+ }
+
+ conn.disconnect();
+
+ } catch (MalformedURLException e) {
+ log.error("Malformed URL for GET request", e);
+ } catch (IOException e) {
+ log.warn("Couldn't connect remote REST server");
+ }
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/bgproute/Rib.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Rib.java
similarity index 95%
rename from src/main/java/net/floodlightcontroller/bgproute/Rib.java
rename to src/main/java/net/onrc/onos/ofcontroller/bgproute/Rib.java
index 574e820..dc5f71d 100644
--- a/src/main/java/net/floodlightcontroller/bgproute/Rib.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Rib.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.bgproute;
+package net.onrc.onos.ofcontroller.bgproute;
import java.net.InetAddress;
import java.net.UnknownHostException;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibUpdate.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibUpdate.java
new file mode 100644
index 0000000..c7272bd
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibUpdate.java
@@ -0,0 +1,27 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+public class RibUpdate {
+ public enum Operation {UPDATE, DELETE};
+
+ private Operation operation;
+ private Prefix prefix;
+ private Rib ribEntry;
+
+ public RibUpdate(Operation operation, Prefix prefix, Rib ribEntry) {
+ this.operation = operation;
+ this.prefix = prefix;
+ this.ribEntry = ribEntry;
+ }
+
+ public Operation getOperation() {
+ return operation;
+ }
+
+ public Prefix getPrefix() {
+ return prefix;
+ }
+
+ public Rib getRibEntry() {
+ return ribEntry;
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
similarity index 70%
rename from src/main/java/net/floodlightcontroller/devicemanager/IDeviceStorage.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
index f41e32c..7310d8c 100644
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
@@ -1,7 +1,7 @@
-package net.floodlightcontroller.devicemanager;
+package net.onrc.onos.ofcontroller.core;
-import net.floodlightcontroller.core.INetMapStorage;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.floodlightcontroller.devicemanager.IDevice;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
public interface IDeviceStorage extends INetMapStorage {
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
similarity index 86%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/ILinkStorage.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
index eb2fac9..b56cfef 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
@@ -1,9 +1,9 @@
-package net.floodlightcontroller.linkdiscovery;
+package net.onrc.onos.ofcontroller.core;
import java.util.List;
-import net.floodlightcontroller.core.INetMapStorage;
import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
public interface ILinkStorage extends INetMapStorage {
@@ -17,7 +17,7 @@
/*
* Add Linkinfo
*/
- public void addOrUpdateLink (Link link, LinkInfo linkinfo, DM_OPERATION op);
+ public void updateLink (Link link, LinkInfo linkinfo, DM_OPERATION op);
/*
* Delete a single link
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapService.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapService.java
new file mode 100644
index 0000000..8392a32
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapService.java
@@ -0,0 +1,5 @@
+package net.onrc.onos.ofcontroller.core;
+
+public interface INetMapService {
+
+}
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
similarity index 90%
rename from src/main/java/net/floodlightcontroller/core/INetMapStorage.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
index 67c6631..b052540 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
@@ -1,7 +1,7 @@
/**
*
*/
-package net.floodlightcontroller.core;
+package net.onrc.onos.ofcontroller.core;
/**
* @author pankaj
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
similarity index 68%
rename from src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
index 4a03327..9a96638 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -1,6 +1,6 @@
-package net.floodlightcontroller.core;
+package net.onrc.onos.ofcontroller.core;
-import net.floodlightcontroller.flowcache.web.DatapathSummarySerializer;
+import net.onrc.onos.ofcontroller.flowmanager.web.DatapathSummarySerializer;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -11,8 +11,15 @@
import com.tinkerpop.frames.Incidence;
import com.tinkerpop.frames.Property;
import com.tinkerpop.frames.annotations.gremlin.GremlinGroovy;
+import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
import com.tinkerpop.frames.VertexFrame;
+/*
+ * This is the interfaces to make the objects for Cassandra DB.
+ * They are interfaces, but it is also implementation,
+ * so this handles various control to the objects.
+ * Please take a look at tinkerpop/frames annotation doc to understand more.
+ */
public interface INetMapTopologyObjects {
public interface IBaseObject extends VertexFrame {
@@ -46,9 +53,9 @@
public Iterable<IPortObject> getPorts();
// Requires Frames 2.3.0
-// @JsonIgnore
-// @GremlinGroovy("_().out('on').has('number',port_num)")
-// public IPortObject getPort(@GremlinParam("port_num") final short port_num);
+ @JsonIgnore
+ @GremlinGroovy("it.out('on').has('number',port_num)")
+ public IPortObject getPort(@GremlinParam("port_num") final short port_num);
@Adjacency(label="on")
public void addPort(final IPortObject port);
@@ -57,12 +64,13 @@
public void removePort(final IPortObject port);
@JsonIgnore
- @GremlinGroovy("_().out('on').out('host')")
+ @GremlinGroovy("it.out('on').out('host')")
public Iterable<IDeviceObject> getDevices();
@JsonIgnore
- @Incidence(label="switch",direction = Direction.IN)
+ @Adjacency(label="switch",direction = Direction.IN)
public Iterable<IFlowEntry> getFlowEntries();
+
}
public interface IPortObject extends IBaseObject{
@@ -71,6 +79,14 @@
@Property("number")
public Short getNumber();
+ @JsonIgnore
+ @Property("port_id")
+ public void setPortId(String id);
+
+ @JsonIgnore
+ @Property("port_id")
+ public String getPortId();
+
@Property("number")
public void setNumber(Short n);
@@ -89,7 +105,8 @@
public void setPortState(Integer s);
@JsonIgnore
- @Incidence(label="on",direction = Direction.IN)
+// @GremlinGroovy("it.in('on')")
+ @Adjacency(label="on",direction = Direction.IN)
public ISwitchObject getSwitch();
@JsonProperty("devices")
@@ -103,11 +120,11 @@
public void removeDevice(final IDeviceObject device);
@JsonIgnore
- @Incidence(label="inport",direction = Direction.IN)
+ @Adjacency(label="inport",direction = Direction.IN)
public Iterable<IFlowEntry> getInFlowEntries();
@JsonIgnore
- @Incidence(label="outport",direction = Direction.IN)
+ @Adjacency(label="outport",direction = Direction.IN)
public Iterable<IFlowEntry> getOutFlowEntries();
@JsonIgnore
@@ -136,23 +153,23 @@
@JsonProperty("ipv4")
@Property("nw_addr")
public String getIPAddress();
- @Property("dl_addr")
+ @Property("nw_addr")
public void setIPAddress(String ipaddr);
@JsonIgnore
- @Incidence(label="host",direction = Direction.IN)
+ @Adjacency(label="host",direction = Direction.IN)
public Iterable<IPortObject> getAttachedPorts();
@JsonIgnore
- @Incidence(label="host",direction=Direction.IN)
+ @Adjacency(label="host",direction=Direction.IN)
public void setHostPort(final IPortObject port);
@JsonIgnore
- @Incidence(label="host",direction=Direction.IN)
+ @Adjacency(label="host",direction=Direction.IN)
public void removeHostPort(final IPortObject port);
@JsonIgnore
- @GremlinGroovy("_().in('host').in('on')")
+ @GremlinGroovy("it.in('host').in('on')")
public Iterable<ISwitchObject> getSwitch();
/* @JsonProperty("dpid")
@@ -183,6 +200,13 @@
@Property("installer_id")
public void setInstallerId(String installerId);
+ @JsonProperty("flowPathFlags")
+ @Property("flow_path_flags")
+ public Long getFlowPathFlags();
+
+ @Property("flow_path_flags")
+ public void setFlowPathFlags(Long flowPathFlags);
+
@JsonProperty("srcDpid")
@Property("src_switch")
public String getSrcSwitch();
@@ -229,13 +253,9 @@
@Adjacency(label="flow", direction=Direction.IN)
public void removeFlowEntry(final IFlowEntry flowEntry);
- @JsonIgnore
- @Property("matchEthernetFrameType")
- public Short getMatchEthernetFrameType();
-
- @Property("matchEthernetFrameType")
- public void setMatchEthernetFrameType(Short matchEthernetFrameType);
-
+ //
+ // Matching fields
+ //
@JsonIgnore
@Property("matchSrcMac")
public String getMatchSrcMac();
@@ -251,6 +271,27 @@
public void setMatchDstMac(String matchDstMac);
@JsonIgnore
+ @Property("matchEthernetFrameType")
+ public Short getMatchEthernetFrameType();
+
+ @Property("matchEthernetFrameType")
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType);
+
+ @JsonIgnore
+ @Property("matchVlanId")
+ public Short getMatchVlanId();
+
+ @Property("matchVlanId")
+ public void setMatchVlanId(Short matchVlanId);
+
+ @JsonIgnore
+ @Property("matchVlanPriority")
+ public Byte getMatchVlanPriority();
+
+ @Property("matchVlanPriority")
+ public void setMatchVlanPriority(Byte matchVlanPriority);
+
+ @JsonIgnore
@Property("matchSrcIPv4Net")
public String getMatchSrcIPv4Net();
@@ -263,9 +304,49 @@
@Property("matchDstIPv4Net")
public void setMatchDstIPv4Net(String matchDstIPv4Net);
-
+
@JsonIgnore
- @GremlinGroovy("_().in('flow').out('switch')")
+ @Property("matchIpProto")
+ public Byte getMatchIpProto();
+
+ @Property("matchIpProto")
+ public void setMatchIpProto(Byte matchIpProto);
+
+ @JsonIgnore
+ @Property("matchIpToS")
+ public Byte getMatchIpToS();
+
+ @Property("matchIpToS")
+ public void setMatchIpToS(Byte matchIpToS);
+
+ @JsonIgnore
+ @Property("matchSrcTcpUdpPort")
+ public Short getMatchSrcTcpUdpPort();
+
+ @Property("matchSrcTcpUdpPort")
+ public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort);
+
+ @JsonIgnore
+ @Property("matchDstTcpUdpPort")
+ public Short getMatchDstTcpUdpPort();
+
+ @Property("matchDstTcpUdpPort")
+ public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort);
+
+ //
+ // Action-related fields
+ //
+ @Property("actions")
+ public String getActions();
+
+ @Property("actions")
+ public void setActions(String actionsStr);
+
+ //
+ // Other fields
+ //
+ @JsonIgnore
+ @GremlinGroovy("it.in('flow').out('switch')")
public Iterable<ISwitchObject> getSwitches();
@JsonIgnore
@@ -317,18 +398,15 @@
@Property("error_state_code")
public void setErrorStateCode(String errorStateCode);
+ //
+ // Matching fields
+ //
@Property("matchInPort")
public Short getMatchInPort();
@Property("matchInPort")
public void setMatchInPort(Short matchInPort);
- @Property("matchEthernetFrameType")
- public Short getMatchEthernetFrameType();
-
- @Property("matchEthernetFrameType")
- public void setMatchEthernetFrameType(Short matchEthernetFrameType);
-
@Property("matchSrcMac")
public String getMatchSrcMac();
@@ -341,6 +419,24 @@
@Property("matchDstMac")
public void setMatchDstMac(String matchDstMac);
+ @Property("matchEthernetFrameType")
+ public Short getMatchEthernetFrameType();
+
+ @Property("matchEthernetFrameType")
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType);
+
+ @Property("matchVlanId")
+ public Short getMatchVlanId();
+
+ @Property("matchVlanId")
+ public void setMatchVlanId(Short matchVlanId);
+
+ @Property("matchVlanPriority")
+ public Byte getMatchVlanPriority();
+
+ @Property("matchVlanPriority")
+ public void setMatchVlanPriority(Byte matchVlanPriority);
+
@Property("matchSrcIPv4Net")
public String getMatchSrcIPv4Net();
@@ -353,12 +449,48 @@
@Property("matchDstIPv4Net")
public void setMatchDstIPv4Net(String matchDstIPv4Net);
- @Property("actionOutput")
- public Short getActionOutput();
+ @Property("matchIpProto")
+ public Byte getMatchIpProto();
- @Property("actionOutput")
- public void setActionOutput(Short actionOutput);
+ @Property("matchIpProto")
+ public void setMatchIpProto(Byte matchIpProto);
+ @Property("matchIpToS")
+ public Byte getMatchIpToS();
+
+ @Property("matchIpToS")
+ public void setMatchIpToS(Byte matchIpToS);
+
+ @Property("matchSrcTcpUdpPort")
+ public Short getMatchSrcTcpUdpPort();
+
+ @Property("matchSrcTcpUdpPort")
+ public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort);
+
+ @Property("matchDstTcpUdpPort")
+ public Short getMatchDstTcpUdpPort();
+
+ @Property("matchDstTcpUdpPort")
+ public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort);
+
+ //
+ // Action-related fields
+ //
+ @Property("actionOutputPort")
+ public Short getActionOutputPort();
+
+ @Property("actionOutputPort")
+ public void setActionOutputPort(Short actionOutputPort);
+
+ @Property("actions")
+ public String getActions();
+
+ @Property("actions")
+ public void setActions(String actionsStr);
+
+ //
+ // Other fields
+ //
@Adjacency(label="flow")
public IFlowPath getFlow();
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyService.java
similarity index 75%
rename from src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyService.java
index ecf217e..1992624 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyService.java
@@ -1,15 +1,16 @@
-package net.floodlightcontroller.core;
+package net.onrc.onos.ofcontroller.core;
import java.util.List;
+import java.util.Map;
import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.topology.NodePortTuple;
-import net.floodlightcontroller.util.DataPath;
-import net.floodlightcontroller.util.SwitchPort;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
public interface INetMapTopologyService extends INetMapService {
@@ -47,7 +48,7 @@
/**
* Fetch the Switch and Ports info from the Titan Graph
- * and store it locally for fast access during the shortest path
+ * and return it for fast access during the shortest path
* computation.
*
* After fetching the state, method @ref getTopoShortestPath()
@@ -63,14 +64,17 @@
* method @ref dropShortestPathTopo() should be used to release
* the internal state that is not needed anymore:
*
- * prepareShortestPathTopo();
+ * Map<Long, ?> shortestPathTopo;
+ * shortestPathTopo = prepareShortestPathTopo();
* for (int i = 0; i < 10000; i++) {
- * dataPath = getTopoShortestPath(...);
+ * dataPath = getTopoShortestPath(shortestPathTopo, ...);
* ...
* }
- * dropShortestPathTopo();
+ * dropShortestPathTopo(shortestPathTopo);
+ *
+ * @return the Shortest Path info handler stored in a map.
*/
- void prepareShortestPathTopo();
+ Map<Long, ?> prepareShortestPathTopo();
/**
* Release the state that was populated by
@@ -78,8 +82,10 @@
*
* See the documentation for method @ref prepareShortestPathTopo()
* for additional information and usage.
+ *
+ * @shortestPathTopo the Shortest Path info handler to release.
*/
- void dropShortestPathTopo();
+ void dropShortestPathTopo(Map<Long, ?> shortestPathTopo);
/**
* Get the shortest path from a source to a destination by
@@ -89,12 +95,15 @@
* See the documentation for method @ref prepareShortestPathTopo()
* for additional information and usage.
*
+ * @paran shortestPathTopoHandler the Shortest Path info handler
+ * to use.
* @param src the source in the shortest path computation.
* @param dest the destination in the shortest path computation.
* @return the data path with the computed shortest path if
* found, otherwise null.
*/
- DataPath getTopoShortestPath(SwitchPort src, SwitchPort dest);
+ DataPath getTopoShortestPath(Map<Long, ?> shortestPathTopo,
+ SwitchPort src, SwitchPort dest);
/**
* Test whether a route exists from a source to a destination.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/IOFSwitchPortListener.java b/src/main/java/net/onrc/onos/ofcontroller/core/IOFSwitchPortListener.java
new file mode 100644
index 0000000..5deae69
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IOFSwitchPortListener.java
@@ -0,0 +1,26 @@
+/**
+ *
+ */
+package net.onrc.onos.ofcontroller.core;
+
+import org.openflow.protocol.OFPhysicalPort;
+
+import net.floodlightcontroller.core.IOFSwitchListener;
+
+/**
+ * @author y-higuchi
+ *
+ */
+public interface IOFSwitchPortListener extends IOFSwitchListener {
+
+ /**
+ * Fired when ports on a switch area added
+ */
+ public void switchPortAdded(Long switchId, OFPhysicalPort port);
+
+ /**
+ * Fired when ports on a switch area removed
+ */
+ public void switchPortRemoved(Long switchId, OFPhysicalPort port);
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/IOnosRemoteSwitch.java b/src/main/java/net/onrc/onos/ofcontroller/core/IOnosRemoteSwitch.java
new file mode 100644
index 0000000..c9b0e2f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IOnosRemoteSwitch.java
@@ -0,0 +1,20 @@
+/**
+ *
+ */
+package net.onrc.onos.ofcontroller.core;
+
+import net.floodlightcontroller.core.IOFSwitch;
+
+/**
+ * @author y-higuchi
+ *
+ */
+public interface IOnosRemoteSwitch extends IOFSwitch {
+
+ /**
+ * Setup an unconnected switch with the info required.
+ * @param dpid of the switch
+ */
+ public void setupRemoteSwitch(Long dpid);
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
new file mode 100644
index 0000000..a4dd528
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
@@ -0,0 +1,47 @@
+package net.onrc.onos.ofcontroller.core;
+
+import java.util.Collection;
+
+
+import net.floodlightcontroller.core.IOFSwitch;
+
+import org.openflow.protocol.OFPhysicalPort;
+
+public interface ISwitchStorage extends INetMapStorage {
+
+ public enum SwitchState {
+ INACTIVE,
+ ACTIVE
+ }
+
+ /*
+ * Update the switch details
+ */
+ public void update(String dpid,SwitchState state, DM_OPERATION op);
+ /*
+ * Associate a port on switch
+ */
+ public void addPort(String dpid, OFPhysicalPort port);
+ /*
+ * Add a switch and all its associated ports
+ */
+ public void addSwitch(IOFSwitch sw);
+ /*
+ * Add a switch
+ */
+ public void addSwitch(String dpid);
+ /*
+ * Delete switch and associated ports
+ */
+ public void deleteSwitch(String dpid);
+ /*
+ * Delete a port on a switch by num
+ */
+ public void deletePort(String dpid, short port);
+ /*
+ * Initialize
+ */
+ public void init(String conf);
+
+
+}
diff --git a/src/main/java/net/floodlightcontroller/core/Main.java b/src/main/java/net/onrc/onos/ofcontroller/core/Main.java
similarity index 92%
rename from src/main/java/net/floodlightcontroller/core/Main.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/Main.java
index 91b317a..a80ac36 100644
--- a/src/main/java/net/floodlightcontroller/core/Main.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/Main.java
@@ -1,8 +1,9 @@
-package net.floodlightcontroller.core;
+package net.onrc.onos.ofcontroller.core;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
+import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.internal.CmdLineSettings;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.FloodlightModuleLoader;
@@ -10,7 +11,7 @@
import net.floodlightcontroller.restserver.IRestApiService;
/**
- * Host for the Floodlight main method
+ * Host for the ONOS main method
* @author alexreimers
*/
public class Main {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
new file mode 100644
index 0000000..386c1bd
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
@@ -0,0 +1,264 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.thinkaurelius.titan.core.TitanException;
+import net.floodlightcontroller.devicemanager.IDevice;
+import net.floodlightcontroller.devicemanager.SwitchPort;
+import net.floodlightcontroller.packet.IPv4;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+
+/**
+ * This is the class for storing the information of devices into CassandraDB
+ * @author Pankaj
+ */
+public class DeviceStorageImpl implements IDeviceStorage {
+
+ private GraphDBOperation ope;
+ protected static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ /***
+ * Initialize function. Before you use this class, please call this method
+ * @param conf configuration file for Cassandra DB
+ */
+ @Override
+ public void init(String conf) {
+ try{
+ ope = new GraphDBOperation(conf);
+ } catch(Exception e) {
+ log.error(e.getMessage());
+ }
+ }
+
+ /***
+ * Finalize/close function. After you use this class, please call this method.
+ * It will close the DB connection.
+ */
+ @Override
+ public void close() {
+ ope.close();
+ }
+
+ /***
+ * Finalize/close function. After you use this class, please call this method.
+ * It will close the DB connection. This is for Java garbage collection.
+ */
+ @Override
+ public void finalize() {
+ close();
+ }
+
+ /***
+ * This function is for adding the device into the DB.
+ * @param device The device you want to add into the DB.
+ * @return IDeviceObject which was added in the DB.
+ */
+ @Override
+ public IDeviceObject addDevice(IDevice device) {
+ IDeviceObject obj = null;
+ try {
+ if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+ log.debug("Adding device {}: found existing device",device.getMACAddressString());
+ } else {
+ obj = ope.newDevice();
+ log.debug("Adding device {}: creating new device",device.getMACAddressString());
+ }
+ changeDeviceAttachments(device, obj);
+
+ String multiIntString = "";
+ for(Integer intValue : device.getIPv4Addresses()) {
+ if (multiIntString == null || multiIntString.isEmpty()){
+ multiIntString = IPv4.fromIPv4Address(intValue);
+ multiIntString = "[" + IPv4.fromIPv4Address(intValue);
+ }else{
+ multiIntString += "," + IPv4.fromIPv4Address(intValue);
+ }
+ }
+
+ if(multiIntString.toString() != null && !multiIntString.toString().isEmpty()){
+ obj.setIPAddress(multiIntString + "]");
+ }
+
+ obj.setMACAddress(device.getMACAddressString());
+ obj.setType("device");
+ obj.setState("ACTIVE");
+ ope.commit();
+
+ log.debug("Adding device {}",device.getMACAddressString());
+ } catch (Exception e) {
+ ope.rollback();
+ log.error(":addDevice mac:{} failed", device.getMACAddressString());
+ obj = null;
+ }
+ return obj;
+ }
+
+ /***
+ * This function is for updating the Device properties.
+ * @param device The device you want to add into the DB.
+ * @return IDeviceObject which was added in the DB.
+ */
+ @Override
+ public IDeviceObject updateDevice(IDevice device) {
+ return addDevice(device);
+ }
+
+ /***
+ * This function is for removing the Device from the DB.
+ * @param device The device you want to delete from the DB.
+ */
+ @Override
+ public void removeDevice(IDevice device) {
+ IDeviceObject dev;
+ try {
+ if ((dev = ope.searchDevice(device.getMACAddressString())) != null) {
+ ope.removeDevice(dev);
+ ope.commit();
+ log.error("DeviceStorage:removeDevice mac:{} done", device.getMACAddressString());
+ }
+ } catch (Exception e) {
+ ope.rollback();
+ log.error("DeviceStorage:removeDevice mac:{} failed", device.getMACAddressString());
+ }
+ }
+
+ /***
+ * This function is for getting the Device from the DB by Mac address of the device.
+ * @param mac The device mac address you want to get from the DB.
+ * @return IDeviceObject you want to get.
+ */
+ @Override
+ public IDeviceObject getDeviceByMac(String mac) {
+ return ope.searchDevice(mac);
+ }
+
+ /***
+ * This function is for getting the Device from the DB by IP address of the device.
+ * @param ip The device ip address you want to get from the DB.
+ * @return IDeviceObject you want to get.
+ */
+ @Override
+ public IDeviceObject getDeviceByIP(String ip) {
+ try
+ {
+ for(IDeviceObject dev : ope.getDevices()){
+ String ips;
+ if((ips = dev.getIPAddress()) != null){
+ String nw_addr_wob = ips.replace("[", "").replace("]", "");
+ ArrayList<String> iplists = Lists.newArrayList(nw_addr_wob.split(","));
+ if(iplists.contains(ip)){
+ return dev;
+ }
+ }
+ }
+ return null;
+ }
+ catch (Exception e)
+ {
+ log.error("DeviceStorage:getDeviceByIP:{} failed");
+ return null;
+ }
+ }
+
+ /***
+ * This function is for changing the Device attachment point.
+ * @param device The device you want change the attachment point
+ */
+ @Override
+ public void changeDeviceAttachments(IDevice device) {
+ IDeviceObject obj = null;
+ try {
+ if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+ log.debug("Changing device ports {}: found existing device",device.getMACAddressString());
+ changeDeviceAttachments(device, obj);
+ ope.commit();
+ } else {
+ log.debug("failed to search device...now adding {}",device.getMACAddressString());
+ addDevice(device);
+ }
+ } catch (Exception e) {
+ ope.rollback();
+ log.error(":addDevice mac:{} failed", device.getMACAddressString());
+ }
+ }
+
+ /***
+ * This function is for changing the Device attachment point.
+ * @param device The new device you want change the attachment point
+ * @param obj The old device IDeviceObject that is going to change the attachment point.
+ */
+ public void changeDeviceAttachments(IDevice device, IDeviceObject obj) {
+ SwitchPort[] attachmentPoints = device.getAttachmentPoints();
+ List<IPortObject> attachedPorts = Lists.newArrayList(obj.getAttachedPorts());
+
+ for (SwitchPort ap : attachmentPoints) {
+ //Check weather there is the port
+ IPortObject port = ope.searchPort( HexString.toHexString(ap.getSwitchDPID()),
+ (short) ap.getPort());
+ log.debug("New Switch Port is {},{}", HexString.toHexString(ap.getSwitchDPID()),(short) ap.getPort());
+
+ if(port != null){
+ if(attachedPorts.contains(port))
+ {
+ log.debug("This is the port you already attached {}: do nothing",device.getMACAddressString());
+ //This port will be remained, so remove from the removed port lists.
+ attachedPorts.remove(port);
+ } else {
+ log.debug("Adding device {}: attaching to port",device.getMACAddressString());
+ port.setDevice(obj);
+ }
+
+ log.debug("port number is {}", port.getNumber().toString());
+ log.debug("port desc is {}", port.getDesc());
+ }
+ }
+
+ for (IPortObject port: attachedPorts) {
+ log.debug("Detouching the device {}: detouching from port",device.getMACAddressString());
+ port.removeDevice(obj);
+ }
+ }
+
+ /***
+ * This function is for changing the Device IPv4 address.
+ * @param device The new device you want change the ipaddress
+ */
+ @Override
+ public void changeDeviceIPv4Address(IDevice device) {
+ IDeviceObject obj;
+ try {
+ if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+
+ String multiIntString = "";
+ for(Integer intValue : device.getIPv4Addresses()){
+ if (multiIntString == null || multiIntString.isEmpty()){
+ multiIntString = "[" + IPv4.fromIPv4Address(intValue);
+ } else {
+ multiIntString += "," + IPv4.fromIPv4Address(intValue);
+ }
+ }
+
+ if(multiIntString != null && !multiIntString.isEmpty()){
+ obj.setIPAddress(multiIntString + "]");
+ }
+
+ ope.commit();
+ } else {
+ log.error(":changeDeviceIPv4Address mac:{} failed", device.getMACAddressString());
+ }
+ } catch (TitanException e) {
+ ope.rollback();
+ log.error(":changeDeviceIPv4Address mac:{} failed due to exception {}", device.getMACAddressString(),e);
+ }
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
new file mode 100644
index 0000000..6e42771
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
@@ -0,0 +1,350 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.ILinkStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.thinkaurelius.titan.core.TitanException;
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+import com.tinkerpop.pipes.PipeFunction;
+import com.tinkerpop.pipes.transform.PathPipe;
+
+/**
+ * This is the class for storing the information of links into CassandraDB
+ */
+public class LinkStorageImpl implements ILinkStorage {
+
+ protected static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
+ protected GraphDBOperation dbop;
+
+ /**
+ * Update a record in the LinkStorage in a way provided by op.
+ * @param link Record of a link to be updated.
+ * @param op Operation to be done.
+ */
+ @Override
+ public void update(Link link, DM_OPERATION op) {
+ update(link, (LinkInfo)null, op);
+ }
+
+ /**
+ * Update multiple records in the LinkStorage in a way provided by op.
+ * @param links List of records to be updated.
+ * @param op Operation to be done.
+ */
+ @Override
+ public void update(List<Link> links, DM_OPERATION op) {
+ for (Link lt: links) {
+ update(lt, (LinkInfo)null, op);
+ }
+ }
+
+ /**
+ * Update a record of link with meta-information in the LinkStorage in a way provided by op.
+ * @param link Record of a link to update.
+ * @param linkinfo Meta-information of a link to be updated.
+ * @param op Operation to be done.
+ */
+ @Override
+ public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
+ switch (op) {
+ case UPDATE:
+ case CREATE:
+ case INSERT:
+ updateLink(link, linkinfo, op);
+ break;
+ case DELETE:
+ deleteLink(link);
+ break;
+ }
+ }
+
+ /**
+ * Perform INSERT/CREATE/UPDATE operation to update the LinkStorage.
+ * @param lt Record of a link to be updated.
+ * @param linkinfo Meta-information of a link to be updated.
+ * @param op Operation to be done. (only INSERT/CREATE/UPDATE is acceptable)
+ */
+ public void updateLink(Link lt, LinkInfo linkinfo, DM_OPERATION op) {
+ IPortObject vportSrc = null, vportDst = null;
+
+ log.trace("updateLink(): op {} {} {}", new Object[]{op, lt, linkinfo});
+
+ try {
+ // get source port vertex
+ String dpid = HexString.toHexString(lt.getSrc());
+ short port = lt.getSrcPort();
+ vportSrc = dbop.searchPort(dpid, port);
+
+ // get dest port vertex
+ dpid = HexString.toHexString(lt.getDst());
+ port = lt.getDstPort();
+ vportDst = dbop.searchPort(dpid, port);
+
+ if (vportSrc != null && vportDst != null) {
+ // check if the link exists
+
+ Iterable<IPortObject> currPorts = vportSrc.getLinkedPorts();
+ List<IPortObject> currLinks = new ArrayList<IPortObject>();
+ for (IPortObject V : currPorts) {
+ currLinks.add(V);
+ }
+
+ if (currLinks.contains(vportDst)) {
+ // TODO: update linkinfo
+ if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
+ log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
+ new Object[]{op, lt, vportSrc, vportDst});
+ }
+ } else {
+ vportSrc.setLinkPort(vportDst);
+
+ dbop.commit();
+ log.debug("updateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
+ }
+ } else {
+ log.error("updateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
+ dbop.rollback();
+ }
+ } catch (TitanException e) {
+ /*
+ * retry till we succeed?
+ */
+ e.printStackTrace();
+ log.error("updateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
+ }
+ }
+
+ /**
+ * Delete multiple records in LinkStorage.
+ * @param links List of records to be deleted.
+ */
+ @Override
+ public void deleteLinks(List<Link> links) {
+
+ for (Link lt : links) {
+ deleteLink(lt);
+ }
+ }
+
+ /**
+ * Delete a record in the LinkStorage.
+ * @param link Record to be deleted.
+ */
+ @Override
+ public void deleteLink(Link lt) {
+ IPortObject vportSrc = null, vportDst = null;
+ int count = 0;
+
+ log.debug("deleteLink(): {}", lt);
+
+ try {
+ // get source port vertex
+ String dpid = HexString.toHexString(lt.getSrc());
+ short port = lt.getSrcPort();
+ vportSrc = dbop.searchPort(dpid, port);
+
+ // get dst port vertex
+ dpid = HexString.toHexString(lt.getDst());
+ port = lt.getDstPort();
+ vportDst = dbop.searchPort(dpid, port);
+ // FIXME: This needs to remove all edges
+
+ if (vportSrc != null && vportDst != null) {
+
+ /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
+ log.debug("deleteLink(): {} in {} out {}",
+ new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
+ if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
+ graph.removeEdge(e);
+ count++;
+ }
+ }*/
+ vportSrc.removeLink(vportDst);
+ dbop.commit();
+ log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
+ lt, vportSrc, vportDst});
+
+ } else {
+ log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
+ dbop.rollback();
+ }
+
+ } catch (TitanException e) {
+ /*
+ * retry till we succeed?
+ */
+ log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
+ dbop.rollback();
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Get list of all links connected to the port specified by given DPID and port number.
+ * @param dpid DPID of desired port.
+ * @param port Port number of desired port.
+ * @return List of links. Empty list if no port was found.
+ */
+ // TODO: Fix me
+ @Override
+ public List<Link> getLinks(Long dpid, short port) {
+ List<Link> links = new ArrayList<Link>();
+
+ IPortObject srcPort = dbop.searchPort(HexString.toHexString(dpid), port);
+ ISwitchObject srcSw = srcPort.getSwitch();
+
+ if(srcSw != null) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
+ Link link = new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber());
+
+ links.add(link);
+ }
+ }
+
+ return links;
+ }
+
+ /**
+ * Initialize the object. Open LinkStorage using given configuration file.
+ * @param conf Path (absolute path for now) to configuration file.
+ */
+ @Override
+ public void init(String conf) {
+ //TODO extract the DB location from properties
+ this.dbop = new GraphDBOperation(conf);
+ }
+
+ /**
+ * Delete records of the links connected to the port specified by given DPID and port number.
+ * @param dpid DPID of desired port.
+ * @param port Port number of desired port.
+ */
+ // TODO: Fix me
+ @Override
+ public void deleteLinksOnPort(Long dpid, short port) {
+ List<Link> linksToDelete = getLinks(dpid,port);
+
+ for(Link l : linksToDelete) {
+ deleteLink(l);
+ }
+ }
+
+ /**
+ * Get list of all links connected to the switch specified by given DPID.
+ * @param dpid DPID of desired switch.
+ * @return List of links. Empty list if no port was found.
+ */
+ // TODO: Fix me
+ @Override
+ public List<Link> getLinks(String dpid) {
+ List<Link> links = new ArrayList<Link>();
+
+ ISwitchObject srcSw = dbop.searchSwitch(dpid);
+
+ if(srcSw != null) {
+ for(IPortObject srcPort : srcSw.getPorts()) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
+ if(dstSw != null) {
+ Link link = new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber());
+ links.add(link);
+ }
+ }
+ }
+ }
+
+ return links;
+ }
+
+ /**
+ * Get list of all links whose state is ACTIVE.
+ * @return List of active links. Empty list if no port was found.
+ */
+ public List<Link> getActiveLinks() {
+ Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
+
+ List<Link> links = new ArrayList<Link>();
+
+ for (ISwitchObject srcSw : switches) {
+ for(IPortObject srcPort : srcSw.getPorts()) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
+
+ if(dstSw != null && dstSw.getState().equals("ACTIVE")) {
+ links.add(new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber()));
+ }
+ }
+ }
+ }
+
+ return links;
+ }
+
+ static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
+
+ @Override
+ public Link compute(PathPipe<Vertex> pipe ) {
+ // TODO Auto-generated method stub
+ long s_dpid = 0;
+ long d_dpid = 0;
+ short s_port = 0;
+ short d_port = 0;
+ List<Vertex> V = new ArrayList<Vertex>();
+ V = pipe.next();
+ Vertex src_sw = V.get(0);
+ Vertex dest_sw = V.get(3);
+ Vertex src_port = V.get(1);
+ Vertex dest_port = V.get(2);
+ s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
+ d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
+ s_port = (Short) src_port.getProperty("number");
+ d_port = (Short) dest_port.getProperty("number");
+
+ Link l = new Link(s_dpid,s_port,d_dpid,d_port);
+
+ return l;
+ }
+ }
+
+ /**
+ * Finalize the object.
+ */
+ public void finalize() {
+ close();
+ }
+
+ /**
+ * Close LinkStorage.
+ */
+ @Override
+ public void close() {
+ // TODO Auto-generated method stub
+// graph.shutdown();
+ }
+
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
new file mode 100644
index 0000000..126efb3
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
@@ -0,0 +1,243 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import net.floodlightcontroller.core.IOFSwitch;
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+
+import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
+import org.openflow.protocol.OFPhysicalPort.OFPortState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the class for storing the information of switches into CassandraDB
+ */
+public class SwitchStorageImpl implements ISwitchStorage {
+ protected GraphDBOperation op;
+ protected static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ /***
+ * Initialize function. Before you use this class, please call this method
+ * @param conf configuration file for Cassandra DB
+ */
+ @Override
+ public void init(String conf) {
+ GraphDBConnection conn = GraphDBConnection.getInstance(conf);
+ op = new GraphDBOperation(conn);
+ }
+
+ /***
+ * Finalize/close function. After you use this class, please call this method.
+ * It will close the DB connection.
+ */
+ public void finalize() {
+ close();
+ }
+
+ /***
+ * Finalize/close function. After you use this class, please call this method.
+ * It will close the DB connection. This is for Java garbage collection.
+ */
+ @Override
+ public void close() {
+ op.close();
+ }
+
+ private void setStatus(String dpid, SwitchState state) {
+ ISwitchObject sw = op.searchSwitch(dpid);
+
+ try {
+ if (sw != null) {
+ sw.setState(state.toString());
+ op.commit();
+ log.info("SwitchStorage:setStatus dpid:{} state: {} done", dpid, state);
+ }
+ } catch(Exception e) {
+ e.printStackTrace();
+ op.rollback();
+ log.info("SwitchStorage:setStatus dpid:{} state: {} failed: switch not found", dpid, state);
+ }
+ }
+
+ /***
+ * This function is for adding the switch into the DB.
+ * @param dpid The switch dpid you want to add into the DB.
+ */
+ @Override
+ public void addSwitch(String dpid) {
+
+ log.info("SwitchStorage:addSwitch(): dpid {} ", dpid);
+ try {
+ ISwitchObject sw = newSwitch(dpid);
+ if ( sw == null ) throw new RuntimeException();
+ op.commit();
+ } catch (Exception e) {
+ e.printStackTrace();
+ op.rollback();
+ log.info("SwitchStorage:addSwitch dpid:{} failed", dpid);
+ }
+ }
+
+ private ISwitchObject newSwitch(String dpid) {
+ ISwitchObject sw = op.searchSwitch(dpid);
+ if (sw != null) {
+ //If existing the switch. set The SW state ACTIVE.
+ log.info("SwitchStorage:newSwitch dpid:{} already exists", dpid);
+ sw.setState(SwitchState.ACTIVE.toString());
+ } else {
+ sw = op.newSwitch(dpid);
+ if (sw != null) {
+ sw.setState(SwitchState.ACTIVE.toString());
+ log.info("SwitchStorage:newSwitch dpid:{} added", dpid);
+ } else {
+ log.error("switchStorage:newSwitch dpid:{} failed -> newSwitch failed", dpid);
+ }
+ }
+ return sw;
+ }
+
+ /***
+ * This function is for updating the switch into the DB.
+ * @param dpid The switch dpid you want to update from the DB
+ * @param state The state of the switch like ACTIVE, INACTIVE
+ * @param dmope The DM_OPERATION of the switch
+ */
+ @Override
+ public void update(String dpid, SwitchState state, DM_OPERATION dmope) {
+ log.info("SwitchStorage:update dpid:{} state: {} ", dpid, state);
+ switch(dmope) {
+ case UPDATE:
+ case INSERT:
+ case CREATE:
+ addSwitch(dpid);
+ if (state != SwitchState.ACTIVE) {
+ setStatus(dpid, state);
+ }
+ break;
+ case DELETE:
+ deleteSwitch(dpid);
+ break;
+ default:
+ }
+ }
+
+ /***
+ * This function is for deleting the switch into the DB.
+ * @param dpid The switch dpid you want to delete from the DB.
+ */
+ @Override
+ public void deleteSwitch(String dpid) {
+ try {
+ ISwitchObject sw = op.searchSwitch(dpid);
+ if (sw != null) {
+ op.removeSwitch(sw);
+ op.commit();
+ log.info("SwitchStorage:DeleteSwitch dpid:{} done", dpid);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ op.rollback();
+ log.error("SwitchStorage:deleteSwitch {} failed", dpid);
+ }
+
+ }
+
+ /***
+ * This function is for adding the switch port into the DB.
+ * @param dpid The switch dpid that has the port.
+ * @param port The port you want to add the switch.
+ */
+ @Override
+ public void addPort(String dpid, OFPhysicalPort port) {
+
+ if(((OFPortConfig.OFPPC_PORT_DOWN.getValue() & port.getConfig()) > 0) ||
+ ((OFPortState.OFPPS_LINK_DOWN.getValue() & port.getState()) > 0)) {
+ deletePort(dpid, port.getPortNumber());
+ return;
+ }
+
+ try {
+ ISwitchObject sw = op.searchSwitch(dpid);
+
+ if (sw != null) {
+ IPortObject p = op.searchPort(dpid, port.getPortNumber());
+ log.info("SwitchStorage:addPort dpid:{} port:{}", dpid, port.getPortNumber());
+ if (p != null) {
+ log.error("SwitchStorage:addPort dpid:{} port:{} exists", dpid, port.getPortNumber());
+ } else {
+ p = op.newPort(dpid, port.getPortNumber());
+ p.setState("ACTIVE");
+ p.setPortState(port.getState());
+ p.setDesc(port.getName());
+ sw.addPort(p);
+ op.commit();
+ }
+ } else {
+ log.error("SwitchStorage:addPort dpid:{} port:{} : failed switch does not exist", dpid, port.getPortNumber());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ op.rollback();
+ log.error("SwitchStorage:addPort dpid:{} port:{} failed", dpid, port.getPortNumber());
+ }
+
+ }
+
+ /***
+ * This function is for deleting the switch port from the DB.
+ * @param dpid The switch dpid that has the port.
+ * @param port The port you want to delete the switch.
+ */
+ @Override
+ public void deletePort(String dpid, short port) {
+ try {
+ ISwitchObject sw = op.searchSwitch(dpid);
+
+ if (sw != null) {
+ IPortObject p = op.searchPort(dpid, port);
+ if (p != null) {
+ log.info("SwitchStorage:deletePort dpid:{} port:{} found and deleted", dpid, port);
+ sw.removePort(p);
+ op.removePort(p);
+ op.commit();
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ op.rollback();
+ log.info("SwitchStorage:deletePort dpid:{} port:{} failed", dpid, port);
+ }
+ }
+
+ @Override
+ public void addSwitch(IOFSwitch sw) {
+ // TODO Auto-generated method stub
+ String dpid = sw.getStringId();
+ log.info("SwitchStorage:addSwitch(): dpid {} ", dpid);
+ try {
+ ISwitchObject switchObject = newSwitch(dpid);
+ for (OFPhysicalPort port: sw.getPorts()) {
+ IPortObject p = op.searchPort(dpid, port.getPortNumber());
+ if (p != null) {
+ log.error("SwitchStorage:addPort dpid:{} port:{} exists", dpid, port.getPortNumber());
+ } else {
+ p = op.newPort(dpid, port.getPortNumber());
+ p.setState("ACTIVE");
+ p.setPortState(port.getState());
+ p.setDesc(port.getName());
+ switchObject.addPort(p);
+ }
+ }
+ op.commit();
+ } catch (Exception e) {
+ e.printStackTrace();
+ op.rollback();
+ log.info("SwitchStorage:addSwitch dpid:{} failed", dpid);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/TopoLinkServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
similarity index 70%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/internal/TopoLinkServiceImpl.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
index 1bd6421..e810646 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/TopoLinkServiceImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
@@ -1,13 +1,13 @@
-package net.floodlightcontroller.linkdiscovery.internal;
+package net.onrc.onos.ofcontroller.core.internal;
import java.util.ArrayList;
import java.util.List;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoLinkService;
-import net.floodlightcontroller.linkdiscovery.internal.LinkStorageImpl.ExtractLink;
import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
+import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl.ExtractLink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -17,25 +17,24 @@
public class TopoLinkServiceImpl implements ITopoLinkService {
- public GraphDBConnection conn;
+ protected GraphDBOperation op;
protected static Logger log = LoggerFactory.getLogger(TopoLinkServiceImpl.class);
-
public void finalize() {
close();
}
@Override
public void close() {
- conn.close();
+ op.close();
}
@Override
public List<Link> getActiveLinks() {
// TODO Auto-generated method stub
- conn = GraphDBConnection.getInstance("");
- conn.close(); //Commit to ensure we see latest data
- Iterable<ISwitchObject> switches = conn.utils().getActiveSwitches(conn);
+ op = new GraphDBOperation("");
+ op.commit(); //Commit to ensure we see latest data
+ Iterable<ISwitchObject> switches = op.getActiveSwitches();
List<Link> links = new ArrayList<Link>();
for (ISwitchObject sw : switches) {
GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
@@ -51,6 +50,7 @@
}
}
+ op.commit();
return links;
}
@@ -58,7 +58,7 @@
public List<Link> getLinksOnSwitch(String dpid) {
// TODO Auto-generated method stub
List<Link> links = new ArrayList<Link>();
- ISwitchObject sw = conn.utils().searchSwitch(conn, dpid);
+ ISwitchObject sw = op.searchSwitch(dpid);
GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
ExtractLink extractor = new ExtractLink();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
new file mode 100644
index 0000000..978fcde
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
@@ -0,0 +1,65 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoSwitchService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TopoSwitchServiceImpl implements ITopoSwitchService {
+
+ private GraphDBOperation op;
+ protected static Logger log = LoggerFactory.getLogger(TopoSwitchServiceImpl.class);
+
+ public TopoSwitchServiceImpl(String conf) {
+ op = new GraphDBOperation(conf);
+ }
+
+ public TopoSwitchServiceImpl() {
+ this("/tmp/cassandra.titan");
+ }
+
+ public void finalize() {
+ close();
+ }
+
+ @Override
+ public void close() {
+ op.close();
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getActiveSwitches() {
+ // TODO Auto-generated method stub
+ op.close(); //Commit to ensure we see latest data
+ return op.getActiveSwitches();
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getAllSwitches() {
+ // TODO Auto-generated method stub
+ op.close(); //Commit to ensure we see latest data
+ return op.getAllSwitches();
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getInactiveSwitches() {
+ // TODO Auto-generated method stub
+ op.close(); //Commit to ensure we see latest data
+ return op.getInactiveSwitches();
+ }
+
+ @Override
+ public Iterable<IPortObject> getPortsOnSwitch(String dpid) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public IPortObject getPortOnSwitch(String dpid, short port_num) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/core/web/ClearFlowTableResource.java b/src/main/java/net/onrc/onos/ofcontroller/core/web/ClearFlowTableResource.java
similarity index 96%
rename from src/main/java/net/floodlightcontroller/core/web/ClearFlowTableResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/web/ClearFlowTableResource.java
index c2d2eb4..7b1acfe 100644
--- a/src/main/java/net/floodlightcontroller/core/web/ClearFlowTableResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/web/ClearFlowTableResource.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.core.web;
+package net.onrc.onos.ofcontroller.core.web;
import java.io.IOException;
import java.util.ArrayList;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/TopoLinksResource.java b/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoLinksResource.java
similarity index 74%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/web/TopoLinksResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/web/TopoLinksResource.java
index 25b68fb..327c110 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/TopoLinksResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoLinksResource.java
@@ -1,8 +1,8 @@
-package net.floodlightcontroller.linkdiscovery.web;
+package net.onrc.onos.ofcontroller.core.web;
import java.util.List;
-import net.floodlightcontroller.linkdiscovery.internal.TopoLinkServiceImpl;
import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.core.internal.TopoLinkServiceImpl;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/core/web/TopoSwitchesResource.java b/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoSwitchesResource.java
similarity index 77%
rename from src/main/java/net/floodlightcontroller/core/web/TopoSwitchesResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/web/TopoSwitchesResource.java
index 7a8511b..a173a70 100644
--- a/src/main/java/net/floodlightcontroller/core/web/TopoSwitchesResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoSwitchesResource.java
@@ -1,9 +1,9 @@
-package net.floodlightcontroller.core.web;
+package net.onrc.onos.ofcontroller.core.web;
import java.util.Iterator;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.TopoSwitchServiceImpl;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/web/TopoDevicesResource.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/web/TopoDevicesResource.java
new file mode 100644
index 0000000..ac9409f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/web/TopoDevicesResource.java
@@ -0,0 +1,19 @@
+package net.onrc.onos.ofcontroller.devicemanager.web;
+
+import java.util.Iterator;
+
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+
+public class TopoDevicesResource extends ServerResource {
+
+ @Get("json")
+ public Iterator<IDeviceObject> retrieve() {
+ GraphDBOperation op = new GraphDBOperation("");
+
+ return op.getDevices().iterator();
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
similarity index 65%
rename from src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java
rename to src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
index 723fe1c..e0ac4e1 100644
--- a/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.onoslistener;
+package net.onrc.onos.ofcontroller.floodlightlistener;
import java.util.ArrayList;
import java.util.Collection;
@@ -6,19 +6,14 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import org.openflow.protocol.OFPhysicalPort;
import org.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitchListener;
-import net.floodlightcontroller.core.ISwitchStorage;
-import net.floodlightcontroller.core.internal.SwitchStorageImpl;
-import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
@@ -27,32 +22,47 @@
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.devicemanager.IDeviceListener;
import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IDeviceStorage;
-import net.floodlightcontroller.devicemanager.internal.DeviceStorageImpl;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.IDBConnection;
+import net.onrc.onos.graph.LocalTopologyEventListener;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.ILinkStorage;
+import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.registry.controller.IControllerRegistryService;
import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
import net.onrc.onos.registry.controller.RegistryException;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.LocalTopologyEventListener;
-public class OnosPublisher implements IDeviceListener, IOFSwitchListener,
+public class NetworkGraphPublisher implements IDeviceListener, IOFSwitchListener, IOFSwitchPortListener,
ILinkDiscoveryListener, IFloodlightModule {
protected IDeviceStorage devStore;
protected ISwitchStorage swStore;
+ protected ILinkStorage linkStore;
protected static Logger log;
protected IDeviceService deviceService;
protected IControllerRegistryService registryService;
- protected GraphDBConnection conn;
+ protected GraphDBOperation op;
protected static final String DBConfigFile = "dbconf";
protected static final String CleanupEnabled = "EnableCleanup";
protected IThreadPoolService threadPool;
+ protected IFloodlightProviderService floodlightProvider;
protected final int CLEANUP_TASK_INTERVAL = 60; // 1 min
protected SingletonTask cleanupTask;
+ protected ILinkDiscoveryService linkDiscovery;
/**
* Cleanup and synch switch state from registry
@@ -67,7 +77,7 @@
catch (Exception e) {
log.error("Error in cleanup thread", e);
} finally {
- conn.close();
+ op.close();
cleanupTask.reschedule(CLEANUP_TASK_INTERVAL,
TimeUnit.SECONDS);
}
@@ -86,8 +96,8 @@
}
protected void switchCleanup() {
- conn.close();
- Iterable<ISwitchObject> switches = conn.utils().getActiveSwitches(conn);
+ op.close();
+ Iterable<ISwitchObject> switches = op.getActiveSwitches();
log.debug("Checking for inactive switches");
// For each switch check if a controller exists in controller registry
@@ -110,18 +120,44 @@
e.printStackTrace();
}
}
- conn.close();
+ op.close();
}
@Override
public void linkDiscoveryUpdate(LDUpdate update) {
// TODO Auto-generated method stub
+ Link lt = new Link(update.getSrc(),update.getSrcPort(),update.getDst(),update.getDstPort());
+ //log.debug("{}:LinkDicoveryUpdate(): Updating Link {}",this.getClass(), lt);
+
+ switch (update.getOperation()) {
+ case LINK_REMOVED:
+ log.debug("LinkDiscoveryUpdate(): Removing link {}", lt);
+ linkStore.update(lt, DM_OPERATION.DELETE);
+ // TODO: Move network map link removal here
+ // reconcile paths here
+// IPortObject srcPort = conn.utils().searchPort(conn, HexString.toHexString(update.getSrc()), update.getSrcPort());
+ break;
+ case LINK_UPDATED:
+ log.debug("LinkDiscoveryUpdate(): Updating link {}", lt);
+ linkStore.update(lt, DM_OPERATION.UPDATE);
+ break;
+ case LINK_ADDED:
+ log.debug("LinkDiscoveryUpdate(): Adding link {}", lt);
+ linkStore.update(lt, DM_OPERATION.INSERT);
+ break;
+
+ default:
+ break;
+ }
}
@Override
public void addedSwitch(IOFSwitch sw) {
- // TODO Auto-generated method stub
+
+ if (registryService.hasControl(sw.getId())) {
+ swStore.addSwitch(sw);
+ }
}
@@ -137,9 +173,22 @@
}
+
+ @Override
+ public void switchPortAdded(Long switchId, OFPhysicalPort port) {
+ // TODO Auto-generated method stub
+ swStore.addPort(HexString.toHexString(switchId), port);
+ }
+
+ @Override
+ public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
+ // TODO Auto-generated method stub
+ swStore.deletePort(HexString.toHexString(switchId), port.getPortNumber());
+ }
+
@Override
public String getName() {
- return "OnosPublisher";
+ return "NetworkGraphPublisher";
}
@Override
@@ -203,10 +252,13 @@
// TODO Auto-generated method stub
Map<String, String> configMap = context.getConfigParams(this);
String conf = configMap.get(DBConfigFile);
- conn = GraphDBConnection.getInstance(conf);
+ op = new GraphDBOperation(conf);
- log = LoggerFactory.getLogger(OnosPublisher.class);
+ log = LoggerFactory.getLogger(NetworkGraphPublisher.class);
+ floodlightProvider =
+ context.getServiceImpl(IFloodlightProviderService.class);
deviceService = context.getServiceImpl(IDeviceService.class);
+ linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
threadPool = context.getServiceImpl(IThreadPoolService.class);
registryService = context.getServiceImpl(IControllerRegistryService.class);
@@ -215,8 +267,11 @@
swStore = new SwitchStorageImpl();
swStore.init(conf);
+
+ linkStore = new LinkStorageImpl();
+ linkStore.init(conf);
- log.debug("Initializing OnosPublisher module with {}", conf);
+ log.debug("Initializing NetworkGraphPublisher module with {}", conf);
}
@@ -227,9 +282,12 @@
String cleanupNeeded = configMap.get(CleanupEnabled);
deviceService.addListener(this);
+ floodlightProvider.addOFSwitchListener(this);
+ linkDiscovery.addListener(this);
log.debug("Adding EventListener");
- conn.addEventListener(new LocalTopologyEventListener(conn));
+ IDBConnection conn = op.getDBConnection();
+ conn.addEventListener(new LocalTopologyEventListener((GraphDBConnection) conn));
// Setup the Cleanup task.
if (cleanupNeeded == null || !cleanupNeeded.equals("False")) {
ScheduledExecutorService ses = threadPool.getScheduledExecutor();
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
similarity index 67%
rename from src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index 251620c..a072882 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -1,6 +1,8 @@
-package net.floodlightcontroller.flowcache;
+package net.onrc.onos.ofcontroller.flowmanager;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -11,58 +13,61 @@
import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.INetMapStorage;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.flowcache.web.FlowWebRoutable;
import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.util.CallerId;
-import net.floodlightcontroller.util.DataPath;
-import net.floodlightcontroller.util.DataPathEndpoints;
-import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.FlowEntry;
-import net.floodlightcontroller.util.FlowEntryAction;
-import net.floodlightcontroller.util.FlowEntryId;
-import net.floodlightcontroller.util.FlowEntryMatch;
-import net.floodlightcontroller.util.FlowEntrySwitchState;
-import net.floodlightcontroller.util.FlowEntryUserState;
-import net.floodlightcontroller.util.FlowId;
-import net.floodlightcontroller.util.FlowPath;
-import net.floodlightcontroller.util.IPv4Net;
import net.floodlightcontroller.util.MACAddress;
import net.floodlightcontroller.util.OFMessageDamper;
-import net.floodlightcontroller.util.Port;
-import net.floodlightcontroller.util.SwitchPort;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.GraphDBConnection.Transaction;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.ofcontroller.util.CallerId;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.DataPathEndpoints;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.FlowEntryAction;
+import net.onrc.onos.ofcontroller.util.FlowEntryAction.*;
+import net.onrc.onos.ofcontroller.util.FlowEntryActions;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
+import net.onrc.onos.ofcontroller.util.FlowEntrySwitchState;
+import net.onrc.onos.ofcontroller.util.FlowEntryUserState;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.util.FlowPathFlags;
+import net.onrc.onos.ofcontroller.util.IPv4Net;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
import org.openflow.protocol.OFFlowMod;
import org.openflow.protocol.OFMatch;
import org.openflow.protocol.OFPacketOut;
import org.openflow.protocol.OFPort;
import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
+import org.openflow.protocol.action.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FlowManager implements IFloodlightModule, IFlowService, INetMapStorage {
- public GraphDBConnection conn;
+ protected GraphDBOperation op;
protected IRestApiService restApi;
protected volatile IFloodlightProviderService floodlightProvider;
@@ -93,9 +98,10 @@
private long modifiedMeasurementFlowTime = 0;
//
private LinkedList<FlowPath> measurementStoredPaths = new LinkedList<FlowPath>();
- private LinkedList<FlowPath> measurementProcessingPaths = null;
private long measurementStartTimeProcessingPaths = 0;
private long measurementEndTimeProcessingPaths = 0;
+ Map<Long, ?> measurementShortestPathTopo = null;
+ private String measurementPerFlowStr = new String();
/** The logger. */
private static Logger log = LoggerFactory.getLogger(FlowManager.class);
@@ -110,7 +116,7 @@
runImpl();
} catch (Exception e) {
log.debug("Exception processing All Flow Entries from the Network MAP: ", e);
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
return;
}
}
@@ -137,7 +143,7 @@
//
boolean processed_measurement_flow = false;
Iterable<IFlowEntry> allFlowEntries =
- conn.utils().getAllSwitchNotUpdatedFlowEntries(conn);
+ op.getAllSwitchNotUpdatedFlowEntries();
for (IFlowEntry flowEntryObj : allFlowEntries) {
counterAllFlowEntries++;
@@ -150,7 +156,7 @@
continue; // Ignore the entry: not my switch
IFlowPath flowObj =
- conn.utils().getFlowPathByFlowEntry(conn, flowEntryObj);
+ op.getFlowPathByFlowEntry(flowEntryObj);
if (flowObj == null)
continue; // Should NOT happen
if (flowObj.getFlowId() == null)
@@ -188,8 +194,7 @@
//
for (IFlowEntry flowEntryObj : addFlowEntries) {
IFlowPath flowObj =
- conn.utils().getFlowPathByFlowEntry(conn,
- flowEntryObj);
+ op.getFlowPathByFlowEntry(flowEntryObj);
if (flowObj == null)
continue; // Should NOT happen
if (flowObj.getFlowId() == null)
@@ -213,16 +218,16 @@
while (! deleteFlowEntries.isEmpty()) {
IFlowEntry flowEntryObj = deleteFlowEntries.poll();
IFlowPath flowObj =
- conn.utils().getFlowPathByFlowEntry(conn, flowEntryObj);
+ op.getFlowPathByFlowEntry(flowEntryObj);
if (flowObj == null) {
log.debug("Did not find FlowPath to be deleted");
continue;
}
flowObj.removeFlowEntry(flowEntryObj);
- conn.utils().removeFlowEntry(conn, flowEntryObj);
+ op.removeFlowEntry(flowEntryObj);
}
- conn.endTx(Transaction.COMMIT);
+ op.commit();
if (processed_measurement_flow) {
long estimatedTime =
@@ -251,7 +256,7 @@
runImpl();
} catch (Exception e) {
log.debug("Exception processing All Flows from the Network MAP: ", e);
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
return;
}
}
@@ -275,8 +280,9 @@
// Fetch and recompute the Shortest Path for those
// Flow Paths this controller is responsible for.
//
- topoRouteService.prepareShortestPathTopo();
- Iterable<IFlowPath> allFlowPaths = conn.utils().getAllFlowPaths(conn);
+ Map<Long, ?> shortestPathTopo =
+ topoRouteService.prepareShortestPathTopo();
+ Iterable<IFlowPath> allFlowPaths = op.getAllFlowPaths();
for (IFlowPath flowPathObj : allFlowPaths) {
counterAllFlowPaths++;
if (flowPathObj == null)
@@ -326,9 +332,11 @@
Short srcPortShort = flowPathObj.getSrcPort();
String dstDpidStr = flowPathObj.getDstSwitch();
Short dstPortShort = flowPathObj.getDstPort();
+ Long flowPathFlagsLong = flowPathObj.getFlowPathFlags();
if ((srcPortShort == null) ||
(dstDpidStr == null) ||
- (dstPortShort == null)) {
+ (dstPortShort == null) ||
+ (flowPathFlagsLong == null)) {
continue;
}
@@ -337,6 +345,7 @@
Port dstPort = new Port(dstPortShort);
SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+ FlowPathFlags flowPathFlags = new FlowPathFlags(flowPathFlagsLong);
counterMyFlowPaths++;
@@ -350,7 +359,8 @@
// to avoid closing the transaction.
//
DataPath dataPath =
- topoRouteService.getTopoShortestPath(srcSwitchPort,
+ topoRouteService.getTopoShortestPath(shortestPathTopo,
+ srcSwitchPort,
dstSwitchPort);
if (dataPath == null) {
// We need the DataPath to compare the paths
@@ -358,6 +368,7 @@
dataPath.setSrcPort(srcSwitchPort);
dataPath.setDstPort(dstSwitchPort);
}
+ dataPath.applyFlowPathFlags(flowPathFlags);
String newDataPathSummaryStr = dataPath.dataPathSummary();
if (dataPathSummaryStr.equals(newDataPathSummaryStr))
@@ -372,12 +383,12 @@
//
while (! deleteFlows.isEmpty()) {
IFlowPath flowPathObj = deleteFlows.poll();
- conn.utils().removeFlowPath(conn, flowPathObj);
+ op.removeFlowPath(flowPathObj);
}
- topoRouteService.dropShortestPathTopo();
+ topoRouteService.dropShortestPathTopo(shortestPathTopo);
- conn.endTx(Transaction.COMMIT);
+ op.commit();
if (processed_measurement_flow) {
long estimatedTime =
@@ -408,16 +419,17 @@
@Override
public void init(String conf) {
- conn = GraphDBConnection.getInstance(conf);
+ op = new GraphDBOperation(conf);
+ topoRouteService = new TopoRouteService(conf);
}
public void finalize() {
- close();
+ close();
}
@Override
public void close() {
- conn.close();
+ op.close();
}
@Override
@@ -445,7 +457,6 @@
Collection<Class<? extends IFloodlightService>> l =
new ArrayList<Class<? extends IFloodlightService>>();
l.add(IFloodlightProviderService.class);
- l.add(ITopoRouteService.class);
l.add(IRestApiService.class);
return l;
}
@@ -455,11 +466,11 @@
throws FloodlightModuleException {
this.context = context;
floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
- topoRouteService = context.getServiceImpl(ITopoRouteService.class);
restApi = context.getServiceImpl(IRestApiService.class);
messageDamper = new OFMessageDamper(OFMESSAGE_DAMPER_CAPACITY,
EnumSet.of(OFType.FLOW_MOD),
OFMESSAGE_DAMPER_TIMEOUT);
+
// TODO: An ugly hack!
String conf = "/tmp/cassandra.titan";
this.init(conf);
@@ -494,9 +505,9 @@
nextFlowEntryIdPrefix = randomGenerator.nextInt();
mapReaderScheduler.scheduleAtFixedRate(
- mapReader, 1, 1, TimeUnit.SECONDS);
+ mapReader, 3, 3, TimeUnit.SECONDS);
shortestPathReconcileScheduler.scheduleAtFixedRate(
- shortestPathReconcile, 100, 100, TimeUnit.MILLISECONDS);
+ shortestPathReconcile, 3, 3, TimeUnit.SECONDS);
}
/**
@@ -524,26 +535,32 @@
IFlowPath flowObj = null;
boolean found = false;
try {
- if ((flowObj = conn.utils().searchFlowPath(conn, flowPath.flowId()))
+ if ((flowObj = op.searchFlowPath(flowPath.flowId()))
!= null) {
log.debug("Adding FlowPath with FlowId {}: found existing FlowPath",
flowPath.flowId().toString());
found = true;
} else {
- flowObj = conn.utils().newFlowPath(conn);
+ flowObj = op.newFlowPath();
log.debug("Adding FlowPath with FlowId {}: creating new FlowPath",
flowPath.flowId().toString());
}
} catch (Exception e) {
// TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
- log.error(":addFlow FlowId:{} failed",
- flowPath.flowId().toString());
+ op.rollback();
+
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw));
+ String stacktrace = sw.toString();
+
+ log.error(":addFlow FlowId:{} failed: {}",
+ flowPath.flowId().toString(),
+ stacktrace);
}
if (flowObj == null) {
log.error(":addFlow FlowId:{} failed: Flow object not created",
flowPath.flowId().toString());
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
return false;
}
@@ -557,33 +574,63 @@
//
// Set the Flow attributes:
// - flowPath.installerId()
+ // - flowPath.flowPathFlags()
// - flowPath.dataPath().srcPort()
// - flowPath.dataPath().dstPort()
- // - flowPath.matchEthernetFrameType()
- // - flowPath.matchSrcIPv4Net()
- // - flowPath.matchDstIPv4Net()
// - flowPath.matchSrcMac()
// - flowPath.matchDstMac()
+ // - flowPath.matchEthernetFrameType()
+ // - flowPath.matchVlanId()
+ // - flowPath.matchVlanPriority()
+ // - flowPath.matchSrcIPv4Net()
+ // - flowPath.matchDstIPv4Net()
+ // - flowPath.matchIpProto()
+ // - flowPath.matchIpToS()
+ // - flowPath.matchSrcTcpUdpPort()
+ // - flowPath.matchDstTcpUdpPort()
+ // - flowPath.flowEntryActions()
//
flowObj.setInstallerId(flowPath.installerId().toString());
+ flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
+ if (flowPath.flowEntryMatch().matchSrcMac()) {
+ flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
+ }
+ if (flowPath.flowEntryMatch().matchDstMac()) {
+ flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
+ }
if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
}
+ if (flowPath.flowEntryMatch().matchVlanId()) {
+ flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
+ }
+ if (flowPath.flowEntryMatch().matchVlanPriority()) {
+ flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
+ }
if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
}
if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
}
- if (flowPath.flowEntryMatch().matchSrcMac()) {
- flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
+ if (flowPath.flowEntryMatch().matchIpProto()) {
+ flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
}
- if (flowPath.flowEntryMatch().matchDstMac()) {
- flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
+ if (flowPath.flowEntryMatch().matchIpToS()) {
+ flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
+ }
+ if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
+ flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
+ }
+ if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
+ flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
+ }
+ if (! flowPath.flowEntryActions().actions().isEmpty()) {
+ flowObj.setActions(flowPath.flowEntryActions().toString());
}
if (dataPathSummaryStr != null) {
@@ -607,11 +654,11 @@
//
for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
if (addFlowEntry(flowObj, flowEntry) == null) {
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
return false;
}
}
- conn.endTx(Transaction.COMMIT);
+ op.commit();
//
// TODO: We need a proper Flow ID allocation mechanism.
@@ -645,12 +692,12 @@
boolean found = false;
try {
if ((flowEntryObj =
- conn.utils().searchFlowEntry(conn, flowEntry.flowEntryId())) != null) {
+ op.searchFlowEntry(flowEntry.flowEntryId())) != null) {
log.debug("Adding FlowEntry with FlowEntryId {}: found existing FlowEntry",
flowEntry.flowEntryId().toString());
found = true;
} else {
- flowEntryObj = conn.utils().newFlowEntry(conn);
+ flowEntryObj = op.newFlowEntry();
log.debug("Adding FlowEntry with FlowEntryId {}: creating new FlowEntry",
flowEntry.flowEntryId().toString());
}
@@ -678,57 +725,83 @@
// - InPort edge
// - OutPort edge
//
- // - flowEntry.flowEntryMatch()
- // - flowEntry.flowEntryActions()
// - flowEntry.dpid()
// - flowEntry.flowEntryUserState()
// - flowEntry.flowEntrySwitchState()
// - flowEntry.flowEntryErrorState()
// - flowEntry.matchInPort()
- // - flowEntry.matchEthernetFrameType()
- // - flowEntry.matchSrcIPv4Net()
- // - flowEntry.matchDstIPv4Net()
// - flowEntry.matchSrcMac()
// - flowEntry.matchDstMac()
- // - flowEntry.actionOutput()
+ // - flowEntry.matchEthernetFrameType()
+ // - flowEntry.matchVlanId()
+ // - flowEntry.matchVlanPriority()
+ // - flowEntry.matchSrcIPv4Net()
+ // - flowEntry.matchDstIPv4Net()
+ // - flowEntry.matchIpProto()
+ // - flowEntry.matchIpToS()
+ // - flowEntry.matchSrcTcpUdpPort()
+ // - flowEntry.matchDstTcpUdpPort()
+ // - flowEntry.actionOutputPort()
+ // - flowEntry.actions()
//
ISwitchObject sw =
- conn.utils().searchSwitch(conn, flowEntry.dpid().toString());
+ op.searchSwitch(flowEntry.dpid().toString());
flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
flowEntryObj.setSwitch(sw);
if (flowEntry.flowEntryMatch().matchInPort()) {
IPortObject inport =
- conn.utils().searchPort(conn, flowEntry.dpid().toString(),
+ op.searchPort(flowEntry.dpid().toString(),
flowEntry.flowEntryMatch().inPort().value());
flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
flowEntryObj.setInPort(inport);
}
- if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
- flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
- }
- if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
- flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
- }
- if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
- flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
- }
if (flowEntry.flowEntryMatch().matchSrcMac()) {
flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
}
if (flowEntry.flowEntryMatch().matchDstMac()) {
flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
}
+ if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
+ flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+ }
+ if (flowEntry.flowEntryMatch().matchVlanId()) {
+ flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
+ }
+ if (flowEntry.flowEntryMatch().matchVlanPriority()) {
+ flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
+ }
+ if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
+ flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
+ flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchIpProto()) {
+ flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
+ }
+ if (flowEntry.flowEntryMatch().matchIpToS()) {
+ flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
+ }
+ if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
+ flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
+ }
+ if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
+ flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
+ }
- for (FlowEntryAction fa : flowEntry.flowEntryActions()) {
+ for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
if (fa.actionOutput() != null) {
IPortObject outport =
- conn.utils().searchPort(conn,
- flowEntry.dpid().toString(),
- fa.actionOutput().port().value());
- flowEntryObj.setActionOutput(fa.actionOutput().port().value());
+ op.searchPort(flowEntry.dpid().toString(),
+ fa.actionOutput().port().value());
+ flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
flowEntryObj.setOutPort(outport);
}
}
+ if (! flowEntry.flowEntryActions().isEmpty()) {
+ flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
+ }
+
// TODO: Hacks with hard-coded state names!
if (found)
flowEntryObj.setUserState("FE_USER_MODIFY");
@@ -757,13 +830,63 @@
*/
@Override
public boolean deleteAllFlows() {
+ List<Thread> threads = new LinkedList<Thread>();
+ final ConcurrentLinkedQueue<FlowId> concurrentAllFlowIds =
+ new ConcurrentLinkedQueue<FlowId>();
- // Get all flows and delete them one-by-one
- ArrayList<FlowPath> allFlows = getAllFlows();
- for (FlowPath flowPath : allFlows) {
- deleteFlow(flowPath.flowId());
+ // Get all Flow IDs
+ Iterable<IFlowPath> allFlowPaths = op.getAllFlowPaths();
+ for (IFlowPath flowPathObj : allFlowPaths) {
+ if (flowPathObj == null)
+ continue;
+ String flowIdStr = flowPathObj.getFlowId();
+ if (flowIdStr == null)
+ continue;
+ FlowId flowId = new FlowId(flowIdStr);
+ concurrentAllFlowIds.add(flowId);
}
+ // Delete all flows one-by-one
+ for (FlowId flowId : concurrentAllFlowIds)
+ deleteFlow(flowId);
+
+ /*
+ * TODO: A faster mechanism to delete the Flow Paths by using
+ * a number of threads. Commented-out for now.
+ */
+ /*
+ //
+ // Create the threads to delete the Flow Paths
+ //
+ for (int i = 0; i < 10; i++) {
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ while (true) {
+ FlowId flowId = concurrentAllFlowIds.poll();
+ if (flowId == null)
+ return;
+ deleteFlow(flowId);
+ }
+ }}, "Delete All Flow Paths");
+ threads.add(thread);
+ }
+
+ // Start processing
+ for (Thread thread : threads) {
+ thread.start();
+ }
+
+ // Wait for all threads to complete
+ for (Thread thread : threads) {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ log.debug("Exception waiting for a thread to delete a Flow Path: ", e);
+ }
+ }
+ */
+
return true;
}
@@ -789,7 +912,7 @@
// it has been removed from the switches.
//
try {
- if ((flowObj = conn.utils().searchFlowPath(conn, flowId))
+ if ((flowObj = op.searchFlowPath(flowId))
!= null) {
log.debug("Deleting FlowPath with FlowId {}: found existing FlowPath",
flowId.toString());
@@ -799,11 +922,11 @@
}
} catch (Exception e) {
// TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
log.error(":deleteFlow FlowId:{} failed", flowId.toString());
}
if (flowObj == null) {
- conn.endTx(Transaction.COMMIT);
+ op.commit();
return true; // OK: No such flow
}
@@ -823,8 +946,8 @@
}
// Remove from the database empty flows
if (empty)
- conn.utils().removeFlowPath(conn, flowObj);
- conn.endTx(Transaction.COMMIT);
+ op.removeFlowPath(flowObj);
+ op.commit();
return true;
}
@@ -836,11 +959,23 @@
*/
@Override
public boolean clearAllFlows() {
+ List<FlowId> allFlowIds = new LinkedList<FlowId>();
- // Get all flows and clear them one-by-one
- ArrayList<FlowPath> allFlows = getAllFlows();
- for (FlowPath flowPath : allFlows) {
- clearFlow(flowPath.flowId());
+ // Get all Flow IDs
+ Iterable<IFlowPath> allFlowPaths = op.getAllFlowPaths();
+ for (IFlowPath flowPathObj : allFlowPaths) {
+ if (flowPathObj == null)
+ continue;
+ String flowIdStr = flowPathObj.getFlowId();
+ if (flowIdStr == null)
+ continue;
+ FlowId flowId = new FlowId(flowIdStr);
+ allFlowIds.add(flowId);
+ }
+
+ // Clear all flows one-by-one
+ for (FlowId flowId : allFlowIds) {
+ clearFlow(flowId);
}
return true;
@@ -856,7 +991,7 @@
public boolean clearFlow(FlowId flowId) {
IFlowPath flowObj = null;
try {
- if ((flowObj = conn.utils().searchFlowPath(conn, flowId))
+ if ((flowObj = op.searchFlowPath(flowId))
!= null) {
log.debug("Clearing FlowPath with FlowId {}: found existing FlowPath",
flowId.toString());
@@ -866,11 +1001,11 @@
}
} catch (Exception e) {
// TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
log.error(":clearFlow FlowId:{} failed", flowId.toString());
}
if (flowObj == null) {
- conn.endTx(Transaction.COMMIT);
+ op.commit();
return true; // OK: No such flow
}
@@ -880,11 +1015,11 @@
Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
for (IFlowEntry flowEntryObj : flowEntries) {
flowObj.removeFlowEntry(flowEntryObj);
- conn.utils().removeFlowEntry(conn, flowEntryObj);
+ op.removeFlowEntry(flowEntryObj);
}
// Remove the Flow itself
- conn.utils().removeFlowPath(conn, flowObj);
- conn.endTx(Transaction.COMMIT);
+ op.removeFlowPath(flowObj);
+ op.commit();
return true;
}
@@ -899,7 +1034,7 @@
public FlowPath getFlow(FlowId flowId) {
IFlowPath flowObj = null;
try {
- if ((flowObj = conn.utils().searchFlowPath(conn, flowId))
+ if ((flowObj = op.searchFlowPath(flowId))
!= null) {
log.debug("Get FlowPath with FlowId {}: found existing FlowPath",
flowId.toString());
@@ -909,11 +1044,11 @@
}
} catch (Exception e) {
// TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
log.error(":getFlow FlowId:{} failed", flowId.toString());
}
if (flowObj == null) {
- conn.endTx(Transaction.COMMIT);
+ op.commit();
return null; // Flow not found
}
@@ -921,7 +1056,7 @@
// Extract the Flow state
//
FlowPath flowPath = extractFlowPath(flowObj);
- conn.endTx(Transaction.COMMIT);
+ op.commit();
return flowPath;
}
@@ -1112,18 +1247,18 @@
ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
try {
- if ((flowPathsObj = conn.utils().getAllFlowPaths(conn)) != null) {
+ if ((flowPathsObj = op.getAllFlowPaths()) != null) {
log.debug("Get all FlowPaths: found FlowPaths");
} else {
log.debug("Get all FlowPaths: no FlowPaths found");
}
} catch (Exception e) {
// TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
log.error(":getAllFlowPaths failed");
}
if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
- conn.endTx(Transaction.COMMIT);
+ op.commit();
return flowPaths; // No Flows found
}
@@ -1136,7 +1271,7 @@
flowPaths.add(flowPath);
}
- conn.endTx(Transaction.COMMIT);
+ op.commit();
return flowPaths;
}
@@ -1146,17 +1281,17 @@
ArrayList<IFlowPath> flowPathsObjArray = new ArrayList<IFlowPath>();
ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
- conn.endTx(Transaction.COMMIT);
+ op.commit();
try {
- if ((flowPathsObj = conn.utils().getAllFlowPaths(conn)) != null) {
+ if ((flowPathsObj = op.getAllFlowPaths()) != null) {
log.debug("Get all FlowPaths: found FlowPaths");
} else {
log.debug("Get all FlowPaths: no FlowPaths found");
}
} catch (Exception e) {
// TODO: handle exceptions
- conn.endTx(Transaction.ROLLBACK);
+ op.rollback();
log.error(":getAllFlowPaths failed");
}
if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
@@ -1194,6 +1329,7 @@
//
String flowIdStr = flowObj.getFlowId();
String installerIdStr = flowObj.getInstallerId();
+ Long flowPathFlags = flowObj.getFlowPathFlags();
String srcSwitchStr = flowObj.getSrcSwitch();
Short srcPortShort = flowObj.getSrcPort();
String dstSwitchStr = flowObj.getDstSwitch();
@@ -1201,6 +1337,7 @@
if ((flowIdStr == null) ||
(installerIdStr == null) ||
+ (flowPathFlags == null) ||
(srcSwitchStr == null) ||
(srcPortShort == null) ||
(dstSwitchStr == null) ||
@@ -1212,6 +1349,7 @@
FlowPath flowPath = new FlowPath();
flowPath.setFlowId(new FlowId(flowIdStr));
flowPath.setInstallerId(new CallerId(installerIdStr));
+ flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
@@ -1221,23 +1359,52 @@
//
{
FlowEntryMatch match = new FlowEntryMatch();
- Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType != null)
- match.enableEthernetFrameType(matchEthernetFrameType);
- String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net != null)
- match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
- String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net != null)
- match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
String matchSrcMac = flowObj.getMatchSrcMac();
if (matchSrcMac != null)
match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
String matchDstMac = flowObj.getMatchDstMac();
if (matchDstMac != null)
match.enableDstMac(MACAddress.valueOf(matchDstMac));
+ Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null)
+ match.enableEthernetFrameType(matchEthernetFrameType);
+ Short matchVlanId = flowObj.getMatchVlanId();
+ if (matchVlanId != null)
+ match.enableVlanId(matchVlanId);
+ Byte matchVlanPriority = flowObj.getMatchVlanPriority();
+ if (matchVlanPriority != null)
+ match.enableVlanPriority(matchVlanPriority);
+ String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null)
+ match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+ String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null)
+ match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+ Byte matchIpProto = flowObj.getMatchIpProto();
+ if (matchIpProto != null)
+ match.enableIpProto(matchIpProto);
+ Byte matchIpToS = flowObj.getMatchIpToS();
+ if (matchIpToS != null)
+ match.enableIpToS(matchIpToS);
+ Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
+ if (matchSrcTcpUdpPort != null)
+ match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
+ Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
+ if (matchDstTcpUdpPort != null)
+ match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+
flowPath.setFlowEntryMatch(match);
}
+ //
+ // Extract the actions for the first Flow Entry
+ //
+ {
+ String actionsStr = flowObj.getActions();
+ if (actionsStr != null) {
+ FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
+ flowPath.setFlowEntryActions(flowEntryActions);
+ }
+ }
//
// Extract all Flow Entries
@@ -1284,39 +1451,53 @@
Short matchInPort = flowEntryObj.getMatchInPort();
if (matchInPort != null)
match.enableInPort(new Port(matchInPort));
- Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType != null)
- match.enableEthernetFrameType(matchEthernetFrameType);
- String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net != null)
- match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
- String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net != null)
- match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
String matchSrcMac = flowEntryObj.getMatchSrcMac();
if (matchSrcMac != null)
match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
String matchDstMac = flowEntryObj.getMatchDstMac();
if (matchDstMac != null)
match.enableDstMac(MACAddress.valueOf(matchDstMac));
+ Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null)
+ match.enableEthernetFrameType(matchEthernetFrameType);
+ Short matchVlanId = flowEntryObj.getMatchVlanId();
+ if (matchVlanId != null)
+ match.enableVlanId(matchVlanId);
+ Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
+ if (matchVlanPriority != null)
+ match.enableVlanPriority(matchVlanPriority);
+ String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null)
+ match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+ String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null)
+ match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+ Byte matchIpProto = flowEntryObj.getMatchIpProto();
+ if (matchIpProto != null)
+ match.enableIpProto(matchIpProto);
+ Byte matchIpToS = flowEntryObj.getMatchIpToS();
+ if (matchIpToS != null)
+ match.enableIpToS(matchIpToS);
+ Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
+ if (matchSrcTcpUdpPort != null)
+ match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
+ Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
+ if (matchDstTcpUdpPort != null)
+ match.enableDstTcpUdpPort(matchDstTcpUdpPort);
flowEntry.setFlowEntryMatch(match);
//
// Extract the actions
//
- ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
- Short actionOutputPort = flowEntryObj.getActionOutput();
- if (actionOutputPort != null) {
- FlowEntryAction action = new FlowEntryAction();
- action.setActionOutput(new Port(actionOutputPort));
- actions.add(action);
- }
+ FlowEntryActions actions = new FlowEntryActions();
+ String actionsStr = flowEntryObj.getActions();
+ if (actionsStr != null)
+ actions = new FlowEntryActions(actionsStr);
flowEntry.setFlowEntryActions(actions);
flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
//
- // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
- // and FlowEntryErrorState.
+ // TODO: Take care of FlowEntryErrorState.
//
return flowEntry;
}
@@ -1348,8 +1529,10 @@
FlowPath computedFlowPath = new FlowPath();
computedFlowPath.setFlowId(new FlowId(flowPath.flowId().value()));
computedFlowPath.setInstallerId(new CallerId(flowPath.installerId().value()));
+ computedFlowPath.setFlowPathFlags(new FlowPathFlags(flowPath.flowPathFlags().flags()));
computedFlowPath.setDataPath(dataPath);
computedFlowPath.setFlowEntryMatch(new FlowEntryMatch(flowPath.flowEntryMatch()));
+ computedFlowPath.setFlowEntryActions(new FlowEntryActions(flowPath.flowEntryActions()));
FlowId flowId = new FlowId();
String dataPathSummaryStr = dataPath.dataPathSummary();
@@ -1375,21 +1558,35 @@
// Set the incoming port matching and the outgoing port output
// actions for each flow entry.
//
+ int idx = 0;
for (FlowEntry flowEntry : newDataPath.flowEntries()) {
// Set the incoming port matching
FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
flowEntry.setFlowEntryMatch(flowEntryMatch);
flowEntryMatch.enableInPort(flowEntry.inPort());
- // Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
+ //
+ // Set the actions
+ //
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
+ //
+ // If the first Flow Entry, copy the Flow Path actions to it
+ //
+ if (idx == 0) {
+ String actionsStr = flowObj.getActions();
+ if (actionsStr != null) {
+ FlowEntryActions flowActions = new FlowEntryActions(actionsStr);
+ for (FlowEntryAction action : flowActions.actions())
+ flowEntryActions.addAction(action);
+ }
}
+ idx++;
+ //
+ // Add the outgoing port output action
+ //
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
}
//
@@ -1481,31 +1678,6 @@
match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
}
- // Match the Ethernet Frame Type
- Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType == null)
- matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
- if (matchEthernetFrameType != null) {
- match.setDataLayerType(matchEthernetFrameType);
- match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
- }
-
- // Match the Source IPv4 Network prefix
- String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net == null)
- matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
- if (matchSrcIPv4Net != null) {
- match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
- }
-
- // Natch the Destination IPv4 Network prefix
- String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net == null)
- matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
- if (matchDstIPv4Net != null) {
- match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
- }
-
// Match the Source MAC address
String matchSrcMac = flowEntryObj.getMatchSrcMac();
if (matchSrcMac == null)
@@ -1524,19 +1696,197 @@
match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
}
+ // Match the Ethernet Frame Type
+ Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType == null)
+ matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null) {
+ match.setDataLayerType(matchEthernetFrameType);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+ }
+
+ // Match the VLAN ID
+ Short matchVlanId = flowEntryObj.getMatchVlanId();
+ if (matchVlanId == null)
+ matchVlanId = flowObj.getMatchVlanId();
+ if (matchVlanId != null) {
+ match.setDataLayerVirtualLan(matchVlanId);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN);
+ }
+
+ // Match the VLAN priority
+ Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
+ if (matchVlanPriority == null)
+ matchVlanPriority = flowObj.getMatchVlanPriority();
+ if (matchVlanPriority != null) {
+ match.setDataLayerVirtualLanPriorityCodePoint(matchVlanPriority);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN_PCP);
+ }
+
+ // Match the Source IPv4 Network prefix
+ String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net == null)
+ matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null) {
+ match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
+ }
+
+ // Natch the Destination IPv4 Network prefix
+ String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net == null)
+ matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null) {
+ match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
+ }
+
+ // Match the IP protocol
+ Byte matchIpProto = flowEntryObj.getMatchIpProto();
+ if (matchIpProto == null)
+ matchIpProto = flowObj.getMatchIpProto();
+ if (matchIpProto != null) {
+ match.setNetworkProtocol(matchIpProto);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
+ }
+
+ // Match the IP ToS (DSCP field, 6 bits)
+ Byte matchIpToS = flowEntryObj.getMatchIpToS();
+ if (matchIpToS == null)
+ matchIpToS = flowObj.getMatchIpToS();
+ if (matchIpToS != null) {
+ match.setNetworkTypeOfService(matchIpToS);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_TOS);
+ }
+
+ // Match the Source TCP/UDP port
+ Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
+ if (matchSrcTcpUdpPort == null)
+ matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
+ if (matchSrcTcpUdpPort != null) {
+ match.setTransportSource(matchSrcTcpUdpPort);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
+ }
+
+ // Match the Destination TCP/UDP port
+ Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
+ if (matchDstTcpUdpPort == null)
+ matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
+ if (matchDstTcpUdpPort != null) {
+ match.setTransportDestination(matchDstTcpUdpPort);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_DST);
+ }
+
//
// Fetch the actions
//
- // TODO: For now we support only the "OUTPUT" actions.
- //
- List<OFAction> actions = new ArrayList<OFAction>();
- Short actionOutputPort = flowEntryObj.getActionOutput();
- if (actionOutputPort != null) {
- OFActionOutput action = new OFActionOutput();
- // XXX: The max length is hard-coded for now
- action.setMaxLength((short)0xffff);
- action.setPort(actionOutputPort);
- actions.add(action);
+ Short actionOutputPort = null;
+ List<OFAction> openFlowActions = new ArrayList<OFAction>();
+ int actionsLen = 0;
+ FlowEntryActions flowEntryActions = null;
+ String actionsStr = flowEntryObj.getActions();
+ if (actionsStr != null)
+ flowEntryActions = new FlowEntryActions(actionsStr);
+ for (FlowEntryAction action : flowEntryActions.actions()) {
+ ActionOutput actionOutput = action.actionOutput();
+ ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
+ ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
+ ActionStripVlan actionStripVlan = action.actionStripVlan();
+ ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
+ ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
+ ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
+ ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
+ ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
+ ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
+ ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
+ ActionEnqueue actionEnqueue = action.actionEnqueue();
+
+ if (actionOutput != null) {
+ actionOutputPort = actionOutput.port().value();
+ // XXX: The max length is hard-coded for now
+ OFActionOutput ofa =
+ new OFActionOutput(actionOutput.port().value(),
+ (short)0xffff);
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetVlanId != null) {
+ OFActionVirtualLanIdentifier ofa =
+ new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetVlanPriority != null) {
+ OFActionVirtualLanPriorityCodePoint ofa =
+ new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionStripVlan != null) {
+ if (actionStripVlan.stripVlan() == true) {
+ OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+ }
+
+ if (actionSetEthernetSrcAddr != null) {
+ OFActionDataLayerSource ofa =
+ new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetEthernetDstAddr != null) {
+ OFActionDataLayerDestination ofa =
+ new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIPv4SrcAddr != null) {
+ OFActionNetworkLayerSource ofa =
+ new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIPv4DstAddr != null) {
+ OFActionNetworkLayerDestination ofa =
+ new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIpToS != null) {
+ OFActionNetworkTypeOfService ofa =
+ new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetTcpUdpSrcPort != null) {
+ OFActionTransportLayerSource ofa =
+ new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetTcpUdpDstPort != null) {
+ OFActionTransportLayerDestination ofa =
+ new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionEnqueue != null) {
+ OFActionEnqueue ofa =
+ new OFActionEnqueue(actionEnqueue.port().value(),
+ actionEnqueue.queueId());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
}
fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
@@ -1546,8 +1896,8 @@
.setCookie(cookie)
.setCommand(flowModCommand)
.setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+ .setActions(openFlowActions)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
fm.setOutPort(OFPort.OFPP_NONE.getValue());
if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
(flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
@@ -1640,34 +1990,6 @@
match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
}
- // Match the Ethernet Frame Type
- Short matchEthernetFrameType = flowEntryMatch.ethernetFrameType();
- if ((matchEthernetFrameType == null) && (flowPathMatch != null)) {
- matchEthernetFrameType = flowPathMatch.ethernetFrameType();
- }
- if (matchEthernetFrameType != null) {
- match.setDataLayerType(matchEthernetFrameType);
- match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
- }
-
- // Match the Source IPv4 Network prefix
- IPv4Net matchSrcIPv4Net = flowEntryMatch.srcIPv4Net();
- if ((matchSrcIPv4Net == null) && (flowPathMatch != null)) {
- matchSrcIPv4Net = flowPathMatch.srcIPv4Net();
- }
- if (matchSrcIPv4Net != null) {
- match.setFromCIDR(matchSrcIPv4Net.toString(), OFMatch.STR_NW_SRC);
- }
-
- // Natch the Destination IPv4 Network prefix
- IPv4Net matchDstIPv4Net = flowEntryMatch.dstIPv4Net();
- if ((matchDstIPv4Net == null) && (flowPathMatch != null)) {
- matchDstIPv4Net = flowPathMatch.dstIPv4Net();
- }
- if (matchDstIPv4Net != null) {
- match.setFromCIDR(matchDstIPv4Net.toString(), OFMatch.STR_NW_DST);
- }
-
// Match the Source MAC address
MACAddress matchSrcMac = flowEntryMatch.srcMac();
if ((matchSrcMac == null) && (flowPathMatch != null)) {
@@ -1688,30 +2010,204 @@
match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
}
+ // Match the Ethernet Frame Type
+ Short matchEthernetFrameType = flowEntryMatch.ethernetFrameType();
+ if ((matchEthernetFrameType == null) && (flowPathMatch != null)) {
+ matchEthernetFrameType = flowPathMatch.ethernetFrameType();
+ }
+ if (matchEthernetFrameType != null) {
+ match.setDataLayerType(matchEthernetFrameType);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+ }
+
+ // Match the VLAN ID
+ Short matchVlanId = flowEntryMatch.vlanId();
+ if ((matchVlanId == null) && (flowPathMatch != null)) {
+ matchVlanId = flowPathMatch.vlanId();
+ }
+ if (matchVlanId != null) {
+ match.setDataLayerVirtualLan(matchVlanId);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN);
+ }
+
+ // Match the VLAN priority
+ Byte matchVlanPriority = flowEntryMatch.vlanPriority();
+ if ((matchVlanPriority == null) && (flowPathMatch != null)) {
+ matchVlanPriority = flowPathMatch.vlanPriority();
+ }
+ if (matchVlanPriority != null) {
+ match.setDataLayerVirtualLanPriorityCodePoint(matchVlanPriority);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN_PCP);
+ }
+
+ // Match the Source IPv4 Network prefix
+ IPv4Net matchSrcIPv4Net = flowEntryMatch.srcIPv4Net();
+ if ((matchSrcIPv4Net == null) && (flowPathMatch != null)) {
+ matchSrcIPv4Net = flowPathMatch.srcIPv4Net();
+ }
+ if (matchSrcIPv4Net != null) {
+ match.setFromCIDR(matchSrcIPv4Net.toString(), OFMatch.STR_NW_SRC);
+ }
+
+ // Natch the Destination IPv4 Network prefix
+ IPv4Net matchDstIPv4Net = flowEntryMatch.dstIPv4Net();
+ if ((matchDstIPv4Net == null) && (flowPathMatch != null)) {
+ matchDstIPv4Net = flowPathMatch.dstIPv4Net();
+ }
+ if (matchDstIPv4Net != null) {
+ match.setFromCIDR(matchDstIPv4Net.toString(), OFMatch.STR_NW_DST);
+ }
+
+ // Match the IP protocol
+ Byte matchIpProto = flowEntryMatch.ipProto();
+ if ((matchIpProto == null) && (flowPathMatch != null)) {
+ matchIpProto = flowPathMatch.ipProto();
+ }
+ if (matchIpProto != null) {
+ match.setNetworkProtocol(matchIpProto);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
+ }
+
+ // Match the IP ToS (DSCP field, 6 bits)
+ Byte matchIpToS = flowEntryMatch.ipToS();
+ if ((matchIpToS == null) && (flowPathMatch != null)) {
+ matchIpToS = flowPathMatch.ipToS();
+ }
+ if (matchIpToS != null) {
+ match.setNetworkTypeOfService(matchIpToS);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_TOS);
+ }
+
+ // Match the Source TCP/UDP port
+ Short matchSrcTcpUdpPort = flowEntryMatch.srcTcpUdpPort();
+ if ((matchSrcTcpUdpPort == null) && (flowPathMatch != null)) {
+ matchSrcTcpUdpPort = flowPathMatch.srcTcpUdpPort();
+ }
+ if (matchSrcTcpUdpPort != null) {
+ match.setTransportSource(matchSrcTcpUdpPort);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
+ }
+
+ // Match the Destination TCP/UDP port
+ Short matchDstTcpUdpPort = flowEntryMatch.dstTcpUdpPort();
+ if ((matchDstTcpUdpPort == null) && (flowPathMatch != null)) {
+ matchDstTcpUdpPort = flowPathMatch.dstTcpUdpPort();
+ }
+ if (matchDstTcpUdpPort != null) {
+ match.setTransportDestination(matchDstTcpUdpPort);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_DST);
+ }
+
//
// Fetch the actions
//
- // TODO: For now we support only the "OUTPUT" actions.
+ Short actionOutputPort = null;
+ List<OFAction> openFlowActions = new ArrayList<OFAction>();
+ int actionsLen = 0;
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
//
- fm.setOutPort(OFPort.OFPP_NONE.getValue());
- List<OFAction> actions = new ArrayList<OFAction>();
- ArrayList<FlowEntryAction> flowEntryActions =
- flowEntry.flowEntryActions();
- for (FlowEntryAction flowEntryAction : flowEntryActions) {
- FlowEntryAction.ActionOutput actionOutput =
- flowEntryAction.actionOutput();
+ for (FlowEntryAction action : flowEntryActions.actions()) {
+ ActionOutput actionOutput = action.actionOutput();
+ ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
+ ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
+ ActionStripVlan actionStripVlan = action.actionStripVlan();
+ ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
+ ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
+ ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
+ ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
+ ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
+ ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
+ ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
+ ActionEnqueue actionEnqueue = action.actionEnqueue();
+
if (actionOutput != null) {
- short actionOutputPort = actionOutput.port().value();
- OFActionOutput action = new OFActionOutput();
+ actionOutputPort = actionOutput.port().value();
// XXX: The max length is hard-coded for now
- action.setMaxLength((short)0xffff);
- action.setPort(actionOutputPort);
- actions.add(action);
- if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
- (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
- fm.setOutPort(actionOutputPort);
+ OFActionOutput ofa =
+ new OFActionOutput(actionOutput.port().value(),
+ (short)0xffff);
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetVlanId != null) {
+ OFActionVirtualLanIdentifier ofa =
+ new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetVlanPriority != null) {
+ OFActionVirtualLanPriorityCodePoint ofa =
+ new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionStripVlan != null) {
+ if (actionStripVlan.stripVlan() == true) {
+ OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
}
}
+
+ if (actionSetEthernetSrcAddr != null) {
+ OFActionDataLayerSource ofa =
+ new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetEthernetDstAddr != null) {
+ OFActionDataLayerDestination ofa =
+ new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIPv4SrcAddr != null) {
+ OFActionNetworkLayerSource ofa =
+ new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIPv4DstAddr != null) {
+ OFActionNetworkLayerDestination ofa =
+ new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetIpToS != null) {
+ OFActionNetworkTypeOfService ofa =
+ new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetTcpUdpSrcPort != null) {
+ OFActionTransportLayerSource ofa =
+ new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionSetTcpUdpDstPort != null) {
+ OFActionTransportLayerDestination ofa =
+ new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
+
+ if (actionEnqueue != null) {
+ OFActionEnqueue ofa =
+ new OFActionEnqueue(actionEnqueue.port().value(),
+ actionEnqueue.queueId());
+ openFlowActions.add(ofa);
+ actionsLen += ofa.getLength();
+ }
}
fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
@@ -1721,8 +2217,14 @@
.setCookie(cookie)
.setCommand(flowModCommand)
.setMatch(match)
- .setActions(actions)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+ .setActions(openFlowActions)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
+ fm.setOutPort(OFPort.OFPP_NONE.getValue());
+ if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
+ (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
+ if (actionOutputPort != null)
+ fm.setOutPort(actionOutputPort);
+ }
//
// TODO: Set the following flag
@@ -1816,18 +2318,19 @@
* @return the stored shortest-path flow on success, otherwise null.
*/
@Override
- public FlowPath measurementStorePathFlow(FlowPath flowPath) {
+ public synchronized FlowPath measurementStorePathFlow(FlowPath flowPath) {
//
// Prepare the Shortest Path computation if the first Flow Path
//
if (measurementStoredPaths.isEmpty())
- topoRouteService.prepareShortestPathTopo();
+ measurementShortestPathTopo = topoRouteService.prepareShortestPathTopo();
//
// Compute the Shortest Path
//
DataPath dataPath =
- topoRouteService.getTopoShortestPath(flowPath.dataPath().srcPort(),
+ topoRouteService.getTopoShortestPath(measurementShortestPathTopo,
+ flowPath.dataPath().srcPort(),
flowPath.dataPath().dstPort());
if (dataPath == null) {
// We need the DataPath to populate the Network MAP
@@ -1835,6 +2338,7 @@
dataPath.setSrcPort(flowPath.dataPath().srcPort());
dataPath.setDstPort(flowPath.dataPath().dstPort());
}
+ dataPath.applyFlowPathFlags(flowPath.flowPathFlags());
//
// Set the incoming port matching and the outgoing port output
@@ -1847,14 +2351,10 @@
flowEntryMatch.enableInPort(flowEntry.inPort());
// Set the outgoing port output action
- ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
- if (flowEntryActions == null) {
- flowEntryActions = new ArrayList<FlowEntryAction>();
- flowEntry.setFlowEntryActions(flowEntryActions);
- }
+ FlowEntryActions flowEntryActions = flowEntry.flowEntryActions();
FlowEntryAction flowEntryAction = new FlowEntryAction();
flowEntryAction.setActionOutput(flowEntry.outPort());
- flowEntryActions.add(flowEntryAction);
+ flowEntryActions.addAction(flowEntryAction);
}
//
@@ -1863,14 +2363,18 @@
FlowPath computedFlowPath = new FlowPath();
computedFlowPath.setFlowId(new FlowId(flowPath.flowId().value()));
computedFlowPath.setInstallerId(new CallerId(flowPath.installerId().value()));
+ computedFlowPath.setFlowPathFlags(new FlowPathFlags(flowPath.flowPathFlags().flags()));
computedFlowPath.setDataPath(dataPath);
computedFlowPath.setFlowEntryMatch(new FlowEntryMatch(flowPath.flowEntryMatch()));
//
- // Add the computed Flow Path the the internal storage
+ // Add the computed Flow Path to the internal storage
//
measurementStoredPaths.add(computedFlowPath);
+ log.debug("Measurement storing path {}",
+ computedFlowPath.flowId().toString());
+
return (computedFlowPath);
}
@@ -1883,29 +2387,48 @@
*/
@Override
public boolean measurementInstallPaths(Integer numThreads) {
- List<Thread> threads = new LinkedList<Thread>();
+ // Create a copy of the Flow Paths to install
+ final ConcurrentLinkedQueue<FlowPath> measurementProcessingPaths =
+ new ConcurrentLinkedQueue<FlowPath>(measurementStoredPaths);
- // Create a copy of the paths to install
- measurementProcessingPaths = new LinkedList<FlowPath>(measurementStoredPaths);
+ /**
+ * A Thread-wrapper class for executing the threads and collecting
+ * the measurement data.
+ */
+ class MyThread extends Thread {
+ public long[] execTime = new long[2000];
+ public int samples = 0;
+ public int threadId = -1;
+ @Override
+ public void run() {
+ while (true) {
+ FlowPath flowPath = measurementProcessingPaths.poll();
+ if (flowPath == null)
+ return;
+ // Install the Flow Path
+ FlowId flowId = new FlowId();
+ String dataPathSummaryStr =
+ flowPath.dataPath().dataPathSummary();
+ long startTime = System.nanoTime();
+ addFlow(flowPath, flowId, dataPathSummaryStr);
+ long endTime = System.nanoTime();
+ execTime[samples] = endTime - startTime;
+ samples++;
+ }
+ }
+ };
+
+ List<MyThread> threads = new LinkedList<MyThread>();
+
+ log.debug("Measurement Installing {} flows",
+ measurementProcessingPaths.size());
//
// Create the threads to install the Flow Paths
//
for (int i = 0; i < numThreads; i++) {
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- while (true) {
- FlowPath flowPath = measurementPollFirstFlowPath();
- if (flowPath == null)
- return;
- // Install the Flow Path
- FlowId flowId = new FlowId();
- String dataPathSummaryStr =
- flowPath.dataPath().dataPathSummary();
- addFlow(flowPath, flowId, dataPathSummaryStr);
- }
- }}, "Measurement Add Flow Path");
+ MyThread thread = new MyThread();
+ thread.threadId = i;
threads.add(thread);
}
@@ -1918,14 +2441,29 @@
thread.start();
}
- //
- // Wait until the end of processing time
- //
- while (measurementEndTimeProcessingPaths == 0) {
+ // Wait for all threads to complete
+ for (Thread thread : threads) {
try {
- Thread.sleep(100);
+ thread.join();
} catch (InterruptedException e) {
- // Continue waiting
+ log.debug("Exception waiting for a thread to install a Flow Path: ", e);
+ }
+ }
+
+ // Record the end of processing
+ measurementEndTimeProcessingPaths = System.nanoTime();
+
+ //
+ // Prepare the string with measurement data per each Flow Path
+ // installation.
+ // The string is multiple lines: one line per Flow Path installation:
+ // ThreadAndTimePerFlow <ThreadId> <TotalThreads> <Time(ns)>
+ //
+ measurementPerFlowStr = new String();
+ String eol = System.getProperty("line.separator");
+ for (MyThread thread : threads) {
+ for (int i = 0; i < thread.samples; i++) {
+ measurementPerFlowStr += "ThreadAndTimePerFlow " + thread.threadId + " " + numThreads + " " + thread.execTime[i] + eol;
}
}
@@ -1945,21 +2483,14 @@
}
/**
- * Get a Flow Path that needs to be installed for measurement purpose.
+ * Get the measurement install time per Flow.
*
- * If there is no next Flow Path to install, the end time measurement
- * is recorded.
- *
- * @return the next Flow Path to install if exists, otherwise null.
+ * @return a multi-line string with the following format per line:
+ * ThreadAndTimePerFlow <ThreadId> <TotalThreads> <Time(ns)>
*/
- private synchronized FlowPath measurementPollFirstFlowPath() {
- FlowPath flowPath = measurementProcessingPaths.pollFirst();
-
- // Record the end of processing, if the first call
- if ((flowPath == null) && (measurementEndTimeProcessingPaths == 0))
- measurementEndTimeProcessingPaths = System.nanoTime();
-
- return flowPath;
+ @Override
+ public String measurementGetPerFlowInstallTime() {
+ return new String(measurementPerFlowStr);
}
/**
@@ -1970,11 +2501,11 @@
@Override
public boolean measurementClearAllPaths() {
measurementStoredPaths.clear();
- topoRouteService.dropShortestPathTopo();
+ topoRouteService.dropShortestPathTopo(measurementShortestPathTopo);
measurementStartTimeProcessingPaths = 0;
measurementEndTimeProcessingPaths = 0;
+ measurementPerFlowStr = new String();
return true;
}
-
}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
similarity index 88%
rename from src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
index 5e0db35..ba9cd1b 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowService.java
@@ -1,13 +1,13 @@
-package net.floodlightcontroller.flowcache;
+package net.onrc.onos.ofcontroller.flowmanager;
import java.util.ArrayList;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.util.CallerId;
-import net.floodlightcontroller.util.DataPathEndpoints;
-import net.floodlightcontroller.util.FlowId;
-import net.floodlightcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.util.CallerId;
+import net.onrc.onos.ofcontroller.util.DataPathEndpoints;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
/**
* @short Interface for providing Flow Service to other modules.
@@ -145,6 +145,14 @@
public Long measurementGetInstallPathsTimeNsec();
/**
+ * Get the measurement install time per Flow.
+ *
+ * @return a multi-line string with the following format per line:
+ * ThreadAndTimePerFlow <ThreadId> <TotalThreads> <Time(ns)>
+ */
+ public String measurementGetPerFlowInstallTime();
+
+ /**
* Clear the path flows stored for measurement purpose.
*
* @return true on success, otherwise false.
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddFlowResource.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddFlowResource.java
index e266e2e..2800305 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/AddFlowResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddFlowResource.java
@@ -1,15 +1,14 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import java.io.IOException;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
-import net.floodlightcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.JsonMappingException;
-import org.codehaus.jackson.map.ObjectMapper;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/AddShortestPathFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddShortestPathFlowResource.java
similarity index 84%
rename from src/main/java/net/floodlightcontroller/flowcache/web/AddShortestPathFlowResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddShortestPathFlowResource.java
index 3c5bcd8..2a75c6a 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/AddShortestPathFlowResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/AddShortestPathFlowResource.java
@@ -1,13 +1,12 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import java.io.IOException;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
-import net.floodlightcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
import org.codehaus.jackson.JsonGenerationException;
-import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.restlet.resource.Post;
@@ -54,10 +53,11 @@
if (flowPath != null) {
FlowPath addedFlowPath =
flowService.addAndMaintainShortestPathFlow(flowPath);
- if (addedFlowPath == null)
+ if (addedFlowPath == null) {
result = new FlowId(); // Error: Return empty Flow Id
- else
+ } else {
result = addedFlowPath.flowId();
+ }
}
return result;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/ClearFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/ClearFlowResource.java
similarity index 84%
rename from src/main/java/net/floodlightcontroller/flowcache/web/ClearFlowResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/ClearFlowResource.java
index 7f3b589..1daa2ab 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/ClearFlowResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/ClearFlowResource.java
@@ -1,9 +1,8 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.FlowId;
-import org.openflow.util.HexString;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/DatapathSummarySerializer.java
similarity index 97%
rename from src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/DatapathSummarySerializer.java
index b780e5c..9133077 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/DatapathSummarySerializer.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import java.io.IOException;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/DeleteFlowResource.java
similarity index 84%
rename from src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/DeleteFlowResource.java
index ed6f0f7..393ff44 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/DeleteFlowResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/DeleteFlowResource.java
@@ -1,9 +1,8 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.FlowId;
-import org.openflow.util.HexString;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/FlowWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/FlowWebRoutable.java
similarity index 90%
rename from src/main/java/net/floodlightcontroller/flowcache/web/FlowWebRoutable.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/FlowWebRoutable.java
index 9fa5e63..954c84d 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/FlowWebRoutable.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/FlowWebRoutable.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import net.floodlightcontroller.restserver.RestletRoutable;
@@ -25,6 +25,7 @@
router.attach("/measurement-store-path/json", MeasurementStorePathFlowResource.class);
router.attach("/measurement-install-paths/{num-threads}/json", MeasurementInstallPathsFlowResource.class);
router.attach("/measurement-get-install-paths-time-nsec/json", MeasurementGetInstallPathsTimeNsecFlowResource.class);
+ router.attach("/measurement-get-per-flow-install-time/json", MeasurementGetPerFlowInstallTimeFlowResource.class);
router.attach("/measurement-clear-all-paths/json", MeasurementClearAllPathsFlowResource.class);
return router;
}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsByEndpointsResource.java
similarity index 81%
rename from src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsByEndpointsResource.java
index 34d79c8..6142096 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByEndpointsResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsByEndpointsResource.java
@@ -1,13 +1,13 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import java.util.ArrayList;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.DataPathEndpoints;
-import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.FlowPath;
-import net.floodlightcontroller.util.Port;
-import net.floodlightcontroller.util.SwitchPort;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.DataPathEndpoints;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByInstallerIdResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsByInstallerIdResource.java
similarity index 81%
rename from src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByInstallerIdResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsByInstallerIdResource.java
index e3043dc..498108f 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsByInstallerIdResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsByInstallerIdResource.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import java.util.ArrayList;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.CallerId;
-import net.floodlightcontroller.util.DataPathEndpoints;
-import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.FlowPath;
-import net.floodlightcontroller.util.Port;
-import net.floodlightcontroller.util.SwitchPort;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.CallerId;
+import net.onrc.onos.ofcontroller.util.DataPathEndpoints;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsResource.java
similarity index 83%
rename from src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsResource.java
index 92317cf..61eaf27 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetAllFlowsResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetAllFlowsResource.java
@@ -1,9 +1,9 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import java.util.ArrayList;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.FlowPath;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetFlowByIdResource.java
similarity index 80%
rename from src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetFlowByIdResource.java
index 85d5b7e..48e7369 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetFlowByIdResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetFlowByIdResource.java
@@ -1,8 +1,8 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
-import net.floodlightcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetSummaryFlowsResource.java
similarity index 81%
rename from src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetSummaryFlowsResource.java
index 5f63222..4b3c00f 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/GetSummaryFlowsResource.java
@@ -1,11 +1,10 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import java.util.ArrayList;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
-import net.floodlightcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.FlowId;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/MeasurementClearAllPathsFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementClearAllPathsFlowResource.java
similarity index 81%
rename from src/main/java/net/floodlightcontroller/flowcache/web/MeasurementClearAllPathsFlowResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementClearAllPathsFlowResource.java
index f69180d..07d9fb2 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/MeasurementClearAllPathsFlowResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementClearAllPathsFlowResource.java
@@ -1,9 +1,7 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
-import org.openflow.util.HexString;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/MeasurementGetInstallPathsTimeNsecFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementGetInstallPathsTimeNsecFlowResource.java
similarity index 82%
rename from src/main/java/net/floodlightcontroller/flowcache/web/MeasurementGetInstallPathsTimeNsecFlowResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementGetInstallPathsTimeNsecFlowResource.java
index 3dc1d08..467afca 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/MeasurementGetInstallPathsTimeNsecFlowResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementGetInstallPathsTimeNsecFlowResource.java
@@ -1,9 +1,7 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
-import org.openflow.util.HexString;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementGetPerFlowInstallTimeFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementGetPerFlowInstallTimeFlowResource.java
new file mode 100644
index 0000000..92d84ab
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementGetPerFlowInstallTimeFlowResource.java
@@ -0,0 +1,35 @@
+package net.onrc.onos.ofcontroller.flowmanager.web;
+
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MeasurementGetPerFlowInstallTimeFlowResource extends ServerResource {
+ protected static Logger log = LoggerFactory.getLogger(MeasurementGetPerFlowInstallTimeFlowResource.class);
+
+ @Get("json")
+ public String retrieve() {
+ String result = null;
+
+ IFlowService flowService =
+ (IFlowService)getContext().getAttributes().
+ get(IFlowService.class.getCanonicalName());
+
+ if (flowService == null) {
+ log.debug("ONOS Flow Service not found");
+ return result;
+ }
+
+ // Extract the arguments
+
+ // Process the request
+ result = flowService.measurementGetPerFlowInstallTime();
+
+ log.debug("Measurement Get Install Paths Time (nsec): " + result);
+
+ return result;
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/MeasurementInstallPathsFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementInstallPathsFlowResource.java
similarity index 83%
rename from src/main/java/net/floodlightcontroller/flowcache/web/MeasurementInstallPathsFlowResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementInstallPathsFlowResource.java
index 1bba4b1..074dfb4 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/MeasurementInstallPathsFlowResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementInstallPathsFlowResource.java
@@ -1,9 +1,7 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
-import org.openflow.util.HexString;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/MeasurementStorePathFlowResource.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementStorePathFlowResource.java
similarity index 86%
rename from src/main/java/net/floodlightcontroller/flowcache/web/MeasurementStorePathFlowResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementStorePathFlowResource.java
index e68ceb7..0f23663 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/MeasurementStorePathFlowResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/web/MeasurementStorePathFlowResource.java
@@ -1,13 +1,12 @@
-package net.floodlightcontroller.flowcache.web;
+package net.onrc.onos.ofcontroller.flowmanager.web;
import java.io.IOException;
-import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowId;
-import net.floodlightcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
import org.codehaus.jackson.JsonGenerationException;
-import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.restlet.resource.Post;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscovery.java
similarity index 96%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscovery.java
index 1efe015..6113ea8 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscovery.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.linkdiscovery;
+package net.onrc.onos.ofcontroller.linkdiscovery;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.ser.std.ToStringSerializer;
@@ -8,6 +8,7 @@
@JsonSerialize(using=ToStringSerializer.class)
public enum UpdateOperation {
+ LINK_ADDED("Link Added"), // Operation Added by ONOS
LINK_UPDATED("Link Updated"),
LINK_REMOVED("Link Removed"),
SWITCH_UPDATED("Switch Updated"),
@@ -106,6 +107,7 @@
@Override
public String toString() {
switch (operation) {
+ case LINK_ADDED:
case LINK_REMOVED:
case LINK_UPDATED:
return "LDUpdate [operation=" + operation +
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryListener.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryListener.java
similarity index 94%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryListener.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryListener.java
index 35779a2..9ca114f 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryListener.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryListener.java
@@ -15,7 +15,7 @@
* under the License.
**/
-package net.floodlightcontroller.linkdiscovery;
+package net.onrc.onos.ofcontroller.linkdiscovery;
public interface ILinkDiscoveryListener extends ILinkDiscovery{
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryService.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryService.java
similarity index 97%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryService.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryService.java
index 4145592..99438ab 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/ILinkDiscoveryService.java
@@ -15,7 +15,7 @@
* under the License.
**/
-package net.floodlightcontroller.linkdiscovery;
+package net.onrc.onos.ofcontroller.linkdiscovery;
import java.util.Map;
import java.util.Set;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/LinkInfo.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/LinkInfo.java
similarity index 97%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/LinkInfo.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/LinkInfo.java
index 9c0dd1a..825b0a2 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/LinkInfo.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/LinkInfo.java
@@ -13,9 +13,9 @@
* under the License.
**/
-package net.floodlightcontroller.linkdiscovery;
+package net.onrc.onos.ofcontroller.linkdiscovery;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkType;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LinkType;
import org.openflow.protocol.OFPhysicalPort.OFPortState;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/README b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/README
new file mode 100644
index 0000000..3cec58d
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/README
@@ -0,0 +1,8 @@
+Note about this directory
+=========================
+
+This directory contains link discovery manager and it's related module derived from Flood Light v0.9.0.
+Many of the code is unmodified from it's original state, but they had to be moved due to package visibility etc.
+
+Compare with floodlight's linkdiscovery directory to see what was modified from it's original code.
+
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java
similarity index 95%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java
index d57e987..696c63e 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.linkdiscovery.internal;
+package net.onrc.onos.ofcontroller.linkdiscovery.internal;
import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java
similarity index 96%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java
index 98796ed..5d2e955 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.linkdiscovery.internal;
+package net.onrc.onos.ofcontroller.linkdiscovery.internal;
import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java
similarity index 94%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java
index 001942b..d6afd7a 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.linkdiscovery.internal;
+package net.onrc.onos.ofcontroller.linkdiscovery.internal;
import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
import net.floodlightcontroller.core.web.serializers.IPv4Serializer;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
similarity index 95%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index 634f7eb..f4e4223 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -15,7 +15,7 @@
* under the License.
**/
-package net.floodlightcontroller.linkdiscovery.internal;
+package net.onrc.onos.ofcontroller.linkdiscovery.internal;
import java.io.IOException;
import java.net.InetAddress;
@@ -44,7 +44,6 @@
import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.IHAListener;
import net.floodlightcontroller.core.IInfoProvider;
-import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitchListener;
@@ -57,15 +56,6 @@
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.core.util.SingletonTask;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkType;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.SwitchType;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.UpdateOperation;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.floodlightcontroller.linkdiscovery.LinkInfo;
-import net.floodlightcontroller.linkdiscovery.web.LinkDiscoveryWebRoutable;
import net.floodlightcontroller.packet.BSN;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;
@@ -82,6 +72,16 @@
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.util.EventHistory;
import net.floodlightcontroller.util.EventHistory.EvAction;
+import net.onrc.onos.ofcontroller.core.IOnosRemoteSwitch;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LinkType;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.SwitchType;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.UpdateOperation;
+import net.onrc.onos.ofcontroller.linkdiscovery.web.LinkDiscoveryWebRoutable;
import net.onrc.onos.registry.controller.IControllerRegistryService;
import org.openflow.protocol.OFMessage;
@@ -127,12 +127,6 @@
IStorageSourceListener, ILinkDiscoveryService,
IFloodlightModule, IInfoProvider, IHAListener {
protected static Logger log = LoggerFactory.getLogger(LinkDiscoveryManager.class);
-
- protected enum NetworkMapOperation {
- NONE,
- INSERT,
- UPDATE
- }
// Names of table/fields for links in the storage API
private static final String LINK_TABLE_NAME = "controller_link";
@@ -152,8 +146,10 @@
protected IStorageSourceService storageSource;
protected IThreadPoolService threadPool;
protected IRestApiService restApi;
+ // Registry Service for ONOS
protected IControllerRegistryService registryService;
+
// LLDP and BDDP fields
private static final byte[] LLDP_STANDARD_DST_MAC_STRING =
HexString.fromHexString("01:80:c2:00:00:0e");
@@ -161,8 +157,8 @@
private static final long LINK_LOCAL_VALUE = 0x0180c2000000L;
// BigSwitch OUI is 5C:16:C7, so 5D:16:C7 is the multicast version
- private static final String LLDP_BSN_DST_MAC_STRING = "5d:16:c7:00:00:01";
- //private static final String LLDP_BSN_DST_MAC_STRING = "ff:ff:ff:ff:ff:ff";
+ // private static final String LLDP_BSN_DST_MAC_STRING = "5d:16:c7:00:00:01";
+ private static final String LLDP_BSN_DST_MAC_STRING = "ff:ff:ff:ff:ff:ff";
// Direction TLVs are used to indicate if the LLDPs were sent
@@ -198,20 +194,6 @@
protected ReentrantReadWriteLock lock;
int lldpTimeCount = 0;
- // Storage
-
- ThreadLocal<LinkStorageImpl> store = new ThreadLocal<LinkStorageImpl>() {
- @Override
- protected LinkStorageImpl initialValue() {
- LinkStorageImpl swStore = new LinkStorageImpl();
- //TODO: Get the file path from global properties
- swStore.init("/tmp/cassandra.titan");
- return swStore;
- }
- };
- protected LinkStorageImpl linkStore = store.get();
- // protected SwitchStorageImpl swStore;
-
/**
* Flag to indicate if automatic port fast is enabled or not.
* Default is set to false -- Initialized in the init method as well.
@@ -220,10 +202,10 @@
/**
* Map of remote switches that are not connected to this controller. This
- * is used to learn remote switches in a distributed controller.
+ * is used to learn remote switches in a distributed controller ONOS.
*/
- protected Map<Long, IOFSwitch> remoteSwitches;
-
+ protected Map<Long, IOnosRemoteSwitch> remoteSwitches;
+
/**
* Map from link to the most recent time it was verified functioning
*/
@@ -534,10 +516,10 @@
}
/**
- * Learn remote switches when running as a distributed controller
+ * Learn remote switches when running as a distributed controller ONOS
*/
protected IOFSwitch addRemoteSwitch(long sw, short port) {
- IOFSwitch remotesw = null;
+ IOnosRemoteSwitch remotesw = null;
// add a switch if we have not seen it before
remotesw = remoteSwitches.get(sw);
@@ -825,6 +807,7 @@
ByteBuffer dpidBB = ByteBuffer.wrap(lldptlv.getValue());
remoteSwitch = floodlightProvider.getSwitches().get(dpidBB.getLong(4));
if (remoteSwitch == null) {
+ // Added by ONOS
// floodlight LLDP coming from a remote switch connected to a different controller
// add it to our cache of unconnected remote switches
remoteSwitch = addRemoteSwitch(dpidBB.getLong(4), remotePort);
@@ -857,7 +840,7 @@
log.trace("Getting BDDP packets from a different controller" +
"and letting it go through normal processing chain.");
}
- //XXX Fix the BDDP broadcast issue
+ //XXX ONOS: Fix the BDDP broadcast issue
//return Command.CONTINUE;
return Command.STOP;
}
@@ -978,7 +961,6 @@
if (bsn.getPayload() instanceof LLDP == false)
return Command.CONTINUE;
return handleLldp((LLDP) bsn.getPayload(), sw, pi, false, cntx);
- //return Command.STOP;
} else if (eth.getEtherType() == Ethernet.TYPE_LLDP) {
return handleLldp((LLDP) eth.getPayload(), sw, pi, true, cntx);
} else if (eth.getEtherType() < 1500) {
@@ -1028,7 +1010,6 @@
NodePortTuple srcNpt, dstNpt;
boolean linkChanged = false;
- NetworkMapOperation operation = NetworkMapOperation.NONE;
lock.writeLock().lock();
try {
@@ -1076,11 +1057,8 @@
writeLinkToStorage(lt, newInfo);
- // Write link to network map
- operation = NetworkMapOperation.INSERT;
- //linkStore.update(lt, newInfo, DM_OPERATION.INSERT);
-
- updateOperation = UpdateOperation.LINK_UPDATED;
+ // ONOS: Distinguish added event separately from updated event
+ updateOperation = UpdateOperation.LINK_ADDED;
linkChanged = true;
// Add to event history
@@ -1136,10 +1114,6 @@
// they weren't set to null in the previous block of code.
writeLinkToStorage(lt, newInfo);
- // Write link to network map
- operation = NetworkMapOperation.UPDATE;
- //linkStore.update(lt, newInfo, DM_OPERATION.UPDATE);
-
if (linkChanged) {
updateOperation = getUpdateOperation(newInfo.getSrcPortState(),
newInfo.getDstPortState());
@@ -1168,18 +1142,6 @@
} finally {
lock.writeLock().unlock();
}
-
- switch (operation){
- case INSERT:
- linkStore.update(lt, newInfo, DM_OPERATION.INSERT);
- break;
- case UPDATE:
- linkStore.update(lt, newInfo, DM_OPERATION.UPDATE);
- break;
- case NONE:
- default:
- break;
- }
return linkChanged;
}
@@ -1193,14 +1155,6 @@
* @param links The List of @LinkTuple to delete.
*/
protected void deleteLinks(List<Link> links, String reason) {
- deleteLinks(links, reason, Boolean.TRUE);
- }
-
- /**
- * Removes links from memory and storage.
- * @param links The List of @LinkTuple to delete.
- */
- protected void deleteLinks(List<Link> links, String reason, Boolean hasControl) {
NodePortTuple srcNpt, dstNpt;
lock.writeLock().lock();
@@ -1247,10 +1201,6 @@
// remove link from storage.
removeLinkFromStorage(lt);
- // remote link from network map
- linkStore.update(lt, DM_OPERATION.DELETE);
-
-
// TODO Whenever link is removed, it has to checked if
// the switchports must be added to quarantine.
@@ -1274,8 +1224,8 @@
IOFSwitch iofSwitch = floodlightProvider.getSwitches().get(sw);
if (iofSwitch == null) return Command.CONTINUE;
-
- // If we do not control this switch, then we should not process its port status messages
+
+ // ONOS: If we do not control this switch, then we should not process its port status messages
if (!registryService.hasControl(iofSwitch.getId())) return Command.CONTINUE;
if (log.isTraceEnabled()) {
@@ -1301,7 +1251,6 @@
((byte)OFPortReason.OFPPR_MODIFY.ordinal() ==
ps.getReason() && !portEnabled(ps.getDesc()))) {
deleteLinksOnPort(npt, "Port Status Changed");
- //swStore.deletePort(HexString.toHexString(npt.getNodeId()), npt.getPortId());
LDUpdate update = new LDUpdate(sw, port, UpdateOperation.PORT_DOWN);
updates.add(update);
linkDeleted = true;
@@ -1344,10 +1293,6 @@
getLinkType(lt, linkInfo),
operation));
writeLinkToStorage(lt, linkInfo);
-
- // Write the changed link to the network map
- linkStore.update(lt, linkInfo, DM_OPERATION.UPDATE);
-
linkInfoChanged = true;
}
}
@@ -1451,11 +1396,7 @@
}
// add all tuples with an endpoint on this switch to erase list
eraseList.addAll(switchLinks.get(sw));
-
- // We can get called to delete links when we lose mastership. To avoid clearing the network map in that case,
- // figure out if we have control of the switch
- boolean hasControl = registryService.hasControl(sw);
- deleteLinks(eraseList, "Switch Removed", hasControl);
+ deleteLinks(eraseList, "Switch Removed");
// Send a switch removed update
LDUpdate update = new LDUpdate(sw, null, UpdateOperation.SWITCH_REMOVED);
@@ -1885,6 +1826,7 @@
l.add(IStorageSourceService.class);
l.add(IThreadPoolService.class);
l.add(IRestApiService.class);
+ // Added by ONOS
l.add(IControllerRegistryService.class);
return l;
}
@@ -1896,6 +1838,7 @@
storageSource = context.getServiceImpl(IStorageSourceService.class);
threadPool = context.getServiceImpl(IThreadPoolService.class);
restApi = context.getServiceImpl(IRestApiService.class);
+ // Added by ONOS
registryService = context.getServiceImpl(IControllerRegistryService.class);
// Set the autoportfast feature to false.
@@ -1913,7 +1856,8 @@
this.switchLinks = new HashMap<Long, Set<Link>>();
this.quarantineQueue = new LinkedBlockingQueue<NodePortTuple>();
this.maintenanceQueue = new LinkedBlockingQueue<NodePortTuple>();
- this.remoteSwitches = new HashMap<Long, IOFSwitch>();
+ // Added by ONOS
+ this.remoteSwitches = new HashMap<Long, IOnosRemoteSwitch>();
this.evHistTopologySwitch =
new EventHistory<EventHistoryTopologySwitch>("Topology: Switch");
@@ -1964,7 +1908,7 @@
log.error("Error in installing listener for " +
"switch table {}", SWITCH_CONFIG_TABLE_NAME);
}
-
+
ScheduledExecutorService ses = threadPool.getScheduledExecutor();
// To be started by the first switch connection
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/AutoPortFast.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/AutoPortFast.java
similarity index 89%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/web/AutoPortFast.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/AutoPortFast.java
index 8f4f4ad..29dc890 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/AutoPortFast.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/AutoPortFast.java
@@ -1,6 +1,6 @@
-package net.floodlightcontroller.linkdiscovery.web;
+package net.onrc.onos.ofcontroller.linkdiscovery.web;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import org.restlet.data.Status;
import org.restlet.resource.Get;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java
similarity index 92%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java
index 3990fba..8eae558 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkDiscoveryWebRoutable.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.linkdiscovery.web;
+package net.onrc.onos.ofcontroller.linkdiscovery.web;
import net.floodlightcontroller.restserver.RestletRoutable;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkWithType.java
similarity index 94%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkWithType.java
index 893e4ad..3e5a5e7 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinkWithType.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.linkdiscovery.web;
+package net.onrc.onos.ofcontroller.linkdiscovery.web;
import java.io.IOException;
@@ -9,8 +9,8 @@
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.openflow.util.HexString;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkType;
import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LinkType;
/**
* This class is both the datastructure and the serializer
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinksResource.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinksResource.java
similarity index 86%
rename from src/main/java/net/floodlightcontroller/linkdiscovery/web/LinksResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinksResource.java
index 4cad18e..c522a05 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinksResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/web/LinksResource.java
@@ -1,13 +1,13 @@
-package net.floodlightcontroller.linkdiscovery.web;
+package net.onrc.onos.ofcontroller.linkdiscovery.web;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.floodlightcontroller.linkdiscovery.LinkInfo;
import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpTableEntry.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpTableEntry.java
new file mode 100644
index 0000000..5830cfd
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpTableEntry.java
@@ -0,0 +1,27 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+
+public class ArpTableEntry {
+
+ private byte[] macAddress;
+ private long timeLastSeen;
+
+ public ArpTableEntry(byte[] macAddress, long timeLastSeen) {
+ this.macAddress = macAddress;
+ this.timeLastSeen = timeLastSeen;
+ }
+
+ public byte[] getMacAddress() {
+ return macAddress;
+ }
+
+ public long getTimeLastSeen() {
+ return timeLastSeen;
+ }
+
+ public void setTimeLastSeen(long time){
+ //TODO thread safety issues?
+ timeLastSeen = time;
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/HostArpRequester.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/HostArpRequester.java
new file mode 100644
index 0000000..20c6a28
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/HostArpRequester.java
@@ -0,0 +1,28 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+import net.floodlightcontroller.packet.ARP;
+
+public class HostArpRequester implements IArpRequester {
+
+ private IProxyArpService arpService;
+ private ARP arpRequest;
+ private long dpid;
+ private short port;
+ //private long requestTime; //in ms
+
+ public HostArpRequester(IProxyArpService arpService, ARP arpRequest,
+ long dpid, short port) {
+
+ this.arpService = arpService;
+ this.arpRequest = arpRequest;
+ this.dpid = dpid;
+ this.port = port;
+ //this.requestTime = System.currentTimeMillis();
+ }
+
+ @Override
+ public void arpResponse(byte[] mac) {
+ arpService.sendArpReply(arpRequest, dpid, port, mac);
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpRequester.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpRequester.java
new file mode 100644
index 0000000..2a74944
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpRequester.java
@@ -0,0 +1,5 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+public interface IArpRequester {
+ public void arpResponse(byte[] mac);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
new file mode 100644
index 0000000..4632aba
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
@@ -0,0 +1,41 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+import java.net.InetAddress;
+
+import net.floodlightcontroller.packet.ARP;
+
+public interface IProxyArpService {
+
+ public final int ARP_REQUEST_TIMEOUT = 2000; //ms
+
+ /**
+ * Tell the IProxyArpService to send an ARP reply with the targetMac to
+ * the host on the specified switchport.
+ * @param arpRequest
+ * @param dpid
+ * @param port
+ * @param targetMac
+ */
+ public void sendArpReply(ARP arpRequest, long dpid, short port, byte[] targetMac);
+
+ /**
+ * Returns the mac address if there is a valid entry in the cache.
+ * Otherwise returns null.
+ * @param ipAddress
+ * @return
+ */
+ public byte[] getMacAddress(InetAddress ipAddress);
+
+ /**
+ * Tell the IProxyArpService to send an ARP request for the IP address.
+ * The request will be broadcast out all edge ports in the network.
+ * As an optimization, the IProxyArpService will first check its cache and
+ * return the MAC address if it is already known. If not, the request will be
+ * sent and the callback will be called when the MAC address is known
+ * (or if the request times out).
+ * @param ipAddress
+ * @param requester
+ * @return
+ */
+ public byte[] sendArpRequest(InetAddress ipAddress, IArpRequester requester);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
new file mode 100644
index 0000000..5c2a2b9
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -0,0 +1,453 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+
+import net.floodlightcontroller.core.FloodlightContext;
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFMessageListener;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.devicemanager.IDeviceService;
+import net.floodlightcontroller.packet.ARP;
+import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.topology.ITopologyService;
+import net.floodlightcontroller.util.MACAddress;
+
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFPacketIn;
+import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPort;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionOutput;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProxyArpManager implements IProxyArpService, IOFMessageListener {
+ private static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
+
+ private final long ARP_ENTRY_TIMEOUT = 600000; //ms (== 10 mins)
+
+ private final long ARP_REQUEST_TIMEOUT_THREAD_PERIOD = 60000; //ms (== 1 min)
+
+ protected IFloodlightProviderService floodlightProvider;
+ protected ITopologyService topology;
+ protected IDeviceService devices;
+
+ protected Map<InetAddress, ArpTableEntry> arpTable;
+
+ //protected ConcurrentHashMap<InetAddress, Set<ArpRequest>> arpRequests;
+ protected ConcurrentHashMap<InetAddress, ArpRequest> arpRequests;
+
+ private class ArpRequest {
+ private Set<IArpRequester> requesters;
+ private long requestTime;
+
+ public ArpRequest(){
+ this.requesters = new HashSet<IArpRequester>();
+ this.requestTime = System.currentTimeMillis();
+ }
+
+ public synchronized void addRequester(IArpRequester requester){
+ requestTime = System.currentTimeMillis();
+ requesters.add(requester);
+ }
+
+ public boolean isExpired(){
+ return (System.currentTimeMillis() - requestTime)
+ > IProxyArpService.ARP_REQUEST_TIMEOUT;
+ }
+
+ public synchronized void dispatchReply(byte[] replyMacAddress){
+ for (IArpRequester requester : requesters){
+ requester.arpResponse(replyMacAddress);
+ }
+ }
+ }
+
+ public ProxyArpManager(IFloodlightProviderService floodlightProvider,
+ ITopologyService topology, IDeviceService devices){
+ this.floodlightProvider = floodlightProvider;
+ this.topology = topology;
+ this.devices = devices;
+
+ arpTable = new HashMap<InetAddress, ArpTableEntry>();
+ //arpRequests = new ConcurrentHashMap<InetAddress, Set<ArpRequest>>();
+ arpRequests = new ConcurrentHashMap<InetAddress, ArpRequest>();
+
+ Timer arpRequestTimeoutTimer = new Timer();
+ arpRequestTimeoutTimer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ synchronized (arpRequests) {
+ log.debug("Current have {} outstanding requests",
+ arpRequests.size());
+
+ Iterator<Map.Entry<InetAddress, ArpRequest>> it
+ = arpRequests.entrySet().iterator();
+
+ while (it.hasNext()){
+ Map.Entry<InetAddress, ArpRequest> entry
+ = it.next();
+
+ if (entry.getValue().isExpired()){
+ log.debug("Cleaning expired ARP request for {}",
+ entry.getKey().getHostAddress());
+ it.remove();
+ }
+ }
+ }
+ }
+ }, 0, ARP_REQUEST_TIMEOUT_THREAD_PERIOD);
+ }
+
+ private void storeRequester(InetAddress address, IArpRequester requester) {
+ synchronized (arpRequests) {
+ if (arpRequests.get(address) == null) {
+ arpRequests.put(address, new ArpRequest());
+ }
+ ArpRequest request = arpRequests.get(address);
+
+ request.addRequester(requester);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "ProxyArpManager";
+ }
+
+ @Override
+ public boolean isCallbackOrderingPrereq(OFType type, String name) {
+ return false;
+ }
+
+ @Override
+ public boolean isCallbackOrderingPostreq(OFType type, String name) {
+ return false;
+ }
+
+ @Override
+ public Command receive(
+ IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
+
+ if (msg.getType() != OFType.PACKET_IN){
+ return Command.CONTINUE;
+ }
+
+ OFPacketIn pi = (OFPacketIn) msg;
+
+ Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
+ IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+
+ if (eth.getEtherType() == Ethernet.TYPE_ARP){
+ ARP arp = (ARP) eth.getPayload();
+
+ if (arp.getOpCode() == ARP.OP_REQUEST) {
+ handleArpRequest(sw, pi, arp);
+ }
+ else if (arp.getOpCode() == ARP.OP_REPLY) {
+ handleArpReply(sw, pi, arp);
+ }
+ }
+
+ //TODO should we propagate ARP or swallow it?
+ //Always propagate for now so DeviceManager can learn the host location
+ return Command.CONTINUE;
+ }
+
+ protected void handleArpRequest(IOFSwitch sw, OFPacketIn pi, ARP arp) {
+ log.debug("ARP request received for {}",
+ bytesToStringAddr(arp.getTargetProtocolAddress()));
+
+ byte[] mac = lookupArpTable(arp.getTargetProtocolAddress());
+
+ if (mac == null){
+ //Mac address is not in our arp table.
+
+ //TODO check what the DeviceManager thinks
+
+ //Record where the request came from so we know where to send the reply
+ InetAddress target;
+ try {
+ target = InetAddress.getByAddress(arp.getTargetProtocolAddress());
+ } catch (UnknownHostException e) {
+ log.debug("Invalid address in ARP request", e);
+ //return Command.CONTINUE; //Continue or stop?
+ return;
+ }
+
+ storeRequester(target, new HostArpRequester(this, arp, sw.getId(),
+ pi.getInPort()));
+
+ //Flood the request out edge ports
+ broadcastArpRequestOutEdge(pi.getPacketData(), sw.getId(), pi.getInPort());
+ }
+ else {
+ //We know the address, so send a reply
+ log.debug("Sending reply of {}", MACAddress.valueOf(mac).toString());
+ //sendArpReply(arp, pi, mac, sw);
+ sendArpReply(arp, sw.getId(), pi.getInPort(), mac);
+ }
+ }
+
+ protected void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp){
+ log.debug("ARP reply recieved for {}",
+ bytesToStringAddr(arp.getSenderProtocolAddress()));
+
+ updateArpTable(arp);
+
+ //See if anyone's waiting for this ARP reply
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByAddress(arp.getSenderProtocolAddress());
+ } catch (UnknownHostException e) {
+ return;
+ }
+
+ ArpRequest request = null;
+ synchronized (arpRequests) {
+ request = arpRequests.get(addr);
+ if (request != null) {
+ arpRequests.remove(addr);
+ }
+ }
+ if (request != null && !request.isExpired()) {
+ request.dispatchReply(arp.getSenderHardwareAddress());
+ }
+
+ /*
+ Set<ArpRequest> requests = arpRequests.get(addr);
+ if (requests != null){
+
+ synchronized (requests) {
+ for (ArpRequest request : requests) {
+ if (!request.isExpired()){
+ request.getRequester().arpResponse(
+ arp.getSenderHardwareAddress());
+ }
+ }
+ }
+ }*/
+ }
+
+ private synchronized byte[] lookupArpTable(byte[] ipAddress){
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByAddress(ipAddress);
+ } catch (UnknownHostException e) {
+ log.warn("Unable to create InetAddress", e);
+ return null;
+ }
+
+ ArpTableEntry arpEntry = arpTable.get(addr);
+
+ if (arpEntry == null){
+ return null;
+ }
+
+ if (System.currentTimeMillis() - arpEntry.getTimeLastSeen()
+ > ARP_ENTRY_TIMEOUT){
+ //Entry has timed out so we'll remove it and return null
+ arpTable.remove(addr);
+ return null;
+ }
+
+ return arpEntry.getMacAddress();
+ }
+
+ private synchronized void updateArpTable(ARP arp){
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByAddress(arp.getSenderProtocolAddress());
+ } catch (UnknownHostException e) {
+ log.warn("Unable to create InetAddress", e);
+ return;
+ }
+
+ ArpTableEntry arpEntry = arpTable.get(addr);
+
+ if (arpEntry != null
+ && arpEntry.getMacAddress() == arp.getSenderHardwareAddress()){
+ arpEntry.setTimeLastSeen(System.currentTimeMillis());
+ }
+ else {
+ arpTable.put(addr,
+ new ArpTableEntry(arp.getSenderHardwareAddress(),
+ System.currentTimeMillis()));
+ }
+ }
+
+ private void sendArpRequestForAddress(InetAddress ipAddress) {
+ byte[] zeroIpv4 = {0x0, 0x0, 0x0, 0x0};
+ byte[] zeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+ byte[] broadcastMac = {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+ (byte)0xff, (byte)0xff, (byte)0xff};
+
+ ARP arpRequest = new ARP();
+
+ arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
+ .setProtocolType(ARP.PROTO_TYPE_IP)
+ .setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
+ .setProtocolAddressLength((byte)4) //can't find the constant anywhere
+ .setOpCode(ARP.OP_REQUEST)
+ .setSenderHardwareAddress(zeroMac)
+ .setSenderProtocolAddress(zeroIpv4)
+ .setTargetHardwareAddress(zeroMac)
+ .setTargetProtocolAddress(ipAddress.getAddress());
+
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
+ .setSourceMACAddress(broadcastMac)
+ .setEtherType(Ethernet.TYPE_ARP)
+ .setPayload(arpRequest);
+
+ broadcastArpRequestOutEdge(eth.serialize(), 0, OFPort.OFPP_NONE.getValue());
+ }
+
+ //private void broadcastArpRequestOutEdge(OFPacketIn pi, long inSwitch, short inPort){
+ private void broadcastArpRequestOutEdge(byte[] arpRequest, long inSwitch, short inPort) {
+ for (IOFSwitch sw : floodlightProvider.getSwitches().values()){
+ Collection<Short> enabledPorts = sw.getEnabledPortNumbers();
+ Set<Short> linkPorts = topology.getPortsWithLinks(sw.getId());
+
+ if (linkPorts == null){
+ //I think this means the switch isn't known to topology yet.
+ //Maybe it only just joined.
+ continue;
+ }
+
+ OFPacketOut po = new OFPacketOut();
+ po.setInPort(OFPort.OFPP_NONE)
+ .setBufferId(-1)
+ .setPacketData(arpRequest);
+
+ List<OFAction> actions = new ArrayList<OFAction>();
+
+ for (short portNum : enabledPorts){
+ if (linkPorts.contains(portNum) ||
+ (sw.getId() == inSwitch && portNum == inPort)){
+ //If this port isn't an edge port or is the ingress port
+ //for the ARP, don't broadcast out it
+ continue;
+ }
+
+ actions.add(new OFActionOutput(portNum));
+ log.debug("Broadcasting out {}/{}", HexString.toHexString(sw.getId()), portNum);
+ }
+
+ po.setActions(actions);
+ short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
+ po.setActionsLength(actionsLength);
+ po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength
+ + arpRequest.length);
+
+ List<OFMessage> msgList = new ArrayList<OFMessage>();
+ msgList.add(po);
+
+ try {
+ sw.write(msgList, null);
+ sw.flush();
+ } catch (IOException e) {
+ log.error("Failure writing packet out to switch", e);
+ }
+ }
+ }
+
+ public void sendArpReply(ARP arpRequest, long dpid, short port, byte[] targetMac) {
+ //private void sendArpReply(ARP arpRequest, OFPacketIn pi, byte[] macRequested, IOFSwitch sw){
+ ARP arpReply = new ARP();
+ arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
+ .setProtocolType(ARP.PROTO_TYPE_IP)
+ .setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
+ .setProtocolAddressLength((byte)4) //can't find the constant anywhere
+ .setOpCode(ARP.OP_REPLY)
+ //.setSenderHardwareAddress(macRequested)
+ .setSenderHardwareAddress(targetMac)
+ .setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
+ .setTargetHardwareAddress(arpRequest.getSenderHardwareAddress())
+ .setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
+
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
+ //.setSourceMACAddress(macRequested)
+ .setSourceMACAddress(targetMac)
+ .setEtherType(Ethernet.TYPE_ARP)
+ .setPayload(arpReply);
+
+ List<OFAction> actions = new ArrayList<OFAction>();
+ //actions.add(new OFActionOutput(pi.getInPort()));
+ actions.add(new OFActionOutput(port));
+
+ OFPacketOut po = new OFPacketOut();
+ po.setInPort(OFPort.OFPP_NONE)
+ .setBufferId(-1)
+ .setPacketData(eth.serialize())
+ .setActions(actions)
+ .setActionsLength((short)OFActionOutput.MINIMUM_LENGTH)
+ .setLengthU(OFPacketOut.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH
+ + po.getPacketData().length);
+
+ List<OFMessage> msgList = new ArrayList<OFMessage>();
+ msgList.add(po);
+
+ IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
+
+ if (sw == null) {
+ return;
+ }
+
+ try {
+ log.debug("Sending ARP reply to {}/{}", HexString.toHexString(sw.getId()), port);
+ sw.write(msgList, null);
+ sw.flush();
+ } catch (IOException e) {
+ log.warn("Failure writing packet out to switch", e);
+ }
+ }
+
+ //TODO this should be put somewhere more central. I use it in BgpRoute as well.
+ //We need a HexString.toHexString() equivalent.
+ private String bytesToStringAddr(byte[] bytes) {
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByAddress(bytes);
+ } catch (UnknownHostException e) {
+ log.warn(" ", e);
+ return "";
+ }
+ if (addr == null) return "";
+ else return addr.getHostAddress();
+ }
+
+
+ public byte[] getMacAddress(InetAddress ipAddress) {
+ return lookupArpTable(ipAddress.getAddress());
+ }
+
+ public byte[] sendArpRequest(InetAddress ipAddress, IArpRequester requester) {
+ byte[] lookupMac;
+ if ((lookupMac = lookupArpTable(ipAddress.getAddress())) == null) {
+ return lookupMac;
+ }
+
+ sendArpRequestForAddress(ipAddress);
+
+ storeRequester(ipAddress, requester);
+
+ return null;
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java b/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
similarity index 78%
rename from src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
rename to src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
index 95a3b19..59e76ca 100644
--- a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.routing;
+package net.onrc.onos.ofcontroller.routing;
import java.util.ArrayList;
import java.util.Collection;
@@ -11,27 +11,21 @@
import java.util.Queue;
import java.util.Set;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
-import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.util.DataPath;
-import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.FlowEntry;
-import net.floodlightcontroller.util.Port;
-import net.floodlightcontroller.util.SwitchPort;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.GraphDBConnection.Transaction;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
import org.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.tinkerpop.blueprints.Direction;
-import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.pipes.PipeFunction;
import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
@@ -42,6 +36,10 @@
* of shortest paths.
*/
class Node {
+ /**
+ * A class for storing Link information for fast computation of shortest
+ * paths.
+ */
class Link {
public Node me; // The node this link originates from
public Node neighbor; // The neighbor node on the other side
@@ -92,83 +90,68 @@
}
};
-
-public class TopoRouteService implements IFloodlightModule, ITopoRouteService {
+/**
+ * A class for implementing Topology Route Service.
+ */
+public class TopoRouteService implements ITopoRouteService {
/** The logger. */
private static Logger log =
LoggerFactory.getLogger(TopoRouteService.class);
- GraphDBConnection conn;
+ protected GraphDBOperation op;
- //
- // Topology state for storing (on demand) Switch and Ports info for
- // fast access during the shortest path computation.
- // It is explicitly populated by method @ref prepareShortestPathTopo().
- // See the documentation for that method for details.
- //
- HashMap<Long, Node> shortestPathTopo;
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(ITopoRouteService.class);
- return l;
+ /**
+ * Default constructor.
+ */
+ public TopoRouteService() {
}
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService>
- getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- m.put(ITopoRouteService.class, this);
- return m;
+ /**
+ * Constructor for given database configuration file.
+ *
+ * @param config the database configuration file to use for
+ * the initialization.
+ */
+ public TopoRouteService(String config) {
+ this.init(config);
}
- @Override
- public Collection<Class<? extends IFloodlightService>>
- getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- // TODO: Add the appropriate dependencies
- // l.add(IRestApiService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- // TODO: Add the appropriate initialization
- conn = GraphDBConnection.getInstance("");
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- // TODO: Add the approprate setup
- }
-
-
- static class ShortestPathLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
- String dpid;
- public ShortestPathLoopFunction(String dpid) {
- super();
- this.dpid = dpid;
- }
- public Boolean compute(LoopBundle<Vertex> bundle) {
- Boolean output = false;
- if (! bundle.getObject().getProperty("dpid").equals(dpid)) {
- output = true;
- }
- return output;
+ /**
+ * Init the module.
+ *
+ * @param config the database configuration file to use for
+ * the initialization.
+ */
+ public void init(String config) {
+ try {
+ op = new GraphDBOperation(config);
+ } catch (Exception e) {
+ log.error(e.getMessage());
}
}
/**
+ * Close the service. It will close the corresponding database connection.
+ */
+ public void close() {
+ op.close();
+ }
+
+ /**
+ * Set the database operation handler.
+ *
+ * @param init_op the database operation handler to use for the
+ * initialization.
+ */
+ public void setDbOperationHandler(GraphDBOperation init_op) {
+ op = init_op;
+ }
+
+ /**
* Fetch the Switch and Ports info from the Titan Graph
- * and store it locally for fast access during the shortest path
+ * and return it for fast access during the shortest path
* computation.
*
* After fetching the state, method @ref getTopoShortestPath()
@@ -184,22 +167,24 @@
* method @ref dropShortestPathTopo() should be used to release
* the internal state that is not needed anymore:
*
- * prepareShortestPathTopo();
+ * Map<Long, ?> shortestPathTopo;
+ * shortestPathTopo = prepareShortestPathTopo();
* for (int i = 0; i < 10000; i++) {
- * dataPath = getTopoShortestPath(...);
+ * dataPath = getTopoShortestPath(shortestPathTopo, ...);
* ...
* }
- * dropShortestPathTopo();
+ * dropShortestPathTopo(shortestPathTopo);
+ *
+ * @return the Shortest Path info handler stored in a map.
*/
-
- public void prepareShortestPathTopo() {
- shortestPathTopo = new HashMap<Long, Node>();
+ public Map<Long, ?> prepareShortestPathTopo() {
+ Map<Long, Node> shortestPathTopo = new HashMap<Long, Node>();
//
// Fetch the relevant info from the Switch and Port vertices
// from the Titan Graph.
//
- Iterable<ISwitchObject> nodes = conn.utils().getActiveSwitches(conn);
+ Iterable<ISwitchObject> nodes = op.getActiveSwitches();
for (ISwitchObject switchObj : nodes) {
Vertex nodeVertex = switchObj.asVertex();
//
@@ -259,7 +244,9 @@
}
}
}
- conn.endTx(Transaction.COMMIT);
+ op.commit();
+
+ return shortestPathTopo;
}
/**
@@ -268,9 +255,10 @@
*
* See the documentation for method @ref prepareShortestPathTopo()
* for additional information and usage.
+ *
+ * @param shortestPathTopo the Shortest Path info handler to release.
*/
-
- public void dropShortestPathTopo() {
+ public void dropShortestPathTopo(Map<Long, ?> shortestPathTopo) {
shortestPathTopo = null;
}
@@ -282,13 +270,17 @@
* See the documentation for method @ref prepareShortestPathTopo()
* for additional information and usage.
*
+ * @param shortestPathTopoHandler the Shortest Path info handler
+ * to use.
* @param src the source in the shortest path computation.
* @param dest the destination in the shortest path computation.
* @return the data path with the computed shortest path if
* found, otherwise null.
*/
-
- public DataPath getTopoShortestPath(SwitchPort src, SwitchPort dest) {
+ public DataPath getTopoShortestPath(Map<Long, ?> shortestPathTopoHandler,
+ SwitchPort src, SwitchPort dest) {
+ @SuppressWarnings("unchecked")
+ Map<Long, Node> shortestPathTopo = (Map)shortestPathTopoHandler;
DataPath result_data_path = new DataPath();
// Initialize the source and destination in the data path to return
@@ -415,9 +407,9 @@
// Get the source and destination switches
ISwitchObject srcSwitch =
- conn.utils().searchActiveSwitch(conn, dpid_src);
+ op.searchActiveSwitch(dpid_src);
ISwitchObject destSwitch =
- conn.utils().searchActiveSwitch(conn, dpid_dest);
+ op.searchActiveSwitch(dpid_dest);
if (srcSwitch == null || destSwitch == null) {
return null;
}
@@ -432,7 +424,7 @@
flowEntry.setInPort(src.port());
flowEntry.setOutPort(dest.port());
result_data_path.flowEntries().add(flowEntry);
- conn.endTx(Transaction.COMMIT);
+ op.commit();
return result_data_path;
}
@@ -551,7 +543,7 @@
result_data_path.flowEntries().add(flowEntry);
}
- conn.endTx(Transaction.COMMIT);
+ op.commit();
if (result_data_path.flowEntries().size() > 0)
return result_data_path;
diff --git a/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java b/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
similarity index 65%
rename from src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
rename to src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
index 20f39d4..659609d 100644
--- a/src/main/java/net/floodlightcontroller/topology/web/RouteResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/web/RouteResource.java
@@ -1,17 +1,12 @@
-package net.floodlightcontroller.topology.web;
+package net.onrc.onos.ofcontroller.topology.web;
-import java.util.List;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
-import net.floodlightcontroller.routing.IRoutingService;
-import net.floodlightcontroller.routing.Route;
-import net.floodlightcontroller.topology.NodePortTuple;
-import net.floodlightcontroller.util.DataPath;
-import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.Port;
-import net.floodlightcontroller.util.SwitchPort;
-
-import org.openflow.util.HexString;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
@@ -23,9 +18,7 @@
@Get("json")
public DataPath retrieve() {
- ITopoRouteService topoRouteService =
- (ITopoRouteService)getContext().getAttributes().
- get(ITopoRouteService.class.getCanonicalName());
+ ITopoRouteService topoRouteService = new TopoRouteService("");
if (topoRouteService == null) {
log.debug("Topology Route Service not found");
return null;
diff --git a/src/main/java/net/floodlightcontroller/util/CallerId.java b/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
similarity index 95%
rename from src/main/java/net/floodlightcontroller/util/CallerId.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
index ade0f0d..0607533 100644
--- a/src/main/java/net/floodlightcontroller/util/CallerId.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
import org.codehaus.jackson.annotate.JsonProperty;
diff --git a/src/main/java/net/floodlightcontroller/util/DataPath.java b/src/main/java/net/onrc/onos/ofcontroller/util/DataPath.java
similarity index 81%
rename from src/main/java/net/floodlightcontroller/util/DataPath.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/DataPath.java
index 0ca0d13..dec70e3 100644
--- a/src/main/java/net/floodlightcontroller/util/DataPath.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/DataPath.java
@@ -1,14 +1,11 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
import java.util.ArrayList;
-import net.floodlightcontroller.util.SwitchPort;
-import net.floodlightcontroller.util.FlowEntry;
-
import org.codehaus.jackson.annotate.JsonProperty;
/**
- * The class representing the Data Path.
+ * The data forwarding path state from a source to a destination.
*/
public class DataPath {
private SwitchPort srcPort; // The source port
@@ -79,6 +76,31 @@
}
/**
+ * Apply Flow Path Flags to the pre-computed Data Path.
+ *
+ * @param flowPathFlags the Flow Path Flags to apply.
+ */
+ public void applyFlowPathFlags(FlowPathFlags flowPathFlags) {
+ if (flowPathFlags == null)
+ return; // Nothing to do
+
+ // Discard the first Flow Entry
+ if (flowPathFlags.isDiscardFirstHopEntry()) {
+ if (flowEntries.size() > 0)
+ flowEntries.remove(0);
+ }
+
+ // Keep only the first Flow Entry
+ if (flowPathFlags.isKeepOnlyFirstHopEntry()) {
+ if (flowEntries.size() > 1) {
+ FlowEntry flowEntry = flowEntries.get(0);
+ flowEntries.clear();
+ flowEntries.add(flowEntry);
+ }
+ }
+ }
+
+ /**
* Get a string with the summary of the shortest-path data path
* computation.
*
diff --git a/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java b/src/main/java/net/onrc/onos/ofcontroller/util/DataPathEndpoints.java
similarity index 95%
rename from src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/DataPathEndpoints.java
index 3ee88d1..9cdd4fb 100644
--- a/src/main/java/net/floodlightcontroller/util/DataPathEndpoints.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/DataPathEndpoints.java
@@ -1,6 +1,5 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
-import net.floodlightcontroller.util.SwitchPort;
import org.codehaus.jackson.annotate.JsonProperty;
diff --git a/src/main/java/net/floodlightcontroller/util/Dpid.java b/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
similarity index 86%
rename from src/main/java/net/floodlightcontroller/util/Dpid.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
index 5af6bea..c3cf3aa 100644
--- a/src/main/java/net/floodlightcontroller/util/Dpid.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
@@ -1,12 +1,11 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
-import org.openflow.util.HexString;
-import net.floodlightcontroller.util.serializers.DpidDeserializer;
-import net.floodlightcontroller.util.serializers.DpidSerializer;
+import net.onrc.onos.ofcontroller.util.serializers.DpidDeserializer;
+import net.onrc.onos.ofcontroller.util.serializers.DpidSerializer;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.openflow.util.HexString;
/**
* The class representing a network switch DPID.
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntry.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
similarity index 86%
rename from src/main/java/net/floodlightcontroller/util/FlowEntry.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
index 3e29c78..049e783 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntry.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntry.java
@@ -1,18 +1,7 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
import java.util.ArrayList;
-import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.FlowEntryAction;
-import net.floodlightcontroller.util.FlowEntryId;
-import net.floodlightcontroller.util.FlowEntryMatch;
-import net.floodlightcontroller.util.FlowEntrySwitchState;
-import net.floodlightcontroller.util.FlowEntryUserState;
-import net.floodlightcontroller.util.Port;
-
-import net.floodlightcontroller.util.MACAddress;
-import net.floodlightcontroller.util.IPv4;
-
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -23,10 +12,10 @@
* support multiple in-ports and multiple out-ports.
*/
public class FlowEntry {
- private FlowId flowId; // FlowID of flowEntry
+ private FlowId flowId; // FlowID of the Flow Entry
private FlowEntryId flowEntryId; // The Flow Entry ID
private FlowEntryMatch flowEntryMatch; // The Flow Entry Match
- private ArrayList<FlowEntryAction> flowEntryActions; // The Flow Entry Actions
+ private FlowEntryActions flowEntryActions; // The Flow Entry Actions
private Dpid dpid; // The Switch DPID
private Port inPort; // The Switch incoming port. Used only
// when the entry is used to return
@@ -64,64 +53,64 @@
flowEntryMatch.enableDstTcpUdpPort((short)80);
FlowEntryAction action = null;
- ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
+ FlowEntryActions actions = new FlowEntryActions();
action = new FlowEntryAction();
action.setActionOutput(new Port((short)12));
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionOutputToController((short)13);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetVlanId((short)14);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetVlanPriority((byte)15);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionStripVlan(true);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetEthernetSrcAddr(mac);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetEthernetDstAddr(mac);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetIPv4SrcAddr(ipv4);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetIPv4DstAddr(ipv4);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetIpToS((byte)16);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetTcpUdpSrcPort((short)17);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionSetTcpUdpDstPort((short)18);
- actions.add(action);
+ actions.addAction(action);
action = new FlowEntryAction();
action.setActionEnqueue(new Port((short)19), 20);
- actions.add(action);
+ actions.addAction(action);
setFlowEntryActions(actions);
*/
-
+ flowEntryActions = new FlowEntryActions();
flowEntryUserState = FlowEntryUserState.FE_USER_UNKNOWN;
flowEntrySwitchState = FlowEntrySwitchState.FE_SWITCH_UNKNOWN;
}
@@ -184,7 +173,7 @@
* @return the Flow Entry Actions.
*/
@JsonProperty("flowEntryActions")
- public ArrayList<FlowEntryAction> flowEntryActions() {
+ public FlowEntryActions flowEntryActions() {
return flowEntryActions;
}
@@ -194,7 +183,7 @@
* @param flowEntryActions the Flow Entry Actions to set.
*/
@JsonProperty("flowEntryActions")
- public void setFlowEntryActions(ArrayList<FlowEntryAction> flowEntryActions) {
+ public void setFlowEntryActions(FlowEntryActions flowEntryActions) {
this.flowEntryActions = flowEntryActions;
}
@@ -330,8 +319,7 @@
* Convert the flow entry to a string.
*
* The string has the following form:
- * [flowEntryId=XXX flowEntryMatch=XXX flowEntryAction=XXX
- * flowEntryAction=XXX flowEntryAction=XXX dpid=XXX
+ * [flowEntryId=XXX flowEntryMatch=XXX flowEntryActions=XXX dpid=XXX
* inPort=XXX outPort=XXX flowEntryUserState=XXX flowEntrySwitchState=XXX
* flowEntryErrorState=XXX]
* @return the flow entry as a string.
@@ -340,9 +328,7 @@
public String toString() {
String ret = "[flowEntryId=" + this.flowEntryId.toString();
ret += " flowEntryMatch=" + this.flowEntryMatch.toString();
- for (FlowEntryAction fa : flowEntryActions) {
- ret += " flowEntryAction=" + fa.toString();
- }
+ ret += " flowEntryActions=" + this.flowEntryActions.toString();
ret += " dpid=" + this.dpid.toString();
ret += " inPort=" + this.inPort.toString();
ret += " outPort=" + this.outPort.toString();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java
new file mode 100644
index 0000000..f150983
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryAction.java
@@ -0,0 +1,1664 @@
+package net.onrc.onos.ofcontroller.util;
+
+import net.floodlightcontroller.util.MACAddress;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * The class representing a single Flow Entry action.
+ *
+ * A Flow Entry action that needs to be applied to each packet.
+ * Note that it contains only a single action. Multiple actions are
+ * listed in a list inside @ref FlowEntryActions.
+ */
+public class FlowEntryAction {
+ /**
+ * Special action values.
+ *
+ * Those values are taken as-is from the OpenFlow-v1.0.0 specification
+ * (pp 21-22).
+ */
+ public enum ActionValues {
+ ACTION_OUTPUT ((short)0x0), // Output to switch port
+ ACTION_SET_VLAN_VID ((short)0x1), // Set the 802.1q VLAN id
+ ACTION_SET_VLAN_PCP ((short)0x2), // Set the 802.1q priority
+ ACTION_STRIP_VLAN ((short)0x3), // Strip the 802.1q header
+ ACTION_SET_DL_SRC ((short)0x4), // Ethernet source address
+ ACTION_SET_DL_DST ((short)0x5), // Ethernet destination address
+ ACTION_SET_NW_SRC ((short)0x6), // IP source address
+ ACTION_SET_NW_DST ((short)0x7), // IP destination address
+ ACTION_SET_NW_TOS ((short)0x8), // IP ToS (DSCP field, 6 bits)
+ ACTION_SET_TP_SRC ((short)0x9), // TCP/UDP source port
+ ACTION_SET_TP_DST ((short)0xa), // TCP/UDP destination port
+ ACTION_ENQUEUE ((short)0xb), // Output to queue on port
+ ACTION_VENDOR ((short)0xffff); // Vendor-specific
+
+ private final short value; // The value
+
+ /**
+ * Constructor for a given value.
+ *
+ * @param value the value to use for the initialization.
+ */
+ private ActionValues(short value) {
+ this.value = value;
+ }
+ }
+
+ /**
+ * Action structure for ACTION_OUTPUT: Output to switch port.
+ */
+ public class ActionOutput {
+ private Port port; // Output port
+ private short maxLen; // Max. length (in bytes) to send to controller
+ // if the port is set to PORT_CONTROLLER
+
+ /**
+ * Default constructor.
+ */
+ public ActionOutput() {
+ this.port = null;
+ this.maxLen = 0;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionOutput(ActionOutput other) {
+ if (other.port != null)
+ this.port = new Port(other.port);
+ this.maxLen = other.maxLen;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [port=XXX maxLen=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionOutput(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given output port and maximum length.
+ *
+ * @param port the output port to set.
+ * @param maxLen the maximum length (in bytes) to send to controller
+ * if the port is set to PORT_CONTROLLER.
+ */
+ public ActionOutput(Port port, short maxLen) {
+ this.port = port;
+ this.maxLen = maxLen;
+ }
+
+ /**
+ * Constructor for a given output port.
+ *
+ * @param port the output port to set.
+ */
+ public ActionOutput(Port port) {
+ this.port = port;
+ this.maxLen = 0;
+ }
+
+ /**
+ * Get the output port.
+ *
+ * @return the output port.
+ */
+ @JsonProperty("port")
+ public Port port() {
+ return this.port;
+ }
+
+ /**
+ * Get the maximum length (in bytes) to send to controller if the
+ * port is set to PORT_CONTROLLER.
+ *
+ * @return the maximum length (in bytes) to send to controller if the
+ * port is set to PORT_CONTROLLER.
+ */
+ @JsonProperty("maxLen")
+ public short maxLen() {
+ return this.maxLen;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [port=XXX maxLen=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "port=" + port.toString();
+ ret += " maxLen=" + maxLen;
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [port=XXX maxLen=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split(" ");
+ String decode = null;
+
+ // Decode the "port=XXX" part
+ if (parts.length > 0)
+ decode = parts[0];
+ if (decode != null) {
+ String[] tokens = decode.split("port=");
+ if (tokens.length > 1 && tokens[1] != null) {
+ try {
+ Short valueShort = Short.valueOf(tokens[1]);
+ port = new Port(valueShort);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Decode the "maxLen=XXX" part
+ decode = null;
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ String[] tokens = decode.split("maxLen=");
+ if (tokens.length > 1 && tokens[1] != null) {
+ try {
+ maxLen = Short.valueOf(tokens[1]);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_VLAN_VID: Set the 802.1q VLAN id
+ */
+ public class ActionSetVlanId {
+ private short vlanId; // The VLAN ID to set
+
+ /**
+ * Default constructor.
+ */
+ public ActionSetVlanId() {
+ this.vlanId = 0;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetVlanId(ActionSetVlanId other) {
+ this.vlanId = other.vlanId;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [vlanId=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetVlanId(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given VLAN ID.
+ *
+ * @param vlanId the VLAN ID to set.
+ */
+ public ActionSetVlanId(short vlanId) {
+ this.vlanId = vlanId;
+ }
+
+ /**
+ * Get the VLAN ID.
+ *
+ * @return the VLAN ID.
+ */
+ @JsonProperty("vlanId")
+ public short vlanId() {
+ return this.vlanId;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [vlanId=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "vlanId=" + this.vlanId;
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [vlanId=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("vlanId=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ vlanId = Short.valueOf(decode);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_VLAN_PCP: Set the 802.1q priority
+ */
+ public class ActionSetVlanPriority {
+ private byte vlanPriority; // The VLAN priority to set
+
+ /**
+ * Default constructor.
+ */
+ public ActionSetVlanPriority() {
+ this.vlanPriority = 0;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetVlanPriority(ActionSetVlanPriority other) {
+ this.vlanPriority = other.vlanPriority;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [vlanPriority=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetVlanPriority(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given VLAN priority.
+ *
+ * @param vlanPriority the VLAN priority to set.
+ */
+ public ActionSetVlanPriority(byte vlanPriority) {
+ this.vlanPriority = vlanPriority;
+ }
+
+ /**
+ * Get the VLAN priority.
+ *
+ * @return the VLAN priority.
+ */
+ @JsonProperty("vlanPriority")
+ public byte vlanPriority() {
+ return this.vlanPriority;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [vlanPriority=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "vlanPriority=" + this.vlanPriority;
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [vlanPriority=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("vlanPriority=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ vlanPriority = Byte.valueOf(decode);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ /**
+ * Action structure for ACTION_STRIP_VLAN: Strip the 802.1q header
+ */
+ public class ActionStripVlan {
+ private boolean stripVlan; // If true, strip the VLAN header
+
+ /**
+ * Default constructor.
+ */
+ public ActionStripVlan() {
+ this.stripVlan = false;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionStripVlan(ActionStripVlan other) {
+ this.stripVlan = other.stripVlan;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [stripVlan=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionStripVlan(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given boolean flag.
+ *
+ * @param stripVlan if true, strip the VLAN header.
+ */
+ public ActionStripVlan(boolean stripVlan) {
+ this.stripVlan = stripVlan;
+ }
+
+ /**
+ * Get the boolean flag whether the VLAN header should be stripped.
+ *
+ * @return the boolean flag whether the VLAN header should be stripped.
+ */
+ @JsonProperty("stripVlan")
+ public boolean stripVlan() {
+ return this.stripVlan;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [stripVlan=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "stripVlan=" + this.stripVlan;
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [stripVlan=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("stripVlan=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ stripVlan = Boolean.valueOf(decode);
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_DL_SRC and ACTION_SET_DL_DST:
+ * Set the Ethernet source/destination address.
+ */
+ public class ActionSetEthernetAddr {
+ private MACAddress addr; // The MAC address to set
+
+ /**
+ * Default constructor.
+ */
+ public ActionSetEthernetAddr() {
+ this.addr = null;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetEthernetAddr(ActionSetEthernetAddr other) {
+ if (other.addr != null)
+ this.addr = MACAddress.valueOf(other.addr.toLong());
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetEthernetAddr(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given MAC address.
+ *
+ * @param addr the MAC address to set.
+ */
+ public ActionSetEthernetAddr(MACAddress addr) {
+ this.addr = addr;
+ }
+
+ /**
+ * Get the MAC address.
+ *
+ * @return the MAC address.
+ */
+ @JsonProperty("addr")
+ public MACAddress addr() {
+ return this.addr;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "addr=" + addr.toString();
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("addr=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ addr = MACAddress.valueOf(decode);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_NW_SRC and ACTION_SET_NW_DST:
+ * Set the IPv4 source/destination address.
+ */
+ public class ActionSetIPv4Addr {
+ private IPv4 addr; // The IPv4 address to set
+
+ /**
+ * Default constructor.
+ */
+ public ActionSetIPv4Addr() {
+ this.addr = null;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetIPv4Addr(ActionSetIPv4Addr other) {
+ if (other.addr != null)
+ this.addr = new IPv4(other.addr);
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetIPv4Addr(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given IPv4 address.
+ *
+ * @param addr the IPv4 address to set.
+ */
+ public ActionSetIPv4Addr(IPv4 addr) {
+ this.addr = addr;
+ }
+
+ /**
+ * Get the IPv4 address.
+ *
+ * @return the IPv4 address.
+ */
+ @JsonProperty("addr")
+ public IPv4 addr() {
+ return this.addr;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "addr=" + addr.toString();
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [addr=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("addr=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ addr = new IPv4(decode);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_NW_TOS:
+ * Set the IP ToS (DSCP field, 6 bits).
+ */
+ public class ActionSetIpToS {
+ private byte ipToS; // The IP ToS to set DSCP field, 6 bits)
+
+ /**
+ * Default constructor.
+ */
+ public ActionSetIpToS() {
+ this.ipToS = 0;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetIpToS(ActionSetIpToS other) {
+ this.ipToS = other.ipToS;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [ipToS=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetIpToS(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given IP ToS (DSCP field, 6 bits).
+ *
+ * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+ */
+ public ActionSetIpToS(byte ipToS) {
+ this.ipToS = ipToS;
+ }
+
+ /**
+ * Get the IP ToS (DSCP field, 6 bits).
+ *
+ * @return the IP ToS (DSCP field, 6 bits).
+ */
+ @JsonProperty("ipToS")
+ public byte ipToS() {
+ return this.ipToS;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [ipToS=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "ipToS=" + ipToS;
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [ipToS=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("ipToS=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ ipToS = Byte.valueOf(decode);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ /**
+ * Action structure for ACTION_SET_TP_SRC and ACTION_SET_TP_DST:
+ * Set the TCP/UDP source/destination port.
+ */
+ public class ActionSetTcpUdpPort {
+ private short port; // The TCP/UDP port to set
+
+ /**
+ * Default constructor.
+ */
+ public ActionSetTcpUdpPort() {
+ this.port = 0;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionSetTcpUdpPort(ActionSetTcpUdpPort other) {
+ this.port = other.port;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [port=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionSetTcpUdpPort(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given TCP/UDP port.
+ *
+ * @param port the TCP/UDP port to set.
+ */
+ public ActionSetTcpUdpPort(short port) {
+ this.port = port;
+ }
+
+ /**
+ * Get the TCP/UDP port.
+ *
+ * @return the TCP/UDP port.
+ */
+ @JsonProperty("port")
+ public short port() {
+ return this.port;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [port=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "port=" + port;
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [port=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("port=");
+ String decode = null;
+
+ // Decode the value
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ try {
+ port = Short.valueOf(decode);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ /**
+ * Action structure for ACTION_ENQUEUE: Output to queue on port.
+ */
+ public class ActionEnqueue {
+ private Port port; // Port that queue belongs. Should
+ // refer to a valid physical port
+ // (i.e. < PORT_MAX) or PORT_IN_PORT
+ private int queueId; // Where to enqueue the packets
+
+ /**
+ * Default constructor.
+ */
+ public ActionEnqueue() {
+ this.port = null;
+ this.queueId = 0;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public ActionEnqueue(ActionEnqueue other) {
+ if (other.port != null)
+ this.port = new Port(other.port);
+ this.queueId = other.queueId;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [port=XXX queueId=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public ActionEnqueue(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Constructor for a given port and queue ID.
+ *
+ * @param port the port to set.
+ * @param queueId the queue ID on the port.
+ */
+ public ActionEnqueue(Port port, int queueId) {
+ this.port = port;
+ this.queueId = queueId;
+ }
+
+ /**
+ * Get the port.
+ *
+ * @return the port.
+ */
+ @JsonProperty("port")
+ public Port port() {
+ return this.port;
+ }
+
+ /**
+ * Get the queue ID.
+ *
+ * @return the queue ID.
+ */
+ @JsonProperty("queueId")
+ public int queueId() {
+ return this.queueId;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [port=XXX queueId=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "port=" + port.toString();
+ ret += " queueId=" + queueId;
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [port=XXX queueId=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split(" ");
+ String decode = null;
+
+ // Decode the "port=XXX" part
+ if (parts.length > 0)
+ decode = parts[0];
+ if (decode != null) {
+ String[] tokens = decode.split("port=");
+ if (tokens.length > 1 && tokens[1] != null) {
+ try {
+ Short valueShort = Short.valueOf(tokens[1]);
+ port = new Port(valueShort);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Decode the "queueId=XXX" part
+ decode = null;
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode != null) {
+ decode = decode.replace("]", "");
+ String[] tokens = decode.split("queueId=");
+ if (tokens.length > 1 && tokens[1] != null) {
+ try {
+ queueId = Short.valueOf(tokens[1]);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ }
+
+ private ActionValues actionType; // The action type
+
+ //
+ // The actions.
+ // NOTE: Only one action should be set.
+ //
+ private ActionOutput actionOutput;
+ private ActionSetVlanId actionSetVlanId;
+ private ActionSetVlanPriority actionSetVlanPriority;
+ private ActionStripVlan actionStripVlan;
+ private ActionSetEthernetAddr actionSetEthernetSrcAddr;
+ private ActionSetEthernetAddr actionSetEthernetDstAddr;
+ private ActionSetIPv4Addr actionSetIPv4SrcAddr;
+ private ActionSetIPv4Addr actionSetIPv4DstAddr;
+ private ActionSetIpToS actionSetIpToS;
+ private ActionSetTcpUdpPort actionSetTcpUdpSrcPort;
+ private ActionSetTcpUdpPort actionSetTcpUdpDstPort;
+ private ActionEnqueue actionEnqueue;
+
+ /**
+ * Default constructor.
+ */
+ public FlowEntryAction() {
+ actionType = ActionValues.ACTION_VENDOR; // XXX: Initial value
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public FlowEntryAction(FlowEntryAction other) {
+ this.actionType = other.actionType;
+
+ //
+ if (other.actionOutput != null)
+ this.actionOutput = new ActionOutput(other.actionOutput);
+ else
+ this.actionOutput = null;
+ //
+ if (other.actionSetVlanId != null)
+ this.actionSetVlanId = new ActionSetVlanId(other.actionSetVlanId);
+ else
+ this.actionSetVlanId = null;
+ //
+ if (other.actionSetVlanPriority != null)
+ this.actionSetVlanPriority = new ActionSetVlanPriority(other.actionSetVlanPriority);
+ else
+ this.actionSetVlanPriority = null;
+ //
+ if (other.actionStripVlan != null)
+ this.actionStripVlan = new ActionStripVlan(other.actionStripVlan);
+ else
+ this.actionStripVlan = null;
+ //
+ if (other.actionSetEthernetSrcAddr != null)
+ this.actionSetEthernetSrcAddr = new ActionSetEthernetAddr(other.actionSetEthernetSrcAddr);
+ else
+ this.actionSetEthernetSrcAddr = null;
+ //
+ if (other.actionSetEthernetDstAddr != null)
+ this.actionSetEthernetDstAddr = new ActionSetEthernetAddr(other.actionSetEthernetDstAddr);
+ else
+ this.actionSetEthernetDstAddr = null;
+ //
+ if (other.actionSetIPv4SrcAddr != null)
+ this.actionSetIPv4SrcAddr = new ActionSetIPv4Addr(other.actionSetIPv4SrcAddr);
+ else
+ this.actionSetIPv4SrcAddr = null;
+ //
+ if (other.actionSetIPv4DstAddr != null)
+ this.actionSetIPv4DstAddr = new ActionSetIPv4Addr(other.actionSetIPv4DstAddr);
+ else
+ this.actionSetIPv4DstAddr = null;
+ //
+ if (other.actionSetIpToS != null)
+ this.actionSetIpToS = new ActionSetIpToS(other.actionSetIpToS);
+ else
+ this.actionSetIpToS = null;
+ //
+ if (other.actionSetTcpUdpSrcPort != null)
+ this.actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(other.actionSetTcpUdpSrcPort);
+ else
+ this.actionSetTcpUdpSrcPort = null;
+ //
+ if (other.actionSetTcpUdpDstPort != null)
+ this.actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(other.actionSetTcpUdpDstPort);
+ else
+ this.actionSetTcpUdpDstPort = null;
+ //
+ if (other.actionEnqueue != null)
+ this.actionEnqueue = new ActionEnqueue(other.actionEnqueue);
+ else
+ this.actionEnqueue = null;
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [type=XXX action=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public FlowEntryAction(String actionStr) {
+ this.fromString(actionStr);
+ }
+
+ /**
+ * Get the action type.
+ *
+ * @return the action type.
+ */
+ @JsonProperty("actionType")
+ public ActionValues actionType() { return actionType; }
+
+ /**
+ * Get the output action.
+ *
+ * @return the output action.
+ */
+ @JsonProperty("actionOutput")
+ public ActionOutput actionOutput() { return actionOutput; }
+
+ /**
+ * Set the output action on a port.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionOutput")
+ public void setActionOutput(ActionOutput action) {
+ actionOutput = action;
+ actionType = ActionValues.ACTION_OUTPUT;
+ }
+
+ /**
+ * Set the output action on a port.
+ *
+ * @param port the output port to set.
+ */
+ public void setActionOutput(Port port) {
+ actionOutput = new ActionOutput(port);
+ actionType = ActionValues.ACTION_OUTPUT;
+ }
+
+ /**
+ * Set the output action to controller.
+ *
+ * @param maxLen the maximum length (in bytes) to send to controller.
+ */
+ public void setActionOutputToController(short maxLen) {
+ Port port = new Port(Port.PortValues.PORT_CONTROLLER);
+ actionOutput = new ActionOutput(port, maxLen);
+ actionType = ActionValues.ACTION_OUTPUT;
+ }
+
+ /**
+ * Get the action to set the VLAN ID.
+ *
+ * @return the action to set the VLAN ID.
+ */
+ @JsonProperty("actionSetVlanId")
+ public ActionSetVlanId actionSetVlanId() { return actionSetVlanId; }
+
+ /**
+ * Set the action to set the VLAN ID.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetVlanId")
+ public void setActionSetVlanId(ActionSetVlanId action) {
+ actionSetVlanId = action;
+ actionType = ActionValues.ACTION_SET_VLAN_VID;
+ }
+
+ /**
+ * Set the action to set the VLAN ID.
+ *
+ * @param vlanId the VLAN ID to set.
+ */
+ public void setActionSetVlanId(short vlanId) {
+ actionSetVlanId = new ActionSetVlanId(vlanId);
+ actionType = ActionValues.ACTION_SET_VLAN_VID;
+ }
+
+ /**
+ * Get the action to set the VLAN priority.
+ *
+ * @return the action to set the VLAN priority.
+ */
+ @JsonProperty("actionSetVlanPriority")
+ public ActionSetVlanPriority actionSetVlanPriority() {
+ return actionSetVlanPriority;
+ }
+
+ /**
+ * Set the action to set the VLAN priority.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetVlanPriority")
+ public void setActionSetVlanPriority(ActionSetVlanPriority action) {
+ actionSetVlanPriority = action;
+ actionType = ActionValues.ACTION_SET_VLAN_PCP;
+ }
+
+ /**
+ * Set the action to set the VLAN priority.
+ *
+ * @param vlanPriority the VLAN priority to set.
+ */
+ public void setActionSetVlanPriority(byte vlanPriority) {
+ actionSetVlanPriority = new ActionSetVlanPriority(vlanPriority);
+ actionType = ActionValues.ACTION_SET_VLAN_PCP;
+ }
+
+ /**
+ * Get the action to strip the VLAN header.
+ *
+ * @return the action to strip the VLAN header.
+ */
+ @JsonProperty("actionStripVlan")
+ public ActionStripVlan actionStripVlan() {
+ return actionStripVlan;
+ }
+
+ /**
+ * Set the action to strip the VLAN header.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionStripVlan")
+ public void setActionStripVlan(ActionStripVlan action) {
+ actionStripVlan = action;
+ actionType = ActionValues.ACTION_STRIP_VLAN;
+ }
+
+ /**
+ * Set the action to strip the VLAN header.
+ *
+ * @param stripVlan if true, strip the VLAN header.
+ */
+ public void setActionStripVlan(boolean stripVlan) {
+ actionStripVlan = new ActionStripVlan(stripVlan);
+ actionType = ActionValues.ACTION_STRIP_VLAN;
+ }
+
+ /**
+ * Get the action to set the Ethernet source address.
+ *
+ * @return the action to set the Ethernet source address.
+ */
+ @JsonProperty("actionSetEthernetSrcAddr")
+ public ActionSetEthernetAddr actionSetEthernetSrcAddr() {
+ return actionSetEthernetSrcAddr;
+ }
+
+ /**
+ * Set the action to set the Ethernet source address.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetEthernetSrcAddr")
+ public void setActionSetEthernetSrcAddr(ActionSetEthernetAddr action) {
+ actionSetEthernetSrcAddr = action;
+ actionType = ActionValues.ACTION_SET_DL_SRC;
+ }
+
+ /**
+ * Set the action to set the Ethernet source address.
+ *
+ * @param addr the MAC address to set as the Ethernet source address.
+ */
+ public void setActionSetEthernetSrcAddr(MACAddress addr) {
+ actionSetEthernetSrcAddr = new ActionSetEthernetAddr(addr);
+ actionType = ActionValues.ACTION_SET_DL_SRC;
+ }
+
+ /**
+ * Get the action to set the Ethernet destination address.
+ *
+ * @return the action to set the Ethernet destination address.
+ */
+ @JsonProperty("actionSetEthernetDstAddr")
+ public ActionSetEthernetAddr actionSetEthernetDstAddr() {
+ return actionSetEthernetDstAddr;
+ }
+
+ /**
+ * Set the action to set the Ethernet destination address.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetEthernetDstAddr")
+ public void setActionSetEthernetDstAddr(ActionSetEthernetAddr action) {
+ actionSetEthernetDstAddr = action;
+ actionType = ActionValues.ACTION_SET_DL_DST;
+ }
+
+ /**
+ * Set the action to set the Ethernet destination address.
+ *
+ * @param addr the MAC address to set as the Ethernet destination address.
+ */
+ public void setActionSetEthernetDstAddr(MACAddress addr) {
+ actionSetEthernetDstAddr = new ActionSetEthernetAddr(addr);
+ actionType = ActionValues.ACTION_SET_DL_DST;
+ }
+
+ /**
+ * Get the action to set the IPv4 source address.
+ *
+ * @return the action to set the IPv4 source address.
+ */
+ @JsonProperty("actionSetIPv4SrcAddr")
+ public ActionSetIPv4Addr actionSetIPv4SrcAddr() {
+ return actionSetIPv4SrcAddr;
+ }
+
+ /**
+ * Set the action to set the IPv4 source address.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetIPv4SrcAddr")
+ public void setActionSetIPv4SrcAddr(ActionSetIPv4Addr action) {
+ actionSetIPv4SrcAddr = action;
+ actionType = ActionValues.ACTION_SET_NW_SRC;
+ }
+
+ /**
+ * Set the action to set the IPv4 source address.
+ *
+ * @param addr the IPv4 address to set as the IPv4 source address.
+ */
+ public void setActionSetIPv4SrcAddr(IPv4 addr) {
+ actionSetIPv4SrcAddr = new ActionSetIPv4Addr(addr);
+ actionType = ActionValues.ACTION_SET_NW_SRC;
+ }
+
+ /**
+ * Get the action to set the IPv4 destination address.
+ *
+ * @return the action to set the IPv4 destination address.
+ */
+ @JsonProperty("actionSetIPv4DstAddr")
+ public ActionSetIPv4Addr actionSetIPv4DstAddr() {
+ return actionSetIPv4DstAddr;
+ }
+
+ /**
+ * Set the action to set the IPv4 destination address.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetIPv4DstAddr")
+ public void setActionSetIPv4DstAddr(ActionSetIPv4Addr action) {
+ actionSetIPv4DstAddr = action;
+ actionType = ActionValues.ACTION_SET_NW_DST;
+ }
+
+ /**
+ * Set the action to set the IPv4 destination address.
+ *
+ * @param addr the IPv4 address to set as the IPv4 destination address.
+ */
+ public void setActionSetIPv4DstAddr(IPv4 addr) {
+ actionSetIPv4DstAddr = new ActionSetIPv4Addr(addr);
+ actionType = ActionValues.ACTION_SET_NW_DST;
+ }
+
+ /**
+ * Get the action to set the IP ToS (DSCP field, 6 bits).
+ *
+ * @return the action to set the IP ToS (DSCP field, 6 bits).
+ */
+ @JsonProperty("actionSetIpToS")
+ public ActionSetIpToS actionSetIpToS() {
+ return actionSetIpToS;
+ }
+
+ /**
+ * Set the action to set the IP ToS (DSCP field, 6 bits).
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetIpToS")
+ public void setActionSetIpToS(ActionSetIpToS action) {
+ actionSetIpToS = action;
+ actionType = ActionValues.ACTION_SET_NW_TOS;
+ }
+
+ /**
+ * Set the action to set the IP ToS (DSCP field, 6 bits).
+ *
+ * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+ */
+ public void setActionSetIpToS(byte ipToS) {
+ actionSetIpToS = new ActionSetIpToS(ipToS);
+ actionType = ActionValues.ACTION_SET_NW_TOS;
+ }
+
+ /**
+ * Get the action to set the TCP/UDP source port.
+ *
+ * @return the action to set the TCP/UDP source port.
+ */
+ @JsonProperty("actionSetTcpUdpSrcPort")
+ public ActionSetTcpUdpPort actionSetTcpUdpSrcPort() {
+ return actionSetTcpUdpSrcPort;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP source port.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetTcpUdpSrcPort")
+ public void setActionSetTcpUdpSrcPort(ActionSetTcpUdpPort action) {
+ actionSetTcpUdpSrcPort = action;
+ actionType = ActionValues.ACTION_SET_TP_SRC;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP source port.
+ *
+ * @param port the TCP/UDP port to set as the TCP/UDP source port.
+ */
+ public void setActionSetTcpUdpSrcPort(short port) {
+ actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(port);
+ actionType = ActionValues.ACTION_SET_TP_SRC;
+ }
+
+ /**
+ * Get the action to set the TCP/UDP destination port.
+ *
+ * @return the action to set the TCP/UDP destination port.
+ */
+ @JsonProperty("actionSetTcpUdpDstPort")
+ public ActionSetTcpUdpPort actionSetTcpUdpDstPort() {
+ return actionSetTcpUdpDstPort;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP destination port.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionSetTcpUdpDstPort")
+ public void setActionSetTcpUdpDstPort(ActionSetTcpUdpPort action) {
+ actionSetTcpUdpDstPort = action;
+ actionType = ActionValues.ACTION_SET_TP_DST;
+ }
+
+ /**
+ * Set the action to set the TCP/UDP destination port.
+ *
+ * @param port the TCP/UDP port to set as the TCP/UDP destination port.
+ */
+ public void setActionSetTcpUdpDstPort(short port) {
+ actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(port);
+ actionType = ActionValues.ACTION_SET_TP_DST;
+ }
+
+ /**
+ * Get the action to output to queue on a port.
+ *
+ * @return the action to output to queue on a port.
+ */
+ @JsonProperty("actionEnqueue")
+ public ActionEnqueue actionEnqueue() { return actionEnqueue; }
+
+ /**
+ * Set the action to output to queue on a port.
+ *
+ * @param action the action to set.
+ */
+ @JsonProperty("actionEnqueue")
+ public void setActionEnqueue(ActionEnqueue action) {
+ actionEnqueue = action;
+ actionType = ActionValues.ACTION_ENQUEUE;
+ }
+
+ /**
+ * Set the action to output to queue on a port.
+ *
+ * @param port the port to set.
+ * @param int queueId the queue ID to set.
+ */
+ public void setActionEnqueue(Port port, int queueId) {
+ actionEnqueue = new ActionEnqueue(port, queueId);
+ actionType = ActionValues.ACTION_ENQUEUE;
+ }
+
+ /**
+ * Convert the action to a string.
+ *
+ * The string has the following form:
+ * [type=XXX action=XXX]
+ *
+ * @return the action as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ ret += "type=" + actionType;
+ switch (actionType) {
+ case ACTION_OUTPUT:
+ ret += " action=" + actionOutput.toString();
+ break;
+ case ACTION_SET_VLAN_VID:
+ ret += " action=" + actionSetVlanId.toString();
+ break;
+ case ACTION_SET_VLAN_PCP:
+ ret += " action=" + actionSetVlanPriority.toString();
+ break;
+ case ACTION_STRIP_VLAN:
+ ret += " action=" + actionStripVlan.toString();
+ break;
+ case ACTION_SET_DL_SRC:
+ ret += " action=" + actionSetEthernetSrcAddr.toString();
+ break;
+ case ACTION_SET_DL_DST:
+ ret += " action=" + actionSetEthernetDstAddr.toString();
+ break;
+ case ACTION_SET_NW_SRC:
+ ret += " action=" + actionSetIPv4SrcAddr.toString();
+ break;
+ case ACTION_SET_NW_DST:
+ ret += " action=" + actionSetIPv4DstAddr.toString();
+ break;
+ case ACTION_SET_NW_TOS:
+ ret += " action=" + actionSetIpToS.toString();
+ break;
+ case ACTION_SET_TP_SRC:
+ ret += " action=" + actionSetTcpUdpSrcPort.toString();
+ break;
+ case ACTION_SET_TP_DST:
+ ret += " action=" + actionSetTcpUdpDstPort.toString();
+ break;
+ case ACTION_ENQUEUE:
+ ret += " action=" + actionEnqueue.toString();
+ break;
+ }
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to an action.
+ *
+ * The string has the following form:
+ * [type=XXX action=XXX]
+ *
+ * @param actionStr the action as a string.
+ */
+ public void fromString(String actionStr) {
+ String[] parts = actionStr.split("type=");
+ String decode = null;
+
+ // Extract the string after the "type="
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode == null)
+ throw new IllegalArgumentException("Invalid action string");
+
+ // Remove the trailing ']'
+ if ((decode.length() > 0) && (decode.charAt(decode.length() - 1) == ']')) {
+ decode = decode.substring(0, decode.length() - 1);
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Extract the type value and the action value
+ parts = decode.split(" action=");
+
+ // Decode the "type=XXX" payload
+ if (parts.length > 0)
+ decode = parts[0];
+ if (decode != null) {
+ try {
+ actionType = Enum.valueOf(ActionValues.class, decode);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Decode the "action=XXX" payload
+ decode = null;
+ if (parts.length > 1)
+ decode = parts[1];
+ if (decode == null)
+ throw new IllegalArgumentException("Invalid action string");
+ //
+ try {
+ switch (actionType) {
+ case ACTION_OUTPUT:
+ actionOutput = new ActionOutput(decode);
+ break;
+ case ACTION_SET_VLAN_VID:
+ actionSetVlanId = new ActionSetVlanId(decode);
+ break;
+ case ACTION_SET_VLAN_PCP:
+ actionSetVlanPriority = new ActionSetVlanPriority(decode);
+ break;
+ case ACTION_STRIP_VLAN:
+ actionStripVlan = new ActionStripVlan(decode);
+ break;
+ case ACTION_SET_DL_SRC:
+ actionSetEthernetSrcAddr = new ActionSetEthernetAddr(decode);
+ break;
+ case ACTION_SET_DL_DST:
+ actionSetEthernetDstAddr = new ActionSetEthernetAddr(decode);
+ break;
+ case ACTION_SET_NW_SRC:
+ actionSetIPv4SrcAddr = new ActionSetIPv4Addr(decode);
+ break;
+ case ACTION_SET_NW_DST:
+ actionSetIPv4DstAddr = new ActionSetIPv4Addr(decode);
+ break;
+ case ACTION_SET_NW_TOS:
+ actionSetIpToS = new ActionSetIpToS(decode);
+ break;
+ case ACTION_SET_TP_SRC:
+ actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(decode);
+ break;
+ case ACTION_SET_TP_DST:
+ actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(decode);
+ break;
+ case ACTION_ENQUEUE:
+ actionEnqueue = new ActionEnqueue(decode);
+ break;
+ }
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryActions.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryActions.java
new file mode 100644
index 0000000..46f638d
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryActions.java
@@ -0,0 +1,146 @@
+package net.onrc.onos.ofcontroller.util;
+
+import java.util.ArrayList;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * The class representing multiple Flow Entry actions.
+ *
+ * A set of Flow Entry actions need to be applied to each packet.
+ */
+public class FlowEntryActions {
+ private ArrayList<FlowEntryAction> actions; // The Flow Entry Actions
+
+ /**
+ * Default constructor.
+ */
+ public FlowEntryActions() {
+ actions = new ArrayList<FlowEntryAction>();
+ }
+
+ /**
+ * Constructor from a string.
+ *
+ * The string has the following form:
+ * [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+ *
+ * @param actionsStr the set of actions as a string.
+ */
+ public FlowEntryActions(String actionsStr) {
+ this.fromString(actionsStr);
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public FlowEntryActions(FlowEntryActions other) {
+ actions = new ArrayList<FlowEntryAction>();
+
+ for (FlowEntryAction action : other.actions) {
+ FlowEntryAction newAction = new FlowEntryAction(action);
+ actions.add(newAction);
+ }
+ }
+
+ /**
+ * Get the Flow Entry Actions.
+ *
+ * @return the Flow Entry Actions.
+ */
+ @JsonProperty("actions")
+ public ArrayList<FlowEntryAction> actions() {
+ return actions;
+ }
+
+ /**
+ * Set the Flow Entry Actions.
+ *
+ * @param actions the Flow Entry Actions to set.
+ */
+ @JsonProperty("actions")
+ public void setActions(ArrayList<FlowEntryAction> actions) {
+ this.actions = actions;
+ }
+
+ /**
+ * Add a Flow Entry Action.
+ *
+ * @param FlowEntryAction the Flow Entry Action to add.
+ */
+ public void addAction(FlowEntryAction flowEntryAction) {
+ actions.add(flowEntryAction);
+ }
+
+ /**
+ * Test whether the set of actions is empty.
+ *
+ * @return true if the set of actions is empty, otherwise false.
+ */
+ public Boolean isEmpty() {
+ return actions.isEmpty();
+ }
+
+ /**
+ * Convert the set of actions to a string.
+ *
+ * The string has the following form:
+ * [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+ *
+ * @return the set of actions as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[";
+ for (FlowEntryAction action : actions) {
+ ret += action.toString() + ";";
+ }
+ ret += "]";
+
+ return ret;
+ }
+
+ /**
+ * Convert a string to a set of actions.
+ *
+ * The string has the following form:
+ * [[type=XXX action=XXX];[type=XXX action=XXX];...;]
+ *
+ * @param actionsStr the set of actions as a string.
+ */
+ public void fromString(String actionsStr) {
+ String decode = actionsStr;
+
+ actions = new ArrayList<FlowEntryAction>();
+
+ if (decode.isEmpty())
+ return; // Nothing to do
+
+ // Remove the '[' and ']' in the beginning and the end of the string
+ if ((decode.length() > 1) && (decode.charAt(0) == '[') &&
+ (decode.charAt(decode.length() - 1) == ']')) {
+ decode = decode.substring(1, decode.length() - 1);
+ } else {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+
+ // Split the string, and decode each action
+ String[] parts = decode.split(";");
+ for (int i = 0; i < parts.length; i++) {
+ decode = parts[i];
+ if ((decode == null) || decode.isEmpty())
+ continue;
+ FlowEntryAction flowEntryAction = null;
+ try {
+ flowEntryAction = new FlowEntryAction(decode);
+ } catch (IllegalArgumentException e) {
+ // TODO: Ignore invalid actions for now
+ continue;
+ }
+ if (flowEntryAction != null)
+ actions.add(flowEntryAction);
+ }
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryErrorState.java
similarity index 97%
rename from src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryErrorState.java
index bf1708d..2e8c448 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryErrorState.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryErrorState.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
import org.codehaus.jackson.annotate.JsonProperty;
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryId.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryId.java
similarity index 87%
rename from src/main/java/net/floodlightcontroller/util/FlowEntryId.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryId.java
index e146a3d..c4e75a5 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryId.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryId.java
@@ -1,11 +1,10 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
import java.math.BigInteger;
-import net.floodlightcontroller.util.serializers.FlowEntryIdDeserializer;
-import net.floodlightcontroller.util.serializers.FlowEntryIdSerializer;
+import net.onrc.onos.ofcontroller.util.serializers.FlowEntryIdDeserializer;
+import net.onrc.onos.ofcontroller.util.serializers.FlowEntryIdSerializer;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryMatch.java
similarity index 99%
rename from src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryMatch.java
index 6c8e71e..a721ff2 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryMatch.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryMatch.java
@@ -1,7 +1,6 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
import net.floodlightcontroller.util.MACAddress;
-import net.floodlightcontroller.util.IPv4Net;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -73,13 +72,13 @@
private Field<Port> inPort; // Matching input switch port
private Field<MACAddress> srcMac; // Matching source MAC address
private Field<MACAddress> dstMac; // Matching destination MAC address
+ private Field<Short> ethernetFrameType; // Matching Ethernet frame type
private Field<Short> vlanId; // Matching VLAN ID
private Field<Byte> vlanPriority; // Matching VLAN priority
- private Field<Short> ethernetFrameType; // Matching Ethernet frame type
- private Field<Byte> ipToS; // Matching IP ToS (DSCP field, 6 bits)
- private Field<Byte> ipProto; // Matching IP protocol
private Field<IPv4Net> srcIPv4Net; // Matching source IPv4 prefix
private Field<IPv4Net> dstIPv4Net; // Matching destination IPv4 prefix
+ private Field<Byte> ipProto; // Matching IP protocol
+ private Field<Byte> ipToS; // Matching IP ToS (DSCP field, 6 bits)
private Field<Short> srcTcpUdpPort; // Matching source TCP/UDP port
private Field<Short> dstTcpUdpPort; // Matching destination TCP/UDP port
@@ -101,20 +100,20 @@
this.enableSrcMac(other.srcMac.value());
if ((other.dstMac != null) && other.dstMac.enabled())
this.enableDstMac(other.dstMac.value());
+ if ((other.ethernetFrameType != null) && other.ethernetFrameType.enabled())
+ this.enableEthernetFrameType(other.ethernetFrameType.value());
if ((other.vlanId != null) && other.vlanId.enabled())
this.enableVlanId(other.vlanId.value());
if ((other.vlanPriority != null) && other.vlanPriority.enabled())
this.enableVlanPriority(other.vlanPriority.value());
- if ((other.ethernetFrameType != null) && other.ethernetFrameType.enabled())
- this.enableEthernetFrameType(other.ethernetFrameType.value());
- if ((other.ipToS != null) && other.ipToS.enabled())
- this.enableIpToS(other.ipToS.value());
- if ((other.ipProto != null) && other.ipProto.enabled())
- this.enableIpProto(other.ipProto.value());
if ((other.srcIPv4Net != null) && other.srcIPv4Net.enabled())
this.enableSrcIPv4Net(other.srcIPv4Net.value());
if ((other.dstIPv4Net != null) && other.dstIPv4Net.enabled())
this.enableDstIPv4Net(other.dstIPv4Net.value());
+ if ((other.ipProto != null) && other.ipProto.enabled())
+ this.enableIpProto(other.ipProto.value());
+ if ((other.ipToS != null) && other.ipToS.enabled())
+ this.enableIpToS(other.ipToS.value());
if ((other.srcTcpUdpPort != null) && other.srcTcpUdpPort.enabled())
this.enableSrcTcpUdpPort(other.srcTcpUdpPort.value());
if ((other.dstTcpUdpPort != null) && other.dstTcpUdpPort.enabled())
@@ -245,6 +244,48 @@
}
/**
+ * Get the matching Ethernet frame type.
+ *
+ * @return the matching Ethernet frame type.
+ */
+ @JsonProperty("ethernetFrameType")
+ public Short ethernetFrameType() {
+ if (ethernetFrameType != null)
+ return ethernetFrameType.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on Ethernet frame type.
+ *
+ * @param ethernetFrameType the Ethernet frame type value to enable for
+ * matching.
+ */
+ @JsonProperty("ethernetFrameType")
+ public void enableEthernetFrameType(Short ethernetFrameType) {
+ this.ethernetFrameType = new Field<Short>(ethernetFrameType);
+ }
+
+ /**
+ * Disable the matching on Ethernet frame type.
+ */
+ public void disableEthernetFrameType() {
+ this.ethernetFrameType = null;
+ }
+
+ /**
+ * Test if matching on Ethernet frame type is enabled.
+ *
+ * @return true if matching on Ethernet frame type is enabled.
+ */
+ @JsonProperty("matchEthernetFrameType")
+ public boolean matchEthernetFrameType() {
+ if (ethernetFrameType != null)
+ return ethernetFrameType.enabled();
+ return false;
+ }
+
+ /**
* Get the matching VLAN ID.
*
* @return the matching VLAN ID.
@@ -327,130 +368,6 @@
}
/**
- * Get the matching Ethernet frame type.
- *
- * @return the matching Ethernet frame type.
- */
- @JsonProperty("ethernetFrameType")
- public Short ethernetFrameType() {
- if (ethernetFrameType != null)
- return ethernetFrameType.value();
- return null;
- }
-
- /**
- * Enable the matching on Ethernet frame type.
- *
- * @param ethernetFrameType the Ethernet frame type value to enable for
- * matching.
- */
- @JsonProperty("ethernetFrameType")
- public void enableEthernetFrameType(Short ethernetFrameType) {
- this.ethernetFrameType = new Field<Short>(ethernetFrameType);
- }
-
- /**
- * Disable the matching on Ethernet frame type.
- */
- public void disableEthernetFrameType() {
- this.ethernetFrameType = null;
- }
-
- /**
- * Test if matching on Ethernet frame type is enabled.
- *
- * @return true if matching on Ethernet frame type is enabled.
- */
- @JsonProperty("matchEthernetFrameType")
- public boolean matchEthernetFrameType() {
- if (ethernetFrameType != null)
- return ethernetFrameType.enabled();
- return false;
- }
-
- /**
- * Get the matching IP ToS (DSCP field, 6 bits)
- *
- * @return the matching IP ToS.
- */
- @JsonProperty("ipToS")
- public Byte ipToS() {
- if (ipToS != null)
- return ipToS.value();
- return null;
- }
-
- /**
- * Enable the matching on IP ToS (DSCP field, 6 bits).
- *
- * @param ipToS the IP ToS value to enable for matching.
- */
- @JsonProperty("ipToS")
- public void enableIpToS(Byte ipToS) {
- this.ipToS = new Field<Byte>(ipToS);
- }
-
- /**
- * Disable the matching on IP ToS (DSCP field, 6 bits).
- */
- public void disableIpToS() {
- this.ipToS = null;
- }
-
- /**
- * Test if matching on IP ToS (DSCP field, 6 bits) is enabled.
- *
- * @return true if matching on IP ToS is enabled.
- */
- @JsonProperty("matchIpToS")
- public boolean matchIpToS() {
- if (ipToS != null)
- return ipToS.enabled();
- return false;
- }
-
- /**
- * Get the matching IP protocol.
- *
- * @return the matching IP protocol.
- */
- @JsonProperty("ipProto")
- public Byte ipProto() {
- if (ipProto != null)
- return ipProto.value();
- return null;
- }
-
- /**
- * Enable the matching on IP protocol.
- *
- * @param ipProto the IP protocol value to enable for matching.
- */
- @JsonProperty("ipProto")
- public void enableIpProto(Byte ipProto) {
- this.ipProto = new Field<Byte>(ipProto);
- }
-
- /**
- * Disable the matching on IP protocol.
- */
- public void disableIpProto() {
- this.ipProto = null;
- }
-
- /**
- * Test if matching on IP protocol is enabled.
- *
- * @return true if matching on IP protocol is enabled.
- */
- @JsonProperty("matchIpProto")
- public boolean matchIpProto() {
- if (ipProto != null)
- return ipProto.enabled();
- return false;
- }
-
- /**
* Get the matching source IPv4 prefix.
*
* @return the matching source IPv4 prefix.
@@ -534,6 +451,88 @@
}
/**
+ * Get the matching IP protocol.
+ *
+ * @return the matching IP protocol.
+ */
+ @JsonProperty("ipProto")
+ public Byte ipProto() {
+ if (ipProto != null)
+ return ipProto.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on IP protocol.
+ *
+ * @param ipProto the IP protocol value to enable for matching.
+ */
+ @JsonProperty("ipProto")
+ public void enableIpProto(Byte ipProto) {
+ this.ipProto = new Field<Byte>(ipProto);
+ }
+
+ /**
+ * Disable the matching on IP protocol.
+ */
+ public void disableIpProto() {
+ this.ipProto = null;
+ }
+
+ /**
+ * Test if matching on IP protocol is enabled.
+ *
+ * @return true if matching on IP protocol is enabled.
+ */
+ @JsonProperty("matchIpProto")
+ public boolean matchIpProto() {
+ if (ipProto != null)
+ return ipProto.enabled();
+ return false;
+ }
+
+ /**
+ * Get the matching IP ToS (DSCP field, 6 bits)
+ *
+ * @return the matching IP ToS.
+ */
+ @JsonProperty("ipToS")
+ public Byte ipToS() {
+ if (ipToS != null)
+ return ipToS.value();
+ return null;
+ }
+
+ /**
+ * Enable the matching on IP ToS (DSCP field, 6 bits).
+ *
+ * @param ipToS the IP ToS value to enable for matching.
+ */
+ @JsonProperty("ipToS")
+ public void enableIpToS(Byte ipToS) {
+ this.ipToS = new Field<Byte>(ipToS);
+ }
+
+ /**
+ * Disable the matching on IP ToS (DSCP field, 6 bits).
+ */
+ public void disableIpToS() {
+ this.ipToS = null;
+ }
+
+ /**
+ * Test if matching on IP ToS (DSCP field, 6 bits) is enabled.
+ *
+ * @return true if matching on IP ToS is enabled.
+ */
+ @JsonProperty("matchIpToS")
+ public boolean matchIpToS() {
+ if (ipToS != null)
+ return ipToS.enabled();
+ return false;
+ }
+
+ /**
* Get the matching source TCP/UDP port.
*
* @return the matching source TCP/UDP port.
@@ -650,6 +649,12 @@
addSpace = true;
ret += "dstMac=" + this.dstMac().toString();
}
+ if (matchEthernetFrameType()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "ethernetFrameType=" + this.ethernetFrameType().toString();
+ }
if (matchVlanId()) {
if (addSpace)
ret += " ";
@@ -662,24 +667,6 @@
addSpace = true;
ret += "vlanPriority=" + this.vlanPriority().toString();
}
- if (matchEthernetFrameType()) {
- if (addSpace)
- ret += " ";
- addSpace = true;
- ret += "ethernetFrameType=" + this.ethernetFrameType().toString();
- }
- if (matchIpToS()) {
- if (addSpace)
- ret += " ";
- addSpace = true;
- ret += "ipToS=" + this.ipToS().toString();
- }
- if (matchIpProto()) {
- if (addSpace)
- ret += " ";
- addSpace = true;
- ret += "ipProto=" + this.ipProto().toString();
- }
if (matchSrcIPv4Net()) {
if (addSpace)
ret += " ";
@@ -692,6 +679,18 @@
addSpace = true;
ret += "dstIPv4Net=" + this.dstIPv4Net().toString();
}
+ if (matchIpProto()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "ipProto=" + this.ipProto().toString();
+ }
+ if (matchIpToS()) {
+ if (addSpace)
+ ret += " ";
+ addSpace = true;
+ ret += "ipToS=" + this.ipToS().toString();
+ }
if (matchSrcTcpUdpPort()) {
if (addSpace)
ret += " ";
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntrySwitchState.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntrySwitchState.java
similarity index 90%
rename from src/main/java/net/floodlightcontroller/util/FlowEntrySwitchState.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/FlowEntrySwitchState.java
index 4f9882a..a69fdac 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntrySwitchState.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntrySwitchState.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
/**
* The Flow Entry state as set by the controller.
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryUserState.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryUserState.java
similarity index 88%
rename from src/main/java/net/floodlightcontroller/util/FlowEntryUserState.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryUserState.java
index 8637b4f..e3b64f0 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryUserState.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowEntryUserState.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
/**
* The Flow Entry state as set by the user (via the ONOS API).
diff --git a/src/main/java/net/floodlightcontroller/util/FlowId.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowId.java
similarity index 68%
rename from src/main/java/net/floodlightcontroller/util/FlowId.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/FlowId.java
index 0297e2a..de955ba 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowId.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowId.java
@@ -1,11 +1,10 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
import java.math.BigInteger;
-import net.floodlightcontroller.util.serializers.FlowIdDeserializer;
-import net.floodlightcontroller.util.serializers.FlowIdSerializer;
+import net.onrc.onos.ofcontroller.util.serializers.FlowIdDeserializer;
+import net.onrc.onos.ofcontroller.util.serializers.FlowIdSerializer;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -14,7 +13,7 @@
*/
@JsonDeserialize(using=FlowIdDeserializer.class)
@JsonSerialize(using=FlowIdSerializer.class)
-public class FlowId {
+public class FlowId implements Comparable<FlowId> {
private long value;
/**
@@ -77,4 +76,16 @@
public String toString() {
return "0x" + Long.toHexString(this.value);
}
+
+ /**
+ * Compare two FlowId objects numerically using their Flow IDs.
+ *
+ * @return the value 0 if the Flow ID is equal to the argument's Flow ID;
+ * a value less than 0 if the Flow ID is numerically less than the argument's Flow ID;
+ * and a value greater than 0 if the Flow ID is numerically greater than the argument's Flow ID.
+ */
+ @Override
+ public int compareTo(FlowId o) {
+ return Long.valueOf(this.value).compareTo(o.value());
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java
new file mode 100644
index 0000000..153e184
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPath.java
@@ -0,0 +1,332 @@
+package net.onrc.onos.ofcontroller.util;
+
+import java.util.ArrayList;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.util.FlowPathFlags;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * The class representing the Flow Path.
+ */
+public class FlowPath implements Comparable<FlowPath> {
+ private FlowId flowId; // The Flow ID
+ private CallerId installerId; // The Caller ID of the path installer
+ private FlowPathFlags flowPathFlags; // The Flow Path flags
+ private DataPath dataPath; // The data path
+ private FlowEntryMatch flowEntryMatch; // Common Flow Entry Match for all
+ // Flow Entries
+ private FlowEntryActions flowEntryActions; // The Flow Entry Actions for
+ // the first Flow Entry
+
+ /**
+ * Default constructor.
+ */
+ public FlowPath() {
+ flowPathFlags = new FlowPathFlags();
+ dataPath = new DataPath();
+ flowEntryActions = new FlowEntryActions();
+ }
+
+ /**
+ * Constructor to instantiate from object in Network Map
+ */
+ public FlowPath(IFlowPath flowObj) {
+ dataPath = new DataPath();
+ this.setFlowId(new FlowId(flowObj.getFlowId()));
+ this.setInstallerId(new CallerId(flowObj.getInstallerId()));
+ this.setFlowPathFlags(new FlowPathFlags(flowObj.getFlowPathFlags()));
+ this.dataPath().srcPort().setDpid(new Dpid(flowObj.getSrcSwitch()));
+ this.dataPath().srcPort().setPort(new Port(flowObj.getSrcPort()));
+ this.dataPath().dstPort().setDpid(new Dpid(flowObj.getDstSwitch()));
+ this.dataPath().dstPort().setPort(new Port(flowObj.getDstPort()));
+ //
+ // Extract the match conditions that are common for all Flow Entries
+ //
+ {
+ FlowEntryMatch match = new FlowEntryMatch();
+ String matchSrcMac = flowObj.getMatchSrcMac();
+ if (matchSrcMac != null)
+ match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
+ String matchDstMac = flowObj.getMatchDstMac();
+ if (matchDstMac != null)
+ match.enableDstMac(MACAddress.valueOf(matchDstMac));
+ Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null)
+ match.enableEthernetFrameType(matchEthernetFrameType);
+ Short matchVlanId = flowObj.getMatchVlanId();
+ if (matchVlanId != null)
+ match.enableVlanId(matchVlanId);
+ Byte matchVlanPriority = flowObj.getMatchVlanPriority();
+ if (matchVlanPriority != null)
+ match.enableVlanPriority(matchVlanPriority);
+ String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null)
+ match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+ String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null)
+ match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+ Byte matchIpProto = flowObj.getMatchIpProto();
+ if (matchIpProto != null)
+ match.enableIpProto(matchIpProto);
+ Byte matchIpToS = flowObj.getMatchIpToS();
+ if (matchIpToS != null)
+ match.enableIpToS(matchIpToS);
+ Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
+ if (matchSrcTcpUdpPort != null)
+ match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
+ Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
+ if (matchDstTcpUdpPort != null)
+ match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+
+ this.setFlowEntryMatch(match);
+ }
+
+ //
+ // Extract the actions for the first Flow Entry
+ //
+ {
+ FlowEntryActions actions = new FlowEntryActions();
+
+ String actionsStr = flowObj.getActions();
+ if (actions != null)
+ actions = new FlowEntryActions(actionsStr);
+
+ this.setFlowEntryActions(actions);
+ }
+
+ //
+ // Extract all Flow Entries
+ //
+ Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
+ for (IFlowEntry flowEntryObj : flowEntries) {
+ FlowEntry flowEntry = new FlowEntry();
+ flowEntry.setFlowEntryId(new FlowEntryId(flowEntryObj.getFlowEntryId()));
+ flowEntry.setDpid(new Dpid(flowEntryObj.getSwitchDpid()));
+
+ //
+ // Extract the match conditions
+ //
+ FlowEntryMatch match = new FlowEntryMatch();
+ //
+ Short matchInPort = flowEntryObj.getMatchInPort();
+ if (matchInPort != null)
+ match.enableInPort(new Port(matchInPort));
+ //
+ String matchSrcMac = flowEntryObj.getMatchSrcMac();
+ if (matchSrcMac != null)
+ match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
+ //
+ String matchDstMac = flowEntryObj.getMatchDstMac();
+ if (matchDstMac != null)
+ match.enableDstMac(MACAddress.valueOf(matchDstMac));
+ //
+ Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+ if (matchEthernetFrameType != null)
+ match.enableEthernetFrameType(matchEthernetFrameType);
+ //
+ Short matchVlanId = flowEntryObj.getMatchVlanId();
+ if (matchVlanId != null)
+ match.enableVlanId(matchVlanId);
+ //
+ Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
+ if (matchVlanPriority != null)
+ match.enableVlanPriority(matchVlanPriority);
+ //
+ String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+ if (matchSrcIPv4Net != null)
+ match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+ //
+ String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+ if (matchDstIPv4Net != null)
+ match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+ //
+ Byte matchIpProto = flowEntryObj.getMatchIpProto();
+ if (matchIpProto != null)
+ match.enableIpProto(matchIpProto);
+ //
+ Byte matchIpToS = flowEntryObj.getMatchIpToS();
+ if (matchIpToS != null)
+ match.enableIpToS(matchIpToS);
+ //
+ Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
+ if (matchSrcTcpUdpPort != null)
+ match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
+ //
+ Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
+ if (matchDstTcpUdpPort != null)
+ match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+ //
+ flowEntry.setFlowEntryMatch(match);
+
+ //
+ // Extract the actions
+ //
+ {
+ FlowEntryActions actions = new FlowEntryActions();
+
+ String actionsStr = flowObj.getActions();
+ if (actions != null)
+ actions = new FlowEntryActions(actionsStr);
+
+ flowEntry.setFlowEntryActions(actions);
+ }
+
+ String userState = flowEntryObj.getUserState();
+ flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
+ String switchState = flowEntryObj.getSwitchState();
+ flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
+ //
+ // TODO: Take care of the FlowEntryErrorState.
+ //
+ this.dataPath().flowEntries().add(flowEntry);
+ }
+ }
+
+ /**
+ * Get the flow path Flow ID.
+ *
+ * @return the flow path Flow ID.
+ */
+ @JsonProperty("flowId")
+ public FlowId flowId() { return flowId; }
+
+ /**
+ * Set the flow path Flow ID.
+ *
+ * @param flowId the flow path Flow ID to set.
+ */
+ @JsonProperty("flowId")
+ public void setFlowId(FlowId flowId) {
+ this.flowId = flowId;
+ }
+
+ /**
+ * Get the Caller ID of the flow path installer.
+ *
+ * @return the Caller ID of the flow path installer.
+ */
+ @JsonProperty("installerId")
+ public CallerId installerId() { return installerId; }
+
+ /**
+ * Set the Caller ID of the flow path installer.
+ *
+ * @param installerId the Caller ID of the flow path installer.
+ */
+ @JsonProperty("installerId")
+ public void setInstallerId(CallerId installerId) {
+ this.installerId = installerId;
+ }
+
+ /**
+ * Get the flow path flags.
+ *
+ * @return the flow path flags.
+ */
+ @JsonProperty("flowPathFlags")
+ public FlowPathFlags flowPathFlags() { return flowPathFlags; }
+
+ /**
+ * Set the flow path flags.
+ *
+ * @param flowPathFlags the flow path flags to set.
+ */
+ @JsonProperty("flowPathFlags")
+ public void setFlowPathFlags(FlowPathFlags flowPathFlags) {
+ this.flowPathFlags = flowPathFlags;
+ }
+
+ /**
+ * Get the flow path's data path.
+ *
+ * @return the flow path's data path.
+ */
+ @JsonProperty("dataPath")
+ public DataPath dataPath() { return dataPath; }
+
+ /**
+ * Set the flow path's data path.
+ *
+ * @param dataPath the flow path's data path to set.
+ */
+ @JsonProperty("dataPath")
+ public void setDataPath(DataPath dataPath) {
+ this.dataPath = dataPath;
+ }
+
+ /**
+ * Get the flow path's match conditions common for all Flow Entries.
+ *
+ * @return the flow path's match conditions common for all Flow Entries.
+ */
+ @JsonProperty("flowEntryMatch")
+ public FlowEntryMatch flowEntryMatch() { return flowEntryMatch; }
+
+ /**
+ * Set the flow path's match conditions common for all Flow Entries.
+ *
+ * @param flowEntryMatch the flow path's match conditions common for all
+ * Flow Entries.
+ */
+ @JsonProperty("flowEntryMatch")
+ public void setFlowEntryMatch(FlowEntryMatch flowEntryMatch) {
+ this.flowEntryMatch = flowEntryMatch;
+ }
+
+ /**
+ * Get the flow path's flow entry actions for the first Flow Entry.
+ *
+ * @return the flow path's flow entry actions for the first Flow Entry.
+ */
+ @JsonProperty("flowEntryActions")
+ public FlowEntryActions flowEntryActions() {
+ return flowEntryActions;
+ }
+
+ /**
+ * Set the flow path's flow entry actions for the first Flow Entry.
+ *
+ * @param flowEntryActions the flow path's flow entry actions for the first
+ * Flow Entry.
+ */
+ @JsonProperty("flowEntryActions")
+ public void setFlowEntryActions(FlowEntryActions flowEntryActions) {
+ this.flowEntryActions = flowEntryActions;
+ }
+
+ /**
+ * Convert the flow path to a string.
+ *
+ * The string has the following form:
+ * [flowId=XXX installerId=XXX flowPathFlags=XXX dataPath=XXX
+ * flowEntryMatch=XXX flowEntryActions=XXX]
+ *
+ * @return the flow path as a string.
+ */
+ @Override
+ public String toString() {
+ String ret = "[flowId=" + this.flowId.toString();
+ ret += " installerId=" + this.installerId.toString();
+ ret += " flowPathFlags=" + this.flowPathFlags.toString();
+ if (dataPath != null)
+ ret += " dataPath=" + this.dataPath.toString();
+ if (flowEntryMatch != null)
+ ret += " flowEntryMatch=" + this.flowEntryMatch.toString();
+ if (flowEntryActions != null)
+ ret += " flowEntryActions=" + this.flowEntryActions.toString();
+ ret += "]";
+ return ret;
+ }
+
+ /**
+ * CompareTo method to order flowPath by Id
+ */
+ @Override
+ public int compareTo(FlowPath f) {
+ return (int) (this.flowId.value() - f.flowId.value());
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java
new file mode 100644
index 0000000..63241f0
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java
@@ -0,0 +1,128 @@
+package net.onrc.onos.ofcontroller.util;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * The class representing the Flow Path flags.
+ */
+public class FlowPathFlags {
+ private long flags;
+
+ // Discard the first-hop Flow Entry
+ private final long DISCARD_FIRST_HOP_ENTRY = (1 << 0);
+
+ // Keep only the first-hop Flow Entry
+ private final long KEEP_ONLY_FIRST_HOP_ENTRY = (1 << 1);
+
+ /**
+ * Default constructor.
+ */
+ public FlowPathFlags() {
+ this.flags = 0;
+ }
+
+ /**
+ * Constructor for given flags.
+ *
+ * @param flags the flags value to set.
+ */
+ public FlowPathFlags(long flags) {
+ this.flags = flags;
+ }
+
+ /**
+ * Constructor for given flags as a string.
+ *
+ * The string value should contain the name of each flags to set. E.g.:
+ * "DISCARD_FIRST_HOP_ENTRY,KEEP_ONLY_FIRST_HOP_ENTRY"
+ * @param flagsStr the string value of the flags to set.
+ */
+ public FlowPathFlags(String flagsStr) {
+ this.setFlagsStr(flagsStr);
+ }
+
+ /**
+ * Get the flags.
+ *
+ * @return the flags.
+ */
+ @JsonProperty("flags")
+ public long flags() { return flags; }
+
+ /**
+ * Set the flags.
+ *
+ * @param flags the flags value to set.
+ */
+ @JsonProperty("flags")
+ public void setFlags(long flags) {
+ this.flags = flags;
+ }
+
+ /**
+ * Set the flags as a string.
+ *
+ * The string value should contain the name of each flags to set. E.g.:
+ * "DISCARD_FIRST_HOP_ENTRY,KEEP_ONLY_FIRST_HOP_ENTRY"
+ * @param flagsStr the string value of the flags to set.
+ */
+ @JsonProperty("flagsStr")
+ public void setFlagsStr(String flagsStr) {
+ this.flags = 0L;
+
+ // Test all flags
+ if (flagsStr.contains("DISCARD_FIRST_HOP_ENTRY"))
+ this.flags |= DISCARD_FIRST_HOP_ENTRY;
+ if (flagsStr.contains("KEEP_ONLY_FIRST_HOP_ENTRY"))
+ this.flags |= KEEP_ONLY_FIRST_HOP_ENTRY;
+ }
+
+ /**
+ * Test whether the DISCARD_FIRST_HOP_ENTRY flag is set.
+ *
+ * @return true if the DISCARD_FIRST_HOP_ENTRY flag is set,
+ * otherwise false.
+ */
+ public boolean isDiscardFirstHopEntry() {
+ return ((flags & DISCARD_FIRST_HOP_ENTRY) != 0);
+ }
+
+ /**
+ * Test whether the KEEP_ONLY_FIRST_HOP_ENTRY flag is set.
+ *
+ * @return true if the KEEP_ONLY_FIRST_HOP_ENTRY flag is set,
+ * otherwise false.
+ */
+ public boolean isKeepOnlyFirstHopEntry() {
+ return ((flags & KEEP_ONLY_FIRST_HOP_ENTRY) != 0);
+ }
+
+ /**
+ * Convert the Flow Path Flags to a string.
+ *
+ * The string has the following form:
+ * [flags=DISCARD_FIRST_HOP_ENTRY,KEEP_ONLY_FIRST_HOP_ENTRY]
+ *
+ * @return the Flow Path flags as a string.
+ */
+ @Override
+ public String toString() {
+ String flagsStr = null;
+ String ret = "[flags=";
+
+ // Test all flags
+ if ((this.flags & DISCARD_FIRST_HOP_ENTRY) != 0) {
+ if (flagsStr != null)
+ flagsStr += ",";
+ flagsStr += "DISCARD_FIRST_HOP_ENTRY";
+ }
+ if ((this.flags & KEEP_ONLY_FIRST_HOP_ENTRY) != 0) {
+ if (flagsStr != null)
+ flagsStr += ",";
+ flagsStr += "KEEP_ONLY_FIRST_HOP_ENTRY";
+ }
+ ret += "]";
+
+ return ret;
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/util/IPv4.java b/src/main/java/net/onrc/onos/ofcontroller/util/IPv4.java
similarity index 83%
rename from src/main/java/net/floodlightcontroller/util/IPv4.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/IPv4.java
index ef3a1e5..119165c 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv4.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/IPv4.java
@@ -1,9 +1,8 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
-import net.floodlightcontroller.util.serializers.IPv4Deserializer;
-import net.floodlightcontroller.util.serializers.IPv4Serializer;
+import net.onrc.onos.ofcontroller.util.serializers.IPv4Deserializer;
+import net.onrc.onos.ofcontroller.util.serializers.IPv4Serializer;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -23,6 +22,15 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public IPv4(IPv4 other) {
+ this.value = other.value;
+ }
+
+ /**
* Constructor from an integer value.
*
* @param value the value to use.
diff --git a/src/main/java/net/floodlightcontroller/util/IPv4Net.java b/src/main/java/net/onrc/onos/ofcontroller/util/IPv4Net.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/IPv4Net.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/IPv4Net.java
index 824e3e2..9ce247c 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv4Net.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/IPv4Net.java
@@ -1,10 +1,8 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
-import net.floodlightcontroller.util.IPv4;
-import net.floodlightcontroller.util.serializers.IPv4NetDeserializer;
-import net.floodlightcontroller.util.serializers.IPv4NetSerializer;
+import net.onrc.onos.ofcontroller.util.serializers.IPv4NetDeserializer;
+import net.onrc.onos.ofcontroller.util.serializers.IPv4NetSerializer;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -25,6 +23,17 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public IPv4Net(IPv4Net other) {
+ if (other.address != null)
+ this.address = new IPv4(other.address);
+ this.prefixLen = other.prefixLen;
+ }
+
+ /**
* Constructor for a given address and prefix length.
*
* @param address the address to use.
diff --git a/src/main/java/net/floodlightcontroller/util/IPv6.java b/src/main/java/net/onrc/onos/ofcontroller/util/IPv6.java
similarity index 87%
rename from src/main/java/net/floodlightcontroller/util/IPv6.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/IPv6.java
index eda4502..f5dae11 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv6.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/IPv6.java
@@ -1,12 +1,11 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
-import org.openflow.util.HexString;
-import net.floodlightcontroller.util.serializers.IPv6Deserializer;
-import net.floodlightcontroller.util.serializers.IPv6Serializer;
+import net.onrc.onos.ofcontroller.util.serializers.IPv6Deserializer;
+import net.onrc.onos.ofcontroller.util.serializers.IPv6Serializer;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.openflow.util.HexString;
/**
* The class representing an IPv6 address.
@@ -26,6 +25,16 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public IPv6(IPv6 other) {
+ this.valueHigh = other.valueHigh;
+ this.valueLow = other.valueLow;
+ }
+
+ /**
* Constructor from integer values.
*
* @param valueHigh the higher (more significant) 64 bits of the address.
diff --git a/src/main/java/net/floodlightcontroller/util/IPv6Net.java b/src/main/java/net/onrc/onos/ofcontroller/util/IPv6Net.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/IPv6Net.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/IPv6Net.java
index b6f7d67..65ffe54 100644
--- a/src/main/java/net/floodlightcontroller/util/IPv6Net.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/IPv6Net.java
@@ -1,10 +1,8 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
-import net.floodlightcontroller.util.IPv6;
-import net.floodlightcontroller.util.serializers.IPv6NetDeserializer;
-import net.floodlightcontroller.util.serializers.IPv6NetSerializer;
+import net.onrc.onos.ofcontroller.util.serializers.IPv6NetDeserializer;
+import net.onrc.onos.ofcontroller.util.serializers.IPv6NetSerializer;
-import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -25,6 +23,17 @@
}
/**
+ * Copy constructor.
+ *
+ * @param other the object to copy from.
+ */
+ public IPv6Net(IPv6Net other) {
+ if (other.address != null)
+ this.address = new IPv6(other.address);
+ this.prefixLen = other.prefixLen;
+ }
+
+ /**
* Constructor for a given address and prefix length.
*
* @param address the address to use.
diff --git a/src/main/java/net/floodlightcontroller/util/Port.java b/src/main/java/net/onrc/onos/ofcontroller/util/Port.java
similarity index 95%
rename from src/main/java/net/floodlightcontroller/util/Port.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/Port.java
index 41f0d55..bb4851c 100644
--- a/src/main/java/net/floodlightcontroller/util/Port.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/Port.java
@@ -1,4 +1,4 @@
-package net.floodlightcontroller.util;
+package net.onrc.onos.ofcontroller.util;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -78,9 +78,9 @@
}
/**
- * Constructor from another entry.
+ * Copy constructor.
*
- * @param other the other entry to use.
+ * @param other the object to copy from.
*/
public Port(Port other) {
this.value = other.value();
diff --git a/src/main/java/net/floodlightcontroller/util/SwitchPort.java b/src/main/java/net/onrc/onos/ofcontroller/util/SwitchPort.java
similarity index 93%
rename from src/main/java/net/floodlightcontroller/util/SwitchPort.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/SwitchPort.java
index 027b681..95a934f 100644
--- a/src/main/java/net/floodlightcontroller/util/SwitchPort.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/SwitchPort.java
@@ -1,7 +1,4 @@
-package net.floodlightcontroller.util;
-
-import net.floodlightcontroller.util.Dpid;
-import net.floodlightcontroller.util.Port;
+package net.onrc.onos.ofcontroller.util;
import org.codehaus.jackson.annotate.JsonProperty;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/DpidDeserializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/DpidDeserializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/DpidDeserializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/DpidDeserializer.java
index 9297f56..9075f96 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/DpidDeserializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/DpidDeserializer.java
@@ -1,17 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
-import org.codehaus.jackson.JsonNode;
+import net.onrc.onos.ofcontroller.util.Dpid;
+
import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
-
-import net.floodlightcontroller.util.Dpid;
-
+import org.codehaus.jackson.map.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/DpidSerializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/DpidSerializer.java
index 06fab62..7ece4d3 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/DpidSerializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/DpidSerializer.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
+import net.onrc.onos.ofcontroller.util.Dpid;
+
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
-import net.floodlightcontroller.util.Dpid;
-
/**
* Serialize a DPID as a string.
*/
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdDeserializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowEntryIdDeserializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdDeserializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowEntryIdDeserializer.java
index e6481d5..72ddfea 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdDeserializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowEntryIdDeserializer.java
@@ -1,17 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
-import org.codehaus.jackson.JsonNode;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+
import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
-
-import net.floodlightcontroller.util.FlowEntryId;
-
+import org.codehaus.jackson.map.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdSerializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowEntryIdSerializer.java
similarity index 84%
rename from src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdSerializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowEntryIdSerializer.java
index 4b6583c..bf73265 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowEntryIdSerializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowEntryIdSerializer.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
-import net.floodlightcontroller.util.FlowEntryId;
-
/**
* Serialize a Flow Entry ID as a hexadecimal string.
*/
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowIdDeserializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowIdDeserializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/FlowIdDeserializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowIdDeserializer.java
index a7f53d4..eb93a23 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowIdDeserializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowIdDeserializer.java
@@ -1,17 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
-import org.codehaus.jackson.JsonNode;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
-
-import net.floodlightcontroller.util.FlowId;
-
+import org.codehaus.jackson.map.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowIdSerializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowIdSerializer.java
index 6f1a6f6..34f6e05 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/FlowIdSerializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/FlowIdSerializer.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
-import net.floodlightcontroller.util.FlowId;
-
/**
* Serialize a Flow ID as a hexadecimal string.
*/
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4Deserializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4Deserializer.java
index 275f9f0..daf90af 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Deserializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4Deserializer.java
@@ -1,17 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
-import org.codehaus.jackson.JsonNode;
+import net.onrc.onos.ofcontroller.util.IPv4;
+
import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
-
-import net.floodlightcontroller.util.IPv4;
-
+import org.codehaus.jackson.map.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4NetDeserializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4NetDeserializer.java
index 3c36870..f67ab38 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetDeserializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4NetDeserializer.java
@@ -1,17 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
-import org.codehaus.jackson.JsonNode;
+import net.onrc.onos.ofcontroller.util.IPv4Net;
+
import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
-
-import net.floodlightcontroller.util.IPv4Net;
-
+import org.codehaus.jackson.map.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4NetSerializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4NetSerializer.java
index 5c5e1d0..0454a58 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv4NetSerializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4NetSerializer.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
+import net.onrc.onos.ofcontroller.util.IPv4Net;
+
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
-import net.floodlightcontroller.util.IPv4Net;
-
/**
* Serialize an IPv4Net address as a string.
*/
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4Serializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4Serializer.java
index ba7d825..aefc8a0 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv4Serializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv4Serializer.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
+import net.onrc.onos.ofcontroller.util.IPv4;
+
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
-import net.floodlightcontroller.util.IPv4;
-
/**
* Serialize an IPv4 address as a string.
*/
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6Deserializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6Deserializer.java
index 818de30..7e3e5f6 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Deserializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6Deserializer.java
@@ -1,17 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
-import org.codehaus.jackson.JsonNode;
+import net.onrc.onos.ofcontroller.util.IPv6;
+
import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
-
-import net.floodlightcontroller.util.IPv6;
-
+import org.codehaus.jackson.map.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6NetDeserializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6NetDeserializer.java
index 375dc26..d7631b3 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetDeserializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6NetDeserializer.java
@@ -1,17 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
-import org.codehaus.jackson.JsonNode;
+import net.onrc.onos.ofcontroller.util.IPv6Net;
+
import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
-
-import net.floodlightcontroller.util.IPv6Net;
-
+import org.codehaus.jackson.map.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6NetSerializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6NetSerializer.java
index fc5d262..06dc6cf 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv6NetSerializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6NetSerializer.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
+import net.onrc.onos.ofcontroller.util.IPv6Net;
+
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
-import net.floodlightcontroller.util.IPv6Net;
-
/**
* Serialize an IPv6Net address as a string.
*/
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6Serializer.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6Serializer.java
index 0b08a63..b6709b8 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/IPv6Serializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/IPv6Serializer.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
+import net.onrc.onos.ofcontroller.util.IPv6;
+
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
-import net.floodlightcontroller.util.IPv6;
-
/**
* Serialize an IPv6 address as a string.
*/
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/MACAddressDeserializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/MACAddressDeserializer.java
similarity index 89%
rename from src/main/java/net/floodlightcontroller/util/serializers/MACAddressDeserializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/MACAddressDeserializer.java
index 35b384d..dc4a0e2 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/MACAddressDeserializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/MACAddressDeserializer.java
@@ -1,17 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.ObjectCodec;
-import org.codehaus.jackson.map.JsonDeserializer;
-import org.codehaus.jackson.map.DeserializationContext;
-
import net.floodlightcontroller.util.MACAddress;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.map.DeserializationContext;
+import org.codehaus.jackson.map.JsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/src/main/java/net/floodlightcontroller/util/serializers/MACAddressSerializer.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/MACAddressSerializer.java
similarity index 92%
rename from src/main/java/net/floodlightcontroller/util/serializers/MACAddressSerializer.java
rename to src/main/java/net/onrc/onos/ofcontroller/util/serializers/MACAddressSerializer.java
index dec2596..9c0e225 100644
--- a/src/main/java/net/floodlightcontroller/util/serializers/MACAddressSerializer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/MACAddressSerializer.java
@@ -1,14 +1,14 @@
-package net.floodlightcontroller.util.serializers;
+package net.onrc.onos.ofcontroller.util.serializers;
import java.io.IOException;
+import net.floodlightcontroller.util.MACAddress;
+
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
-import net.floodlightcontroller.util.MACAddress;
-
/**
* Serialize a MAC address as a string.
*/
diff --git a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
index e48c519..640a49d 100644
--- a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
@@ -116,10 +116,22 @@
throw new RuntimeException("Not yet implemented");
}
+ private long blockTop = 0L;
+ private static final long BLOCK_SIZE = 0x1000000L;
+
+ /**
+ * Returns a block of IDs which are unique and unused.
+ * Range of IDs is fixed size and is assigned incrementally as this method called.
+ */
@Override
- public IdBlock allocateUniqueIdBlock(){
- //XXX Not exactly unique...
- return new IdBlock(0L, 0x10000000L, 0x10000000L);
+ public synchronized IdBlock allocateUniqueIdBlock(){
+ long blockHead = blockTop;
+ long blockTail = blockTop + BLOCK_SIZE;
+
+ IdBlock block = new IdBlock(blockHead, blockTail - 1, BLOCK_SIZE);
+ blockTop = blockTail;
+
+ return block;
}
@Override
diff --git a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
index 82259a9..2d2083f 100644
--- a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
@@ -109,13 +109,7 @@
}
}
-
- /**
- * Listens for changes to the switch znodes in Zookeeper. This maintains
- * the second level of PathChildrenCaches that hold the controllers
- * contending for each switch - there's one for each switch.
- */
- PathChildrenCacheListener switchPathCacheListener = new PathChildrenCacheListener() {
+ protected class SwitchPathCacheListener implements PathChildrenCacheListener {
@Override
public void childEvent(CuratorFramework client,
PathChildrenCacheEvent event) throws Exception {
@@ -158,6 +152,12 @@
}
};
+ /**
+ * Listens for changes to the switch znodes in Zookeeper. This maintains
+ * the second level of PathChildrenCaches that hold the controllers
+ * contending for each switch - there's one for each switch.
+ */
+ PathChildrenCacheListener switchPathCacheListener = new SwitchPathCacheListener();
protected ServiceDiscovery<ControllerService> serviceDiscovery;
protected ServiceCache<ControllerService> serviceCache;
@@ -379,6 +379,12 @@
return data;
}
+ /**
+ * Returns a block of IDs which are unique and unused.
+ * Range of IDs is fixed size and is assigned incrementally as this method called.
+ * Since the range of IDs is managed by Zookeeper in distributed way, this method may block when
+ * requests come up simultaneously.
+ */
public IdBlock allocateUniqueIdBlock(){
try {
AtomicValue<Long> result = null;
diff --git a/src/main/java/net/onrc/onos/util/GraphDBConnection.java b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
deleted file mode 100644
index 7ea0ab8..0000000
--- a/src/main/java/net/onrc/onos/util/GraphDBConnection.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package net.onrc.onos.util;
-
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.TransactionalGraph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
-import com.tinkerpop.frames.FramedGraph;
-
-public class GraphDBConnection {
- public enum Transaction {
- COMMIT,
- ROLLBACK
- }
- public enum GenerateEvent {
- TRUE,
- FALSE
- }
- class TransactionHandle {
- protected TransactionalGraph tr;
- public void create() {
- tr = graph.newTransaction();
- }
- }
- protected static Logger log = LoggerFactory.getLogger(GraphDBConnection.class);
- private static GraphDBConnection singleton = new GraphDBConnection( );
- private static TitanGraph graph;
- private static EventTransactionalGraph<TitanGraph> eg;
- private static GraphDBUtils utils;
- private static String configFile;
-
-
- /* A private Constructor prevents any other
- * class from instantiating.
- */
- private GraphDBConnection(){ }
-
- /* Static 'instance' method */
- public static synchronized GraphDBConnection getInstance(final String conf) {
- if (GraphDBConnection.configFile == null || GraphDBConnection.configFile.isEmpty()) {
- GraphDBConnection.configFile = conf;
- log.debug("GraphDBConnection::Setting Config File {}", GraphDBConnection.configFile);
- }
- if (!GraphDBConnection.configFile.isEmpty() &&
- (graph == null||graph.isOpen() == Boolean.FALSE)) {
- graph = TitanFactory.open(GraphDBConnection.configFile);
- // FIXME: Creation on Indexes should be done only once
- Set<String> s = graph.getIndexedKeys(Vertex.class);
- if (!s.contains("dpid")) {
- graph.createKeyIndex("dpid", Vertex.class);
- }
- if (!s.contains("type")) {
- graph.createKeyIndex("type", Vertex.class);
- }
- if (!s.contains("dl_address")) {
- graph.createKeyIndex("dl_address", Vertex.class);
- }
- if (!s.contains("flow_id")) {
- graph.createKeyIndex("flow_id", Vertex.class);
- }
- if (!s.contains("flow_entry_id")) {
- graph.createKeyIndex("flow_entry_id",
- Vertex.class);
- }
- if (!s.contains("switch_state")) {
- graph.createKeyIndex("switch_state",
- Vertex.class);
- }
- graph.commit();
- eg = new EventTransactionalGraph<TitanGraph>(graph);
- }
- if (utils == null) {
- utils = new GraphDBUtils();
- }
- return singleton;
- }
-
- public IDBUtils utils() {
- return utils;
- }
-
- public FramedGraph<TitanGraph> getFramedGraph() {
-
- if (isValid()) {
- FramedGraph<TitanGraph> fg = new FramedGraph<TitanGraph>(graph);
- return fg;
- } else {
- log.error("new FramedGraph failed");
- return null;
- }
- }
-
- protected EventTransactionalGraph<TitanGraph> getEventGraph() {
-
- if (isValid()) {
- return eg;
- } else {
- return null;
- }
- }
-
- public void addEventListener(final LocalGraphChangedListener listener) {
- EventTransactionalGraph<TitanGraph> eg = this.getEventGraph();
- eg.addListener(listener);
- log.debug("Registered listener {}",listener.getClass());
- }
-
- public Boolean isValid() {
-
- return (graph != null||graph.isOpen());
- }
-
- public void startTx() {
-
-
- }
-
- public void endTx(Transaction tx) {
- try {
- switch (tx) {
- case COMMIT:
- graph.commit();
- case ROLLBACK:
- graph.rollback();
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- log.error("{}",e.toString());
- }
- }
-
- public void endTx(TransactionHandle tr, Transaction tx) {
- switch (tx) {
- case COMMIT:
- if (tr != null && tr.tr != null) {
- tr.tr.commit();
- } else {
- graph.commit();
- }
- case ROLLBACK:
- if (tr != null && tr.tr != null) {
- tr.tr.rollback();
- } else {
- graph.rollback();
- }
- }
- }
-
- public void endTx(Transaction tx, GenerateEvent fire) {
-
- try {
- if (fire.equals(GenerateEvent.TRUE)) {
- switch (tx) {
- case COMMIT:
- eg.commit();
- case ROLLBACK:
- eg.rollback();
- }
- } else {
- endTx(tx);
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- public void close() {
- endTx(Transaction.COMMIT);
- }
-}
diff --git a/src/main/java/net/onrc/onos/util/GraphDBUtils.java b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
deleted file mode 100644
index 6601bf9..0000000
--- a/src/main/java/net/onrc/onos/util/GraphDBUtils.java
+++ /dev/null
@@ -1,250 +0,0 @@
-package net.onrc.onos.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
-import net.floodlightcontroller.util.FlowEntryId;
-import net.floodlightcontroller.util.FlowId;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.frames.FramedGraph;
-import com.tinkerpop.frames.structures.FramedVertexIterable;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-
-public class GraphDBUtils implements IDBUtils {
-
- @Override
- public ISwitchObject newSwitch(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- ISwitchObject obj = fg.addVertex(null,ISwitchObject.class);
- return obj;
- }
-
- @Override
- public void removeSwitch(GraphDBConnection conn, ISwitchObject sw) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- fg.removeVertex(sw.asVertex());
- }
-
- @Override
- public ISwitchObject searchSwitch(GraphDBConnection conn, String dpid) {
- // TODO Auto-generated method stub
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
- return (fg != null && fg.getVertices("dpid",dpid).iterator().hasNext()) ?
- fg.getVertices("dpid",dpid,ISwitchObject.class).iterator().next() : null;
-
- }
-
- @Override
- public IDeviceObject searchDevice(GraphDBConnection conn, String macAddr) {
- // TODO Auto-generated method stub
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- return (fg != null && fg.getVertices("dl_address",macAddr).iterator().hasNext()) ? fg.getVertices("dl_address",macAddr,
- IDeviceObject.class).iterator().next() : null;
-
- }
-
- @Override
- public IPortObject searchPort(GraphDBConnection conn, String dpid, short number) {
- ISwitchObject sw = searchSwitch(conn, dpid);
-// if (sw != null) {
-//
-// IPortObject port = null;
-//
- // Requires Frames 2.3.0
-//
-// try {
-// port = sw.getPort(number);
-// } catch (Exception e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// }
-//
-// return port;
-// }
-
- if (sw != null) {
- GremlinPipeline<Vertex, IPortObject> pipe = new GremlinPipeline<Vertex, IPortObject>();
- pipe.start(sw.asVertex());
- pipe.out("on").has("number", number);
- FramedVertexIterable<IPortObject> r = new FramedVertexIterable<IPortObject>(conn.getFramedGraph(), (Iterable) pipe, IPortObject.class);
- return r != null && r.iterator().hasNext() ? r.iterator().next() : null;
- }
- return null;
- }
-
- @Override
- public IPortObject newPort(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- IPortObject obj = fg.addVertex(null,IPortObject.class);
- return obj;
- }
-
- @Override
- public IDeviceObject newDevice(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- IDeviceObject obj = fg.addVertex(null,IDeviceObject.class);
- return obj;
- }
-
- @Override
- public void removePort(GraphDBConnection conn, IPortObject port) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-// EventGraph<TitanGraph> eg = conn.getEventGraph();
- if (fg != null) fg.removeVertex(port.asVertex());
- }
-
- @Override
- public void removeDevice(GraphDBConnection conn, IDeviceObject dev) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- if (fg != null) fg.removeVertex(dev.asVertex());
- }
-
- @Override
- public Iterable<IDeviceObject> getDevices(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- return fg != null ? fg.getVertices("type","device",IDeviceObject.class) : null;
- }
-
- @Override
- public IFlowPath searchFlowPath(GraphDBConnection conn,
- FlowId flowId) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
- return fg.getVertices("flow_id", flowId.toString()).iterator().hasNext() ?
- fg.getVertices("flow_id", flowId.toString(),
- IFlowPath.class).iterator().next() : null;
- }
-
- @Override
- public IFlowPath newFlowPath(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- IFlowPath flowPath = fg.addVertex(null, IFlowPath.class);
- return flowPath;
- }
-
- @Override
- public void removeFlowPath(GraphDBConnection conn,
- IFlowPath flowPath) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- fg.removeVertex(flowPath.asVertex());
- }
-
- @Override
- public IFlowPath getFlowPathByFlowEntry(GraphDBConnection conn,
- IFlowEntry flowEntry) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- GremlinPipeline<Vertex, IFlowPath> pipe = new GremlinPipeline<Vertex, IFlowPath>();
- pipe.start(flowEntry.asVertex());
- pipe.out("flow");
- FramedVertexIterable<IFlowPath> r = new FramedVertexIterable(conn.getFramedGraph(), (Iterable) pipe, IFlowPath.class);
- return r.iterator().hasNext() ? r.iterator().next() : null;
- }
-
- @Override
- public Iterable<IFlowPath> getAllFlowPaths(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- Iterable<IFlowPath> flowPaths = fg.getVertices("type", "flow", IFlowPath.class);
-
- List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();
-
- for (IFlowPath fp: flowPaths) {
- if (fp.getFlowId() != null) {
- nonNullFlows.add(fp);
- }
- }
- return nonNullFlows;
- }
-
- @Override
- public IFlowEntry searchFlowEntry(GraphDBConnection conn,
- FlowEntryId flowEntryId) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
- return fg.getVertices("flow_entry_id", flowEntryId.toString()).iterator().hasNext() ?
- fg.getVertices("flow_entry_id", flowEntryId.toString(),
- IFlowEntry.class).iterator().next() : null;
- }
-
- @Override
- public IFlowEntry newFlowEntry(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- IFlowEntry flowEntry = fg.addVertex(null, IFlowEntry.class);
- return flowEntry;
- }
-
- @Override
- public void removeFlowEntry(GraphDBConnection conn,
- IFlowEntry flowEntry) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- fg.removeVertex(flowEntry.asVertex());
- }
-
- @Override
- public Iterable<IFlowEntry> getAllFlowEntries(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
- return fg.getVertices("type", "flow_entry", IFlowEntry.class);
- }
-
- @Override
- public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- //TODO: Should use an enum for flow_switch_state
- return fg.getVertices("switch_state", "FE_SWITCH_NOT_UPDATED", IFlowEntry.class);
- }
-
- @Override
- public Iterable<ISwitchObject> getActiveSwitches(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
- List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
-
- for (ISwitchObject sw: switches) {
- if(sw.getState().equals(SwitchState.ACTIVE.toString())) {
- activeSwitches.add(sw);
- }
- }
- return activeSwitches;
- }
-
- @Override
- public Iterable<ISwitchObject> getAllSwitches(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
- return switches;
- }
-
- @Override
- public Iterable<ISwitchObject> getInactiveSwitches(GraphDBConnection conn) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
- List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();
-
- for (ISwitchObject sw: switches) {
- if(sw.getState().equals(SwitchState.INACTIVE.toString())) {
- inactiveSwitches.add(sw);
- }
- }
- return inactiveSwitches;
- }
-
- @Override
- public ISwitchObject searchActiveSwitch(GraphDBConnection conn, String dpid) {
-
- ISwitchObject sw = searchSwitch(conn, dpid);
- if ((sw != null) &&
- sw.getState().equals(SwitchState.ACTIVE.toString())) {
- return sw;
- }
- return null;
- }
-}
diff --git a/src/main/java/net/onrc/onos/util/IDBUtils.java b/src/main/java/net/onrc/onos/util/IDBUtils.java
deleted file mode 100644
index 35803d2..0000000
--- a/src/main/java/net/onrc/onos/util/IDBUtils.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package net.onrc.onos.util;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.util.FlowEntryId;
-import net.floodlightcontroller.util.FlowId;
-
-public interface IDBUtils {
- public ISwitchObject searchSwitch(GraphDBConnection conn, String dpid);
- public ISwitchObject searchActiveSwitch(GraphDBConnection conn, String dpid);
- public Iterable<ISwitchObject> getActiveSwitches(GraphDBConnection conn);
- public Iterable<ISwitchObject> getAllSwitches(GraphDBConnection conn);
- public Iterable<ISwitchObject> getInactiveSwitches(GraphDBConnection conn);
-
-
- public IDeviceObject searchDevice(GraphDBConnection conn, String macAddr);
- public IDeviceObject newDevice(GraphDBConnection conn);
- public void removeDevice(GraphDBConnection conn, IDeviceObject dev);
- public IPortObject searchPort(GraphDBConnection conn, String dpid, short number);
- public Iterable<IDeviceObject> getDevices(GraphDBConnection conn);
- public IFlowPath searchFlowPath(GraphDBConnection conn, FlowId flowId);
- public IFlowPath newFlowPath(GraphDBConnection conn);
- public void removeFlowPath(GraphDBConnection conn, IFlowPath flowPath);
- public IFlowPath getFlowPathByFlowEntry(GraphDBConnection conn,
- IFlowEntry flowEntry);
- public Iterable<IFlowPath> getAllFlowPaths(GraphDBConnection conn);
- public IFlowEntry searchFlowEntry(GraphDBConnection conn,
- FlowEntryId flowEntryId);
- public IFlowEntry newFlowEntry(GraphDBConnection conn);
- public void removeFlowEntry(GraphDBConnection conn,
- IFlowEntry flowEntry);
- public Iterable<IFlowEntry> getAllFlowEntries(GraphDBConnection conn);
- public IPortObject newPort(GraphDBConnection conn);
- ISwitchObject newSwitch(GraphDBConnection conn);
- void removePort(GraphDBConnection conn, IPortObject port);
- void removeSwitch(GraphDBConnection conn, ISwitchObject sw);
- Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries(GraphDBConnection conn);
-}
diff --git a/src/main/python/PythonClient.py b/src/main/python/PythonClient.py
deleted file mode 100644
index 5c9890e..0000000
--- a/src/main/python/PythonClient.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-sys.path.append('../../../target/gen-py')
-
-from packetstreamer import PacketStreamer
-from packetstreamer.ttypes import *
-
-from thrift import Thrift
-from thrift.transport import TSocket
-from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol
-
-try:
-
- # Make socket
- transport = TSocket.TSocket('localhost', 9090)
-
- # Buffering is critical. Raw sockets are very slow
- transport = TTransport.TFramedTransport(transport)
-
- # Wrap in a protocol
- protocol = TBinaryProtocol.TBinaryProtocol(transport)
-
- # Create a client to use the protocol encoder
- client = PacketStreamer.Client(protocol)
-
- # Connect!
- transport.open()
-
- while 1:
- packets = client.getPackets("session1")
- print 'session1 packets num: %d' % (len(packets))
- count = 1
- for packet in packets:
- print "Packet %d: %s"% (count, packet)
- if "FilterTimeout" in packet:
- sys.exit()
- count += 1
-
- # Close!
- transport.close()
-
-except Thrift.TException, tx:
- print '%s' % (tx.message)
-
-except KeyboardInterrupt, e:
- print 'Bye-bye'
diff --git a/src/main/python/PythonServer.py b/src/main/python/PythonServer.py
deleted file mode 100644
index c3c844e..0000000
--- a/src/main/python/PythonServer.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import logging
-sys.path.append('../../../target/gen-py')
-
-from packetstreamer import PacketStreamer
-from packetstreamer.ttypes import *
-
-from thrift.transport import TSocket
-from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol
-from thrift.server import TServer
-
-class PacketStreamerHandler:
- def __init__(self):
- logging.handlers.codecs = None
- self.log = logging.getLogger("packetstreamer")
- self.log.setLevel(logging.DEBUG)
- handler = logging.handlers.SysLogHandler("/dev/log")
- handler.setFormatter(logging.Formatter("%(name)s: %(levelname)s %(message)s"))
- self.log.addHandler(handler)
-
- def ping(self):
- self.log.debug('ping()')
- return true
-
- def pushPacketSync(self, packet):
- self.log.debug('receive a packet synchronously: %s' %(packet))
- return 0
-
- def pushPacketAsync(self, packet):
- self.log.debug('receive a packet Asynchronously: %s' %(packet))
-
-handler = PacketStreamerHandler()
-processor = PacketStreamer.Processor(handler)
-transport = TSocket.TServerSocket(9090)
-tfactory = TTransport.TBufferedTransportFactory()
-pfactory = TBinaryProtocol.TBinaryProtocolFactory()
-
-server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
-
-# You could do one of these for a multithreaded server
-#server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
-#server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
-
-print 'Starting the server...'
-server.serve()
-print 'done.'
diff --git a/src/main/python/compileall.py b/src/main/python/compileall.py
deleted file mode 100644
index b21d95f..0000000
--- a/src/main/python/compileall.py
+++ /dev/null
@@ -1,157 +0,0 @@
-"""Module/script to "compile" all .py files to .pyc (or .pyo) file.
-
-When called as a script with arguments, this compiles the directories
-given as arguments recursively; the -l option prevents it from
-recursing into directories.
-
-Without arguments, if compiles all modules on sys.path, without
-recursing into subdirectories. (Even though it should do so for
-packages -- for now, you'll have to deal with packages separately.)
-
-See module py_compile for details of the actual byte-compilation.
-
-"""
-
-import os
-import sys
-import py_compile
-
-__all__ = ["compile_dir","compile_path"]
-
-def compile_dir(dir, maxlevels=10, ddir=None,
- force=0, rx=None, quiet=0):
- """Byte-compile all modules in the given directory tree.
-
- Arguments (only dir is required):
-
- dir: the directory to byte-compile
- maxlevels: maximum recursion level (default 10)
- ddir: if given, purported directory name (this is the
- directory name that will show up in error messages)
- force: if 1, force compilation, even if timestamps are up-to-date
- quiet: if 1, be quiet during compilation
-
- """
- if not quiet:
- print 'Listing', dir, '...'
- try:
- names = os.listdir(dir)
- except os.error:
- print "Can't list", dir
- names = []
- names.sort()
- success = 1
- for name in names:
- fullname = os.path.join(dir, name)
- if ddir is not None:
- dfile = os.path.join(ddir, name)
- else:
- dfile = None
- if rx is not None:
- mo = rx.search(fullname)
- if mo:
- continue
- if os.path.isfile(fullname):
- head, tail = name[:-3], name[-3:]
- if tail == '.py':
- cfile = fullname + (__debug__ and 'c' or 'o')
- ftime = os.stat(fullname).st_mtime
- try: ctime = os.stat(cfile).st_mtime
- except os.error: ctime = 0
- if (ctime > ftime) and not force: continue
- if not quiet:
- print 'Compiling', fullname, '...'
- try:
- ok = py_compile.compile(fullname, None, dfile, True)
- except KeyboardInterrupt:
- raise KeyboardInterrupt
- except py_compile.PyCompileError,err:
- if quiet:
- print 'Compiling', fullname, '...'
- print err.msg
- success = 0
- except IOError, e:
- print "Sorry", e
- success = 0
- else:
- if ok == 0:
- success = 0
- elif maxlevels > 0 and \
- name != os.curdir and name != os.pardir and \
- os.path.isdir(fullname) and \
- not os.path.islink(fullname):
- if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, quiet):
- success = 0
- return success
-
-def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0):
- """Byte-compile all module on sys.path.
-
- Arguments (all optional):
-
- skip_curdir: if true, skip current directory (default true)
- maxlevels: max recursion level (default 0)
- force: as for compile_dir() (default 0)
- quiet: as for compile_dir() (default 0)
-
- """
- success = 1
- for dir in sys.path:
- if (not dir or dir == os.curdir) and skip_curdir:
- print 'Skipping current directory'
- else:
- success = success and compile_dir(dir, maxlevels, None,
- force, quiet=quiet)
- return success
-
-def main():
- """Script main program."""
- import getopt
- try:
- opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:')
- except getopt.error, msg:
- print msg
- print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \
- "[-x regexp] [directory ...]"
- print "-l: don't recurse down"
- print "-f: force rebuild even if timestamps are up-to-date"
- print "-q: quiet operation"
- print "-d destdir: purported directory name for error messages"
- print " if no directory arguments, -l sys.path is assumed"
- print "-x regexp: skip files matching the regular expression regexp"
- print " the regexp is search for in the full path of the file"
- sys.exit(2)
- maxlevels = 10
- ddir = None
- force = 0
- quiet = 0
- rx = None
- for o, a in opts:
- if o == '-l': maxlevels = 0
- if o == '-d': ddir = a
- if o == '-f': force = 1
- if o == '-q': quiet = 1
- if o == '-x':
- import re
- rx = re.compile(a)
- if ddir:
- if len(args) != 1:
- print "-d destdir require exactly one directory argument"
- sys.exit(2)
- success = 1
- try:
- if args:
- for dir in args:
- if not compile_dir(dir, maxlevels, ddir,
- force, rx, quiet):
- success = 0
- else:
- success = compile_path()
- except KeyboardInterrupt:
- print "\n[interrupt]"
- success = 0
- return success
-
-if __name__ == '__main__':
- exit_status = int(not main())
- sys.exit(exit_status)
diff --git a/src/main/python/debugserver.py b/src/main/python/debugserver.py
deleted file mode 100644
index d8c81f9..0000000
--- a/src/main/python/debugserver.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-from threading import currentThread
-from SocketServer import BaseRequestHandler, TCPServer
-from code import InteractiveConsole
-
-_locals = None
-
-class DebugLogger(object):
- def do_print(self, *args):
- for i in args:
- print i,
- print
- info = do_print
- warn = do_print
- debug = do_print
-_log = DebugLogger()
-
-
-class DebugConsole(InteractiveConsole):
- def __init__(self, request):
- self.request = request
- InteractiveConsole.__init__(self, _locals)
-
- def raw_input(self, prompt):
- self.request.send(prompt)
- data = self.request.recv(10000).rstrip()
- if len(data) == 1 and ord(data[0]) == 4:
- sys.exit()
- return data
-
- def write(self, data):
- self.request.send(str(data))
-
- def write_nl(self, data):
- self.write(str(data)+"\r\n")
-
-class DebugServerHandler(BaseRequestHandler):
- def __init__(self, request, client_address, server):
- currentThread()._thread.setName("debugserver-%s:%d" % client_address)
- _log.debug('Open connection to DebugServer from %s:%d' % client_address)
- BaseRequestHandler.__init__(self, request, client_address, server)
-
- def handle(self):
- console = DebugConsole(self.request)
- sys.displayhook = console.write_nl
- console.interact('DebugServer')
- self.request.close()
-
-class DebugServer(TCPServer):
- daemon_threads = True
- allow_reuse_address = True
-
- def handle_error(self, request, client_address):
- _log.debug('Closing connection to DebugServer from %s:%d' % client_address)
- request.close()
-
-def run_server(port=6655, host='0.0.0.0', locals=locals()):
- currentThread()._thread.setName("debugserver-main")
-
- global _locals
- _locals = locals
- if "log" in locals.keys():
- global _log
- _log = locals["log"]
-
- _log.info("Starting DebugServer on port %d" % port)
- server = DebugServer(('', port), DebugServerHandler)
- try:
- server.serve_forever()
- except KeyboardInterrupt:
- pass
-
-if __name__ == "__main__":
- run_server()
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index b4b4f27..a9ff0b8 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -1,31 +1,25 @@
net.floodlightcontroller.core.FloodlightProvider
net.floodlightcontroller.storage.memory.MemoryStorageSource
net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl
-net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager
+net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager
net.floodlightcontroller.topology.TopologyManager
net.floodlightcontroller.forwarding.Forwarding
net.floodlightcontroller.flowcache.FlowReconcileManager
-net.floodlightcontroller.core.OFMessageFilterManager
net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher
net.floodlightcontroller.perfmon.PktInProcessingTime
net.floodlightcontroller.perfmon.NullPktInProcessingTime
net.floodlightcontroller.restserver.RestApiServer
-net.floodlightcontroller.learningswitch.LearningSwitch
-net.floodlightcontroller.hub.Hub
-net.floodlightcontroller.jython.JythonDebugInterface
net.floodlightcontroller.counter.CounterStore
net.floodlightcontroller.counter.NullCounterStore
net.floodlightcontroller.threadpool.ThreadPool
net.floodlightcontroller.ui.web.StaticWebRoutable
-net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter
net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier
net.floodlightcontroller.devicemanager.test.MockDeviceManager
net.floodlightcontroller.core.test.MockFloodlightProvider
net.floodlightcontroller.core.test.MockThreadPoolService
-net.floodlightcontroller.firewall.Firewall
-net.floodlightcontroller.onoslistener.OnosPublisher
-net.floodlightcontroller.flowcache.FlowManager
-net.floodlightcontroller.routing.TopoRouteService
-net.floodlightcontroller.bgproute.BgpRoute
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher
+net.onrc.onos.ofcontroller.flowmanager.FlowManager
+net.onrc.onos.ofcontroller.routing.TopoRouteService
+net.onrc.onos.ofcontroller.bgproute.BgpRoute
net.onrc.onos.registry.controller.ZookeeperRegistry
net.onrc.onos.registry.controller.StandaloneRegistry
diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties
index 9e4fc02..8decafb 100644
--- a/src/main/resources/floodlightdefault.properties
+++ b/src/main/resources/floodlightdefault.properties
@@ -6,12 +6,12 @@
net.floodlightcontroller.counter.CounterStore,\
net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.ui.web.StaticWebRoutable,\
-net.floodlightcontroller.onoslistener.OnosPublisher, \
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
net.onrc.onos.registry.controller.ZookeeperRegistry
net.floodlightcontroller.restserver.RestApiServer.port = 8080
net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
net.floodlightcontroller.jython.JythonDebugInterface.port = 6655
net.floodlightcontroller.forwarding.Forwarding.idletimeout = 5
net.floodlightcontroller.forwarding.Forwarding.hardtimeout = 0
-net.floodlightcontroller.onoslistener.OnosPublisher.dbconf = /tmp/cassandra.titan
-net.floodlightcontroller.onoslistener.OnosPublisher.EnableCleanup = True
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/cassandra.titan
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.EnableCleanup = True
diff --git a/src/main/thrift/packetstreamer.thrift b/src/main/thrift/packetstreamer.thrift
deleted file mode 100644
index 827dd85..0000000
--- a/src/main/thrift/packetstreamer.thrift
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Interface definition for packetstreamer service
-#
-
-namespace java net.floodlightcontroller.packetstreamer.thrift
-namespace cpp net.floodlightcontroller.packetstreamer
-namespace py packetstreamer
-namespace php packetstreamer
-namespace perl packetstreamer
-
-const string VERSION = "0.1.0"
-
-#
-# data structures
-#
-
-/**
- * OFMessage type
- **/
-enum OFMessageType {
- HELLO = 0,
- ERROR = 1,
- ECHO_REQUEST = 2,
- ECHO_REPLY = 3,
- VENDOR = 4,
- FEATURES_REQUEST = 5,
- FEATURES_REPLY = 6,
- GET_CONFIG_REQUEST = 7,
- GET_CONFIG_REPLY = 8,
- SET_CONFIG = 9,
- PACKET_IN = 10,
- FLOW_REMOVED = 11,
- PORT_STATUS = 12,
- PACKET_OUT = 13,
- FLOW_MOD = 14,
- PORT_MOD = 15,
- STATS_REQUEST = 16,
- STATS_REPLY = 17,
- BARRIER_REQUEST = 18,
- BARRIER_REPLY = 19,
-}
-
-/**
- * A struct that defines switch port tuple
- */
-struct SwitchPortTuple {
- 1: i64 dpid,
- 2: i16 port,
-}
-
-struct Packet {
- 1: OFMessageType messageType,
- 2: SwitchPortTuple swPortTuple,
- 3: binary data,
-}
-
-struct Message {
- 1: list<string> sessionIDs,
- 2: Packet packet,
-}
-
-/**
- * Packetstreamer API
- */
-service PacketStreamer {
-
- /**
- * Synchronous method to get packets for a given sessionid
- */
- list<binary> getPackets(1:string sessionid),
-
- /**
- * Synchronous method to publish a packet.
- * It ensure the order that the packets are pushed
- */
- i32 pushMessageSync(1:Message packet),
-
- /**
- * Asynchronous method to publish a packet.
- * Order is not guaranteed.
- */
- oneway void pushMessageAsync(1:Message packet)
-
- /**
- * Terminate a session
- */
- void terminateSession(1:string sessionid)
-}
diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index a6948c0..ecdc2d7 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -17,36 +17,43 @@
package net.floodlightcontroller.core.internal;
-import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.same;
+import static org.easymock.EasyMock.verify;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
-import net.floodlightcontroller.core.FloodlightProvider;
import net.floodlightcontroller.core.FloodlightContext;
+import net.floodlightcontroller.core.FloodlightProvider;
import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IHAListener;
import net.floodlightcontroller.core.IFloodlightProviderService.Role;
-import net.floodlightcontroller.core.IOFMessageFilterManagerService;
-import net.floodlightcontroller.core.IOFMessageListener;
+import net.floodlightcontroller.core.IHAListener;
import net.floodlightcontroller.core.IListener.Command;
+import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitchListener;
-import net.floodlightcontroller.core.OFMessageFilterManager;
import net.floodlightcontroller.core.internal.Controller.IUpdate;
import net.floodlightcontroller.core.internal.Controller.SwitchUpdate;
import net.floodlightcontroller.core.internal.Controller.SwitchUpdateType;
import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
import net.floodlightcontroller.core.test.MockThreadPoolService;
import net.floodlightcontroller.counter.CounterStore;
import net.floodlightcontroller.counter.ICounterStoreService;
@@ -62,6 +69,13 @@
import net.floodlightcontroller.storage.memory.MemoryStorageSource;
import net.floodlightcontroller.test.FloodlightTestCase;
import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.onrc.onos.ofcontroller.flowmanager.FlowManager;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.StandaloneRegistry;
import org.easymock.Capture;
import org.easymock.EasyMock;
@@ -72,17 +86,15 @@
import org.openflow.protocol.OFError.OFErrorType;
import org.openflow.protocol.OFFeaturesReply;
import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPacketIn.OFPacketInReason;
import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPort;
+import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
+import org.openflow.protocol.OFPhysicalPort.OFPortState;
import org.openflow.protocol.OFPortStatus;
+import org.openflow.protocol.OFPortStatus.OFPortReason;
import org.openflow.protocol.OFStatisticsReply;
import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFPortStatus.OFPortReason;
import org.openflow.protocol.OFVendor;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
import org.openflow.protocol.factory.BasicFactory;
import org.openflow.protocol.statistics.OFFlowStatisticsReply;
import org.openflow.protocol.statistics.OFStatistics;
@@ -124,16 +136,26 @@
tp = new MockThreadPoolService();
fmc.addService(IThreadPoolService.class, tp);
+ // Following added by ONOS
+ // TODO replace with mock if further testing is needed.
+ fmc.addService(IFlowService.class, new FlowManager() );
+ fmc.addService(ITopoRouteService.class, new TopoRouteService() );
+ StandaloneRegistry sr = new StandaloneRegistry();
+ fmc.addService(IControllerRegistryService.class, sr );
+
+
ppt.init(fmc);
restApi.init(fmc);
memstorage.init(fmc);
cm.init(fmc);
tp.init(fmc);
+ sr.init(fmc);
ppt.startUp(fmc);
restApi.startUp(fmc);
memstorage.startUp(fmc);
cm.startUp(fmc);
tp.startUp(fmc);
+ sr.startUp(fmc);
}
public Controller getController() {
@@ -359,125 +381,6 @@
}
@Test
- public void testMessageFilterManager() throws Exception {
- class MyOFMessageFilterManager extends OFMessageFilterManager {
- public MyOFMessageFilterManager(int timer_interval) {
- super();
- TIMER_INTERVAL = timer_interval;
- }
- }
- FloodlightModuleContext fmCntx = new FloodlightModuleContext();
- MockFloodlightProvider mfp = new MockFloodlightProvider();
- OFMessageFilterManager mfm = new MyOFMessageFilterManager(100);
- MockThreadPoolService mtp = new MockThreadPoolService();
- fmCntx.addService(IOFMessageFilterManagerService.class, mfm);
- fmCntx.addService(IFloodlightProviderService.class, mfp);
- fmCntx.addService(IThreadPoolService.class, mtp);
- String sid = null;
-
- mfm.init(fmCntx);
- mfm.startUp(fmCntx);
-
- ConcurrentHashMap <String, String> filter;
- int i;
-
- //Adding the filter works -- adds up to the maximum filter size.
- for(i=mfm.getMaxFilterSize(); i > 0; --i) {
- filter = new ConcurrentHashMap<String,String>();
- filter.put("mac", String.format("00:11:22:33:44:%d%d", i,i));
- sid = mfm.setupFilter(null, filter, 60);
- assertTrue(mfm.getNumberOfFilters() == mfm.getMaxFilterSize() - i +1);
- }
-
- // Add one more to see if you can't
- filter = new ConcurrentHashMap<String,String>();
- filter.put("mac", "mac2");
- mfm.setupFilter(null, filter, 10*1000);
-
- assertTrue(mfm.getNumberOfFilters() == mfm.getMaxFilterSize());
-
- // Deleting the filter works.
- mfm.setupFilter(sid, null, -1);
- assertTrue(mfm.getNumberOfFilters() == mfm.getMaxFilterSize()-1);
-
- // Creating mock switch to which we will send packet out and
- IOFSwitch sw = createMock(IOFSwitch.class);
- expect(sw.getId()).andReturn(new Long(0));
-
- // Mock Packet-in
- IPacket testPacket = new Ethernet()
- .setSourceMACAddress("00:44:33:22:11:00")
- .setDestinationMACAddress("00:11:22:33:44:55")
- .setEtherType(Ethernet.TYPE_ARP)
- .setPayload(
- new ARP()
- .setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(ARP.PROTO_TYPE_IP)
- .setHardwareAddressLength((byte) 6)
- .setProtocolAddressLength((byte) 4)
- .setOpCode(ARP.OP_REPLY)
- .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
- .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
- .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
- .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
- byte[] testPacketSerialized = testPacket.serialize();
-
- // Build the PacketIn
- OFPacketIn pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(testPacketSerialized)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) testPacketSerialized.length);
-
- // Mock Packet-out
- OFPacketOut packetOut =
- (OFPacketOut) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
- packetOut.setBufferId(pi.getBufferId())
- .setInPort(pi.getInPort());
- List<OFAction> poactions = new ArrayList<OFAction>();
- poactions.add(new OFActionOutput(OFPort.OFPP_TABLE.getValue(), (short) 0));
- packetOut.setActions(poactions)
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
- .setPacketData(testPacketSerialized)
- .setLengthU(OFPacketOut.MINIMUM_LENGTH+packetOut.getActionsLength()+testPacketSerialized.length);
-
- FloodlightContext cntx = new FloodlightContext();
- IFloodlightProviderService.bcStore.put(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD, (Ethernet) testPacket);
-
-
- // Let's check the listeners.
- List <IOFMessageListener> lm;
-
- // Check to see if all the listeners are active.
- lm = mfp.getListeners().get(OFType.PACKET_OUT);
- assertTrue(lm.size() == 1);
- assertTrue(lm.get(0).equals(mfm));
-
- lm = mfp.getListeners().get(OFType.FLOW_MOD);
- assertTrue(lm.size() == 1);
- assertTrue(lm.get(0).equals(mfm));
-
- lm = mfp.getListeners().get(OFType.PACKET_IN);
- assertTrue(lm.size() == 1);
- assertTrue(lm.get(0).equals(mfm));
-
- HashSet<String> matchedFilters;
-
- // Send a packet in and check if it matches a filter.
- matchedFilters = mfm.getMatchedFilters(pi, cntx);
- assertTrue(matchedFilters.size() == 1);
-
- // Send a packet out and check if it matches a filter
- matchedFilters = mfm.getMatchedFilters(packetOut, cntx);
- assertTrue(matchedFilters.size() == 1);
-
- // Wait for all filters to be timed out.
- Thread.sleep(150);
- assertEquals(0, mfm.getNumberOfFilters());
- }
-
- @Test
public void testAddSwitch() throws Exception {
controller.activeSwitches = new ConcurrentHashMap<Long, IOFSwitch>();
@@ -509,7 +412,6 @@
expect(newsw.getBuffers()).andReturn(0).anyTimes();
expect(newsw.getTables()).andReturn((byte)0).anyTimes();
expect(newsw.getActions()).andReturn(0).anyTimes();
- expect(newsw.getPorts()).andReturn(new ArrayList<OFPhysicalPort>());
controller.activeSwitches.put(0L, oldsw);
replay(newsw, channel, channel2);
@@ -520,7 +422,7 @@
@Test
public void testUpdateQueue() throws Exception {
- class DummySwitchListener implements IOFSwitchListener {
+ class DummySwitchListener implements IOFSwitchListener, IOFSwitchPortListener {
public int nAdded;
public int nRemoved;
public int nPortChanged;
@@ -545,6 +447,16 @@
nPortChanged++;
notifyAll();
}
+ @Override
+ public void switchPortAdded(Long switchId, OFPhysicalPort port) {
+ // TODO Auto-generated method stub
+
+ }
+ @Override
+ public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
+ // TODO Auto-generated method stub
+
+ }
}
DummySwitchListener switchListener = new DummySwitchListener();
IOFSwitch sw = createMock(IOFSwitch.class);
@@ -752,7 +664,7 @@
assertTrue("Check that update is HARoleUpdate",
upd instanceof Controller.HARoleUpdate);
Controller.HARoleUpdate roleUpd = (Controller.HARoleUpdate)upd;
- assertSame(null, roleUpd.oldRole);
+ assertSame(Role.MASTER, roleUpd.oldRole);
assertSame(Role.SLAVE, roleUpd.newRole);
}
@@ -806,15 +718,16 @@
state.hasGetConfigReply = true;
// Role support disabled. Switch should be promoted to active switch
// list.
- setupSwitchForAddSwitch(chdlr.sw, 0L);
- chdlr.sw.clearAllFlowMods();
- replay(controller.roleChanger, chdlr.sw);
- chdlr.checkSwitchReady();
- verify(controller.roleChanger, chdlr.sw);
- assertSame(OFChannelState.HandshakeState.READY, state.hsState);
- assertSame(chdlr.sw, controller.activeSwitches.get(0L));
- assertTrue(controller.connectedSwitches.contains(chdlr.sw));
- assertTrue(state.firstRoleReplyReceived);
+// FIXME: ONOS modified the behavior to always submit Role Request to trigger OFS error.
+// setupSwitchForAddSwitch(chdlr.sw, 0L);
+// chdlr.sw.clearAllFlowMods();
+// replay(controller.roleChanger, chdlr.sw);
+// chdlr.checkSwitchReady();
+// verify(controller.roleChanger, chdlr.sw);
+// assertSame(OFChannelState.HandshakeState.READY, state.hsState);
+// assertSame(chdlr.sw, controller.activeSwitches.get(0L));
+// assertTrue(controller.connectedSwitches.contains(chdlr.sw));
+// assertTrue(state.firstRoleReplyReceived);
reset(chdlr.sw);
reset(controller.roleChanger);
controller.connectedSwitches.clear();
@@ -824,9 +737,15 @@
// Role support enabled.
state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
controller.role = Role.MASTER;
+ expect(chdlr.sw.getStringId()).andReturn("SomeID").anyTimes();
+ expect(chdlr.sw.getId()).andReturn(42L).anyTimes();
Capture<Collection<OFSwitchImpl>> swListCapture =
new Capture<Collection<OFSwitchImpl>>();
controller.roleChanger.submitRequest(capture(swListCapture),
+ same(Role.SLAVE));
+ Capture<Collection<OFSwitchImpl>> swListCapture2 =
+ new Capture<Collection<OFSwitchImpl>>();
+ controller.roleChanger.submitRequest(capture(swListCapture2),
same(Role.MASTER));
replay(controller.roleChanger, chdlr.sw);
chdlr.checkSwitchReady();
@@ -834,7 +753,7 @@
assertSame(OFChannelState.HandshakeState.READY, state.hsState);
assertTrue(controller.activeSwitches.isEmpty());
assertTrue(controller.connectedSwitches.contains(chdlr.sw));
- assertTrue(state.firstRoleReplyReceived);
+// assertTrue(state.firstRoleReplyReceived);
Collection<OFSwitchImpl> swList = swListCapture.getValue();
assertEquals(1, swList.size());
assertTrue("swList must contain this switch", swList.contains(chdlr.sw));
@@ -930,7 +849,7 @@
state.firstRoleReplyReceived = false;
controller.role = Role.SLAVE;
expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
- chdlr.sw.deliverRoleRequestNotSupported(xid);
+ expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.SLAVE);
expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes();
expect(ch.close()).andReturn(null);
@@ -950,7 +869,7 @@
state.firstRoleReplyReceived = false;
controller.role = Role.SLAVE;
expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
- chdlr.sw.deliverRoleRequestNotSupported(xid);
+ expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.SLAVE);
expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes();
expect(ch.close()).andReturn(null);
replay(ch, chdlr.sw);
@@ -969,7 +888,7 @@
state.firstRoleReplyReceived = false;
controller.role = Role.MASTER;
expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
- chdlr.sw.deliverRoleRequestNotSupported(xid);
+ expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.MASTER);
setupSwitchForAddSwitch(chdlr.sw, 0L);
chdlr.sw.clearAllFlowMods();
replay(ch, chdlr.sw);
@@ -1207,6 +1126,26 @@
assertEquals(SwitchUpdateType.PORTCHANGED, swUpdate.switchUpdateType);
}
+ public void verifyPortAddedUpdateInQueue(IOFSwitch sw) throws Exception {
+ assertEquals(2, controller.updates.size());
+ IUpdate update = controller.updates.take();
+ assertEquals(true, update instanceof SwitchUpdate);
+ SwitchUpdate swUpdate = (SwitchUpdate)update;
+ assertEquals(sw, swUpdate.sw);
+ assertEquals(SwitchUpdateType.PORTADDED, swUpdate.switchUpdateType);
+ verifyPortChangedUpdateInQueue(sw);
+ }
+
+ public void verifyPortRemovedUpdateInQueue(IOFSwitch sw) throws Exception {
+ assertEquals(2, controller.updates.size());
+ IUpdate update = controller.updates.take();
+ assertEquals(true, update instanceof SwitchUpdate);
+ SwitchUpdate swUpdate = (SwitchUpdate)update;
+ assertEquals(sw, swUpdate.sw);
+ assertEquals(SwitchUpdateType.PORTREMOVED, swUpdate.switchUpdateType);
+ verifyPortChangedUpdateInQueue(sw);
+ }
+
/*
* Test handlePortStatus()
* TODO: test correct updateStorage behavior!
@@ -1227,25 +1166,51 @@
replay(sw);
controller.handlePortStatusMessage(sw, ofps, false);
verify(sw);
- verifyPortChangedUpdateInQueue(sw);
+ verifyPortAddedUpdateInQueue(sw);
reset(sw);
+ // ONOS:Port is considered added if Link state is not down and not configured to be down
ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
sw.setPort(port);
expectLastCall().once();
replay(sw);
controller.handlePortStatusMessage(sw, ofps, false);
verify(sw);
- verifyPortChangedUpdateInQueue(sw);
+ verifyPortAddedUpdateInQueue(sw);
reset(sw);
+ // ONOS:Port is considered removed if Link state is down
+ ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
+ port.setState(OFPortState.OFPPS_LINK_DOWN.getValue());
+ sw.setPort(port);
+ expectLastCall().once();
+ replay(sw);
+ controller.handlePortStatusMessage(sw, ofps, false);
+ verify(sw);
+ verifyPortRemovedUpdateInQueue(sw);
+ reset(sw);
+ port.setState(0);// reset
+
+ // ONOS: .. or is configured to be down
+ ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
+ port.setConfig(OFPortConfig.OFPPC_PORT_DOWN.getValue());
+ sw.setPort(port);
+ expectLastCall().once();
+ replay(sw);
+ controller.handlePortStatusMessage(sw, ofps, false);
+ verify(sw);
+ verifyPortRemovedUpdateInQueue(sw);
+ reset(sw);
+ port.setConfig(0);// reset
+
+
ofps.setReason((byte)OFPortReason.OFPPR_DELETE.ordinal());
sw.deletePort(port.getPortNumber());
expectLastCall().once();
replay(sw);
controller.handlePortStatusMessage(sw, ofps, false);
verify(sw);
- verifyPortChangedUpdateInQueue(sw);
+ verifyPortRemovedUpdateInQueue(sw);
reset(sw);
}
}
diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java
index 758cd05..128c09f 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java
@@ -197,7 +197,7 @@
sw.role = Role.SLAVE;
sw.pendingRoleRequests.add(pending);
replay(sw.channel);
- sw.deliverRoleRequestNotSupported(pending.xid);
+ sw.deliverRoleRequestNotSupportedEx(pending.xid);
verify(sw.channel);
assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
assertEquals(null, sw.role);
@@ -210,7 +210,7 @@
sw.role = Role.SLAVE;
expect(sw.channel.close()).andReturn(null);
replay(sw.channel);
- sw.deliverRoleRequestNotSupported(1);
+ sw.deliverRoleRequestNotSupportedEx(1);
verify(sw.channel);
assertEquals(null, sw.role);
assertEquals(0, sw.pendingRoleRequests.size());
@@ -228,7 +228,7 @@
sw.pendingRoleRequests.add(pending);
expect(sw.channel.close()).andReturn(null);
replay(sw.channel);
- sw.deliverRoleRequestNotSupported(pending.xid+1);
+ sw.deliverRoleRequestNotSupportedEx(pending.xid+1);
verify(sw.channel);
assertEquals(null, sw.role);
assertEquals(0, sw.pendingRoleRequests.size());
diff --git a/src/test/java/net/floodlightcontroller/core/internal/RoleChangeCallbackTest.java b/src/test/java/net/floodlightcontroller/core/internal/RoleChangeCallbackTest.java
new file mode 100644
index 0000000..2aeb60e
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/core/internal/RoleChangeCallbackTest.java
@@ -0,0 +1,143 @@
+package net.floodlightcontroller.core.internal;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+// Extends Controller class to access protected inner class
+public class RoleChangeCallbackTest extends Controller {
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ /**
+ * Test if {@link RoleChangeCallback#controlChanged(long, boolean)} correctly calls {@link RoleChanger#submitRequest(Collection, net.floodlightcontroller.core.IFloodlightProviderService.Role)}
+ * when connectedSwitch is not empty.
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testNormalSwitches() throws Exception {
+ Long [] dpids = new Long [] { 1000L, 1001L, 1002L, 1003L };
+ final long dpidExist = 1000L;
+ final long dpidNotExist = 2000L;
+
+ roleChanger = EasyMock.createMock(RoleChanger.class);
+
+ // First call will be called with (dpidExist,true)
+ roleChanger.submitRequest(EasyMock.anyObject(Collection.class), EasyMock.anyObject(Role.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ Collection<OFSwitchImpl> switches = (Collection<OFSwitchImpl>)EasyMock.getCurrentArguments()[0];
+ Role role = (Role)EasyMock.getCurrentArguments()[1];
+
+ List<Long> dpids = new ArrayList<Long>();
+
+ for(OFSwitchImpl sw : switches) {
+ dpids.add(sw.getId());
+ }
+ assertTrue(dpids.contains(dpidExist));
+ assertEquals(role, Role.MASTER);
+
+ return null;
+ }
+ }).once();
+
+ // Second call will be called with (dpidExist,false)
+ roleChanger.submitRequest(EasyMock.anyObject(Collection.class), EasyMock.anyObject(Role.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ Collection<OFSwitchImpl> switches = (Collection<OFSwitchImpl>)EasyMock.getCurrentArguments()[0];
+ Role role = (Role)EasyMock.getCurrentArguments()[1];
+
+ List<Long> dpids = new ArrayList<Long>();
+
+ for(OFSwitchImpl sw : switches) {
+ dpids.add(sw.getId());
+ }
+ assertTrue(dpids.contains(dpidExist));
+ assertEquals(role, Role.SLAVE);
+
+ return null;
+ }
+ }).once();
+
+ EasyMock.replay(roleChanger);
+
+ initNetwork(roleChanger, dpids);
+
+ RoleChangeCallback callback = new RoleChangeCallback();
+ callback.controlChanged(dpidExist, true);
+ callback.controlChanged(dpidExist, false);
+ callback.controlChanged(dpidNotExist, true);
+ callback.controlChanged(dpidNotExist, false);
+
+ EasyMock.verify(roleChanger);
+ }
+
+ /**
+ * Test if {@link RoleChangeCallback#controlChanged(long, boolean)} doesn't call RoleChanger methods
+ * when connectedSwitch is empty.
+ * @throws Exception
+ */
+ @Test
+ public void testEmptySwitches() throws Exception {
+ Long [] dpids = new Long [] {};
+ final long dpidToTest = 1000L;
+
+ roleChanger = EasyMock.createMock(RoleChanger.class);
+ // roleChanger methods must not be used
+ EasyMock.replay(roleChanger);
+
+ initNetwork(roleChanger, dpids);
+
+ RoleChangeCallback callback = new RoleChangeCallback();
+ callback.controlChanged(dpidToTest, true);
+ callback.controlChanged(dpidToTest, false);
+
+ EasyMock.verify(roleChanger);
+ }
+
+ /**
+ * Create mock OFSwitchImpl object.
+ * @param id
+ * @return
+ */
+ private OFSwitchImpl createOFSwitchImplMock(Long id) {
+ OFSwitchImpl sw = EasyMock.createMock(OFSwitchImpl.class);
+
+ EasyMock.expect(sw.getId()).andReturn(id).anyTimes();
+ EasyMock.replay(sw);
+
+ return sw;
+ }
+
+ /**
+ * Setup connectedSwitches
+ * @param changer
+ * @param ids
+ * @throws Exception
+ */
+ private void initNetwork(RoleChanger changer, Long [] ids) throws Exception {
+ connectedSwitches = new HashSet<OFSwitchImpl>();
+
+ for(Long id : ids) {
+ connectedSwitches.add(createOFSwitchImplMock(id));
+ }
+ }
+}
diff --git a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
index 991afff..a6a6d85 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
@@ -16,6 +16,7 @@
import org.easymock.EasyMock;
import org.jboss.netty.channel.Channel;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
public class RoleChangerTest {
@@ -58,6 +59,7 @@
* The connection should be closed.
*/
@Test
+ @Ignore // FIXME: ONOS modified the behavior here to intentionally trigger OFS error.
public void testSendRoleRequestMasterNotSupported() {
LinkedList<OFSwitchImpl> switches = new LinkedList<OFSwitchImpl>();
diff --git a/src/test/java/net/floodlightcontroller/core/internal/SwitchStorageImplTest.java b/src/test/java/net/floodlightcontroller/core/internal/SwitchStorageImplTest.java
deleted file mode 100644
index a187d4c..0000000
--- a/src/test/java/net/floodlightcontroller/core/internal/SwitchStorageImplTest.java
+++ /dev/null
@@ -1,278 +0,0 @@
-package net.floodlightcontroller.core.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import net.floodlightcontroller.core.ISwitchStorage;
-import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.openflow.protocol.OFPhysicalPort;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-import com.tinkerpop.pipes.PipeFunction;
-import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
-
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
-
-
-public class SwitchStorageImplTest {
-
- private ISwitchStorage switchStorage;
- private TitanGraph titanGraph;
-
- @Before
- public void setUp() throws Exception {
- titanGraph = TestDatabaseManager.getTestDatabase();
- TestDatabaseManager.populateTestData(titanGraph);
-
- switchStorage = new TestableSwitchStorageImpl();
- }
-
- @After
- public void tearDown() throws Exception {
- titanGraph.shutdown();
- }
-
- @Ignore @Test
- public void testUpdate() {
- fail("Not yet implemented");
- }
-
- @Test
- public void testAddPort() {
-
- String dpid = "00:00:00:00:00:00:0a:01";
- short portNumber = 5;
-
- OFPhysicalPort portToAdd = new OFPhysicalPort();
- portToAdd.setName("port 5 at SEA switch");
- portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
- portToAdd.setPortNumber(portNumber);
-
- switchStorage.addPort(dpid, portToAdd);
-
- Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
-
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- pipe.start(sw).out("on").has("number", portNumber);
-
- assertTrue(pipe.hasNext());
- Vertex addedPort = pipe.next();
- assertFalse(pipe.hasNext());
-
- assertEquals(addedPort.getProperty("number"), portNumber);
- }
-
- @Ignore @Test
- public void testGetPorts() {
- fail("Not yet implemented");
- }
-
- @Ignore @Test
- public void testGetPortStringShort() {
- fail("Not yet implemented");
- }
-
- @Ignore @Test
- public void testGetPortStringString() {
- fail("Not yet implemented");
- }
-
- @Test
- public void testAddSwitch() {
- String dpid = "00:00:00:00:00:00:0a:07";
-
- switchStorage.addSwitch(dpid);
-
- Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
- assertTrue(it.hasNext());
- Vertex addedSwitch = it.next();
- assertFalse(it.hasNext());
-
- assertEquals(addedSwitch.getProperty("type"), "switch");
- assertEquals(addedSwitch.getProperty("dpid"), dpid);
- assertEquals(addedSwitch.getProperty("state"), SwitchState.ACTIVE.toString());
- }
-
-
- @Test
- public void testDeleteSwitch() {
- String dpid = "00:00:00:00:00:00:0a:01";
-
- switchStorage.deleteSwitch(dpid);
-
- Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
- assertFalse(it.hasNext());
- }
-
- @Test
- public void testDeletePortByPortNum() {
- //FIXME fails because query for the port is wrong in SwitchStorageImpl
-
- String dpid = "00:00:00:00:00:00:0a:01";
- short portNum = 3;
-
- switchStorage.deletePort(dpid, portNum);
-
- Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
-
- /*
- Iterator<Vertex> it = sw.getVertices(Direction.OUT, "on").iterator();
-
- while (it.hasNext()){
- System.out.println(it.next());
- }
- */
-
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- pipe.start(sw).out("on").has("number", portNum);
- assertFalse(pipe.hasNext());
- }
-
- @Ignore @Test
- public void testDeletePortStringString() {
- fail("Not yet implemented");
- }
-
- @Ignore @Test
- public void testGetActiveSwitches() {
- fail("Not yet implemented");
- }
-
- static class MyLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
- String dpid;
- public MyLoopFunction(String dpid) {
- super();
- this.dpid = dpid;
- }
- public Boolean compute(LoopBundle<Vertex> bundle) {
- Boolean output = false;
- if (! bundle.getObject().getProperty("dpid").equals(dpid)) {
- output = true;
- }
- return output;
- }
- }
-
- @Test
- public void testShortestPath() {
- String dpid_src = "00:00:00:00:00:00:0a:01";
- String dpid_dest = "00:00:00:00:00:00:0a:06";
-
- //
- // Implement the Shortest Path between two vertices by using
- // the following Gremlin CLI code:
- // v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path(){it.dpid}{it.number}{it.number}
- // The equivalent code used here is:
- // results = []; v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path().fill(results)
- //
-
- // Get the source vertex
- Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
- if (! iter.hasNext())
- return; // Source vertex not found
- Vertex v_src = iter.next();
-
- // Get the destination vertex
- iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
- if (! iter.hasNext())
- return; // Destination vertex not found
- Vertex v_dest = iter.next();
-
- //
- // Implement the Gremlin script and run it
- //
- // NOTE: This mechanism is slower. The code is kept here
- // for future reference.
- //
- /*
- String gremlin = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid}.path().fill(results)";
-
- String gremlin_nopath = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != \"NO-SUCH-DPID\"}.path().fill(results)";
-
- ScriptEngine engine = new GremlinGroovyScriptEngine();
- ArrayList<ArrayList<Vertex>> results = new ArrayList<ArrayList<Vertex>>();
- engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", titanGraph);
- engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_src", v_src);
- engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_dest", v_dest);
- engine.getBindings(ScriptContext.ENGINE_SCOPE).put("results", results);
-
- try {
- engine.eval(gremlin);
- } catch (ScriptException e) {
- System.err.println("Caught ScriptException running Gremlin script: " + e.getMessage());
- return;
- }
-
- for (ArrayList<Vertex> lv : results) {
- ...
- }
- */
-
- MyLoopFunction whileFunction = new MyLoopFunction(dpid_dest);
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- Collection<List> results = new ArrayList<List>();
- GremlinPipeline<Vertex, List> path;
- path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", whileFunction).path();
- path.fill(results);
-
- //
- // Extract the result and compose it into a string
- //
- String results_str = "";
- // System.out.println("BEGIN " + results.size());
- for (List l : results) {
- for (Object o: l) {
- Vertex v = (Vertex)(o);
- // System.out.println(v);
- String type = v.getProperty("type").toString();
- results_str += "[type: " + type;
- // System.out.println("type: " + type);
- if (type.equals("port")) {
- String number = v.getProperty("number").toString();
- // System.out.println("number: " + number);
- results_str += " number: " + number + "]";
- }
- if (type.equals("switch")) {
- String dpid = v.getProperty("dpid").toString();
- // System.out.println("dpid: " + dpid);
- results_str += " dpid: " + dpid + "]";
- }
- }
- }
- // System.out.println("END\n");
- System.out.println(results_str);
-
- //
- // Check the result
- //
- String expected_result = "[type: switch dpid: 00:00:00:00:00:00:0a:01][type: port number: 2][type: port number: 1][type: switch dpid: 00:00:00:00:00:00:0a:03][type: port number: 2][type: port number: 2][type: switch dpid: 00:00:00:00:00:00:0a:04][type: port number: 3][type: port number: 1][type: switch dpid: 00:00:00:00:00:00:0a:06]";
-
- assertEquals(results_str, expected_result);
-
- //
- // Test Shortest-Path computation to non-existing destination
- //
- results.clear();
- MyLoopFunction noDestWhileFunction = new MyLoopFunction("NO-SUCH-DPID");
- path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", noDestWhileFunction).path();
- path.fill(results);
- assertTrue(results.size() == 0);
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
index 3d5e03b..f811c9d 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
@@ -58,8 +58,17 @@
Iterator<Vertex> it = titanGraph.getVertices("type", "port").iterator();
while (it.hasNext()){
Vertex port = it.next();
- Integer portNum = (Integer) port.getProperty("number");
- port.setProperty("number", portNum.shortValue());
+
+ if(port.getProperty("number") instanceof Short)
+ {
+ Short portNum = (Short) port.getProperty("number");
+ port.setProperty("number", portNum.shortValue());
+ }
+ else{
+ Integer portNum = (Integer) port.getProperty("number");
+ port.setProperty("number", portNum.shortValue());
+ }
+
}
titanGraph.stopTransaction(Conclusion.SUCCESS);
}
diff --git a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
deleted file mode 100644
index 959bb49..0000000
--- a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
+++ /dev/null
@@ -1,513 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.ARP;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.TCP;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.routing.IRoutingDecision;
-import net.floodlightcontroller.storage.IStorageSourceService;
-import net.floodlightcontroller.storage.memory.MemoryStorageSource;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.util.MACAddress;
-
-import org.easymock.EasyMock;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFType;
-import org.openflow.util.HexString;
-
-/**
- * Unit test for stateless firewall implemented as a Google Summer of Code project.
- *
- * @author Amer Tahir
- */
-public class FirewallTest extends FloodlightTestCase {
- protected MockFloodlightProvider mockFloodlightProvider;
- protected FloodlightContext cntx;
- protected OFPacketIn packetIn;
- protected IOFSwitch sw;
- protected IPacket tcpPacket;
- protected IPacket broadcastARPPacket;
- protected IPacket ARPReplyPacket;
- protected IPacket broadcastIPPacket;
- protected IPacket tcpPacketReply;
- protected IPacket broadcastMalformedPacket;
- private Firewall firewall;
- public static String TestSwitch1DPID = "00:00:00:00:00:00:00:01";
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
- cntx = new FloodlightContext();
- mockFloodlightProvider = getMockFloodlightProvider();
- firewall = new Firewall();
- IStorageSourceService storageService = new MemoryStorageSource();
- RestApiServer restApi = new RestApiServer();
-
- // Mock switches
- long dpid = HexString.toLong(TestSwitch1DPID);
- sw = EasyMock.createNiceMock(IOFSwitch.class);
- expect(sw.getId()).andReturn(dpid).anyTimes();
- expect(sw.getStringId()).andReturn(TestSwitch1DPID).anyTimes();
- replay(sw);
- // Load the switch map
- Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
- switches.put(dpid, sw);
- mockFloodlightProvider.setSwitches(switches);
-
- FloodlightModuleContext fmc = new FloodlightModuleContext();
- fmc.addService(IFloodlightProviderService.class,
- mockFloodlightProvider);
- fmc.addService(IFirewallService.class, firewall);
- fmc.addService(IStorageSourceService.class, storageService);
- fmc.addService(IRestApiService.class, restApi);
-
- try {
- restApi.init(fmc);
- } catch (FloodlightModuleException e) {
- e.printStackTrace();
- }
-
- firewall.init(fmc);
- firewall.startUp(fmc);
-
- // Build our test packet
- this.tcpPacket = new Ethernet()
- .setDestinationMACAddress("00:11:22:33:44:55")
- .setSourceMACAddress("00:44:33:22:11:00")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.1.2")
- .setPayload(new TCP()
- .setSourcePort((short) 81)
- .setDestinationPort((short) 80)
- .setPayload(new Data(new byte[] {0x01}))));
-
- // Build a broadcast ARP packet
- this.broadcastARPPacket = new Ethernet()
- .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
- .setSourceMACAddress("00:44:33:22:11:00")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_ARP)
- .setPayload(
- new ARP()
- .setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(ARP.PROTO_TYPE_IP)
- .setOpCode(ARP.OP_REQUEST)
- .setHardwareAddressLength((byte)6)
- .setProtocolAddressLength((byte)4)
- .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
- .setSenderProtocolAddress(IPv4.toIPv4Address("192.168.1.1"))
- .setTargetHardwareAddress(Ethernet.toMACAddress("00:00:00:00:00:00"))
- .setTargetProtocolAddress(IPv4.toIPv4Address("192.168.1.2"))
- .setPayload(new Data(new byte[] {0x01})));
-
- // Build a ARP packet
- this.ARPReplyPacket = new Ethernet()
- .setDestinationMACAddress("00:44:33:22:11:00")
- .setSourceMACAddress("00:11:22:33:44:55")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_ARP)
- .setPayload(
- new ARP()
- .setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(ARP.PROTO_TYPE_IP)
- .setOpCode(ARP.OP_REQUEST)
- .setHardwareAddressLength((byte)6)
- .setProtocolAddressLength((byte)4)
- .setSenderHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
- .setSenderProtocolAddress(IPv4.toIPv4Address("192.168.1.2"))
- .setTargetHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
- .setTargetProtocolAddress(IPv4.toIPv4Address("192.168.1.1"))
- .setPayload(new Data(new byte[] {0x01})));
-
- // Build a broadcast IP packet
- this.broadcastIPPacket = new Ethernet()
- .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
- .setSourceMACAddress("00:44:33:22:11:00")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.1.255")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
-
- // Build a malformed broadcast packet
- this.broadcastMalformedPacket = new Ethernet()
- .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
- .setSourceMACAddress("00:44:33:22:11:00")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.1.2")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
-
- this.tcpPacketReply = new Ethernet()
- .setDestinationMACAddress("00:44:33:22:11:00")
- .setSourceMACAddress("00:11:22:33:44:55")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.2")
- .setDestinationAddress("192.168.1.1")
- .setPayload(new TCP()
- .setSourcePort((short) 80)
- .setDestinationPort((short) 81)
- .setPayload(new Data(new byte[] {0x02}))));
- }
-
- protected void setPacketIn(IPacket packet) {
- byte[] serializedPacket = packet.serialize();
- // Build the PacketIn
- this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(serializedPacket)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) serializedPacket.length);
-
- // Add the packet to the context store
- IFloodlightProviderService.bcStore.
- put(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
- (Ethernet)packet);
- }
-
- @Test
- public void testNoRules() throws Exception {
- // enable firewall first
- firewall.enableFirewall(true);
- // simulate a packet-in event
- this.setPacketIn(tcpPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- assertEquals(0, firewall.rules.size());
-
- IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- // no rules to match, so firewall should deny
- assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
- }
-
- @Test
- public void testReadRulesFromStorage() throws Exception {
- // add 2 rules first
- FirewallRule rule = new FirewallRule();
- rule.in_port = 2;
- rule.dl_src = MACAddress.valueOf("00:00:00:00:00:01").toLong();
- rule.dl_dst = MACAddress.valueOf("00:00:00:00:00:02").toLong();
- rule.priority = 1;
- rule.action = FirewallRule.FirewallAction.DENY;
- firewall.addRule(rule);
- rule = new FirewallRule();
- rule.in_port = 3;
- rule.dl_src = MACAddress.valueOf("00:00:00:00:00:02").toLong();
- rule.dl_dst = MACAddress.valueOf("00:00:00:00:00:01").toLong();
- rule.nw_proto = IPv4.PROTOCOL_TCP;
- rule.wildcard_nw_proto = false;
- rule.tp_dst = 80;
- rule.priority = 2;
- rule.action = FirewallRule.FirewallAction.ALLOW;
- firewall.addRule(rule);
-
- List<FirewallRule> rules = firewall.readRulesFromStorage();
- // verify rule 1
- FirewallRule r = rules.get(0);
- assertEquals(r.in_port, 2);
- assertEquals(r.priority, 1);
- assertEquals(r.dl_src, MACAddress.valueOf("00:00:00:00:00:01").toLong());
- assertEquals(r.dl_dst, MACAddress.valueOf("00:00:00:00:00:02").toLong());
- assertEquals(r.action, FirewallRule.FirewallAction.DENY);
- // verify rule 2
- r = rules.get(1);
- assertEquals(r.in_port, 3);
- assertEquals(r.priority, 2);
- assertEquals(r.dl_src, MACAddress.valueOf("00:00:00:00:00:02").toLong());
- assertEquals(r.dl_dst, MACAddress.valueOf("00:00:00:00:00:01").toLong());
- assertEquals(r.nw_proto, IPv4.PROTOCOL_TCP);
- assertEquals(r.tp_dst, 80);
- assertEquals(r.wildcard_nw_proto, false);
- assertEquals(r.action, FirewallRule.FirewallAction.ALLOW);
- }
-
- @Test
- public void testRuleInsertionIntoStorage() throws Exception {
- // add TCP rule
- FirewallRule rule = new FirewallRule();
- rule.nw_proto = IPv4.PROTOCOL_TCP;
- rule.wildcard_nw_proto = false;
- rule.priority = 1;
- firewall.addRule(rule);
-
- List<Map<String, Object>> rulesFromStorage = firewall.getStorageRules();
- assertEquals(1, rulesFromStorage.size());
- assertEquals(Integer.parseInt((String)rulesFromStorage.get(0).get("ruleid")), rule.ruleid);
- }
-
- @Test
- public void testRuleDeletion() throws Exception {
- // add TCP rule
- FirewallRule rule = new FirewallRule();
- rule.nw_proto = IPv4.PROTOCOL_TCP;
- rule.wildcard_nw_proto = false;
- rule.priority = 1;
- firewall.addRule(rule);
- int rid = rule.ruleid;
-
- List<Map<String, Object>> rulesFromStorage = firewall.getStorageRules();
- assertEquals(1, rulesFromStorage.size());
- assertEquals(Integer.parseInt((String)rulesFromStorage.get(0).get("ruleid")), rid);
-
- // delete rule
- firewall.deleteRule(rid);
- rulesFromStorage = firewall.getStorageRules();
- assertEquals(0, rulesFromStorage.size());
- }
-
- @Test
- public void testFirewallDisabled() throws Exception {
- // firewall isn't enabled by default
- // so, it shouldn't make any decision
-
- // add TCP rule
- FirewallRule rule = new FirewallRule();
- rule.nw_proto = IPv4.PROTOCOL_TCP;
- rule.wildcard_nw_proto = false;
- rule.priority = 1;
- firewall.addRule(rule);
-
- this.setPacketIn(tcpPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- assertEquals(1, firewall.rules.size());
-
- IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertNull(decision);
- }
-
- @Test
- public void testSimpleAllowRule() throws Exception {
- // enable firewall first
- firewall.enableFirewall(true);
-
- // add TCP rule
- FirewallRule rule = new FirewallRule();
- rule.dl_type = Ethernet.TYPE_IPv4;
- rule.wildcard_dl_type = false;
- rule.nw_proto = IPv4.PROTOCOL_TCP;
- rule.wildcard_nw_proto = false;
- // source is IP 192.168.1.2
- rule.nw_src_prefix = IPv4.toIPv4Address("192.168.1.2");
- rule.wildcard_nw_src = false;
- // dest is network 192.168.1.0/24
- rule.nw_dst_prefix = IPv4.toIPv4Address("192.168.1.0");
- rule.nw_dst_maskbits = 24;
- rule.wildcard_nw_dst = false;
- rule.priority = 1;
- firewall.addRule(rule);
-
- // simulate a packet-in events
-
- this.setPacketIn(tcpPacketReply);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-
- // clear decision
- IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-
- this.setPacketIn(tcpPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
- }
-
- @Test
- public void testOverlappingRules() throws Exception {
- firewall.enableFirewall(true);
-
- // add TCP port 80 (destination only) allow rule
- FirewallRule rule = new FirewallRule();
- rule.dl_type = Ethernet.TYPE_IPv4;
- rule.wildcard_dl_type = false;
- rule.nw_proto = IPv4.PROTOCOL_TCP;
- rule.wildcard_nw_proto = false;
- rule.tp_dst = 80;
- rule.priority = 1;
- firewall.addRule(rule);
-
- // add block all rule
- rule = new FirewallRule();
- rule.action = FirewallRule.FirewallAction.DENY;
- rule.priority = 2;
- firewall.addRule(rule);
-
- assertEquals(2, firewall.rules.size());
-
- // packet destined to TCP port 80 - should be allowed
-
- this.setPacketIn(tcpPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-
- // clear decision
- IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-
- // packet destined for port 81 - should be denied
-
- this.setPacketIn(tcpPacketReply);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
- }
-
- @Test
- public void testARP() throws Exception {
- // enable firewall first
- firewall.enableFirewall(true);
-
- // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
- // simulate an ARP broadcast packet-in event
-
- this.setPacketIn(broadcastARPPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- // broadcast-ARP traffic should be allowed
- IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(IRoutingDecision.RoutingAction.MULTICAST, decision.getRoutingAction());
-
- // clear decision
- IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-
- // simulate an ARP reply packet-in event
-
- this.setPacketIn(ARPReplyPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- // ARP reply traffic should be denied
- decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
- }
-
- @Test
- public void testIPBroadcast() throws Exception {
- // enable firewall first
- firewall.enableFirewall(true);
-
- // set subnet mask for IP broadcast
- firewall.setSubnetMask("255.255.255.0");
-
- // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
- // simulate a packet-in event
-
- this.setPacketIn(broadcastIPPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- // broadcast traffic should be allowed
- IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(IRoutingDecision.RoutingAction.MULTICAST, decision.getRoutingAction());
- }
-
- @Test
- public void testMalformedIPBroadcast() throws Exception {
- // enable firewall first
- firewall.enableFirewall(true);
-
- // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
- // simulate a packet-in event
-
- this.setPacketIn(broadcastMalformedPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- // malformed broadcast traffic should NOT be allowed
- IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
- }
-
- @Test
- public void testLayer2Rule() throws Exception {
- // enable firewall first
- firewall.enableFirewall(true);
-
- // add L2 rule
- FirewallRule rule = new FirewallRule();
- rule.dl_src = MACAddress.valueOf("00:44:33:22:11:00").toLong();
- rule.wildcard_dl_src = false;
- rule.dl_dst = MACAddress.valueOf("00:11:22:33:44:55").toLong();
- rule.wildcard_dl_dst = false;
- rule.priority = 1;
- firewall.addRule(rule);
-
- // add TCP deny all rule
- rule = new FirewallRule();
- rule.nw_proto = IPv4.PROTOCOL_TCP;
- rule.wildcard_nw_proto = false;
- rule.priority = 2;
- rule.action = FirewallRule.FirewallAction.DENY;
- firewall.addRule(rule);
-
- // simulate a packet-in event
-
- this.setPacketIn(tcpPacket);
- firewall.receive(sw, this.packetIn, cntx);
- verify(sw);
-
- IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
- assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/hub/HubTest.java b/src/test/java/net/floodlightcontroller/hub/HubTest.java
deleted file mode 100644
index b4a215c..0000000
--- a/src/test/java/net/floodlightcontroller/hub/HubTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford University
-*
-* 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 net.floodlightcontroller.hub;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.easymock.EasyMock.capture;
-
-import java.util.Arrays;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.test.FloodlightTestCase;
-
-import org.easymock.Capture;
-import org.easymock.CaptureType;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class HubTest extends FloodlightTestCase {
- protected OFPacketIn packetIn;
- protected IPacket testPacket;
- protected byte[] testPacketSerialized;
- private MockFloodlightProvider mockFloodlightProvider;
- private Hub hub;
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- mockFloodlightProvider = getMockFloodlightProvider();
- hub = new Hub();
- mockFloodlightProvider.addOFMessageListener(OFType.PACKET_IN, hub);
- hub.setFloodlightProvider(mockFloodlightProvider);
-
- // Build our test packet
- this.testPacket = new Ethernet()
- .setDestinationMACAddress("00:11:22:33:44:55")
- .setSourceMACAddress("00:44:33:22:11:00")
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.1.2")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
- this.testPacketSerialized = testPacket.serialize();
-
- // Build the PacketIn
- this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(this.testPacketSerialized)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) this.testPacketSerialized.length);
- }
-
- @Test
- public void testFloodNoBufferId() throws Exception {
- // build our expected flooded packetOut
- OFPacketOut po = ((OFPacketOut) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT))
- .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(this.testPacketSerialized);
- po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU()
- + this.testPacketSerialized.length);
-
- // Mock up our expected behavior
- IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-
- Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
- Capture<FloodlightContext> bc1 = new Capture<FloodlightContext>(CaptureType.ALL);
-
- mockSwitch.write(capture(wc1), capture(bc1));
-
- // Start recording the replay on the mocks
- replay(mockSwitch);
- // Get the listener and trigger the packet in
- IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
- OFType.PACKET_IN).get(0);
- listener.receive(mockSwitch, this.packetIn,
- parseAndAnnotate(this.packetIn));
-
- // Verify the replay matched our expectations
- verify(mockSwitch);
-
- assertTrue(wc1.hasCaptured());
- OFMessage m = wc1.getValue();
- assert(m.equals(po));
- }
-
- @Test
- public void testFloodBufferId() throws Exception {
- MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider();
- this.packetIn.setBufferId(10);
-
- // build our expected flooded packetOut
- OFPacketOut po = ((OFPacketOut) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT))
- .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
- .setBufferId(10)
- .setInPort((short) 1);
- po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU());
-
- // Mock up our expected behavior
- IOFSwitch mockSwitch = createMock(IOFSwitch.class);
- Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
- Capture<FloodlightContext> bc1 = new Capture<FloodlightContext>(CaptureType.ALL);
-
- mockSwitch.write(capture(wc1), capture(bc1));
-
- // Start recording the replay on the mocks
- replay(mockSwitch);
- // Get the listener and trigger the packet in
- IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
- OFType.PACKET_IN).get(0);
- listener.receive(mockSwitch, this.packetIn,
- parseAndAnnotate(this.packetIn));
-
- // Verify the replay matched our expectations
- verify(mockSwitch);
-
- assertTrue(wc1.hasCaptured());
- OFMessage m = wc1.getValue();
- assert(m.equals(po));
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
deleted file mode 100644
index a68a1b8..0000000
--- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/**
-* Copyright 2011, Big Switch Networks, Inc.
-* Originally created by David Erickson, Stanford University
-*
-* 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 net.floodlightcontroller.learningswitch;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightTestModuleLoader;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.test.FloodlightTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class LearningSwitchTest extends FloodlightTestCase {
- protected OFPacketIn packetIn;
- protected IPacket testPacket;
- protected byte[] testPacketSerialized;
- protected IPacket broadcastPacket;
- protected byte[] broadcastPacketSerialized;
- protected IPacket testPacketReply;
- protected byte[] testPacketReplySerialized;
- private LearningSwitch learningSwitch;
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
- FloodlightTestModuleLoader fml = new FloodlightTestModuleLoader();
- Collection<Class<? extends IFloodlightModule>> mods
- = new ArrayList<Class<? extends IFloodlightModule>>();
- mods.add(LearningSwitch.class);
- fml.setupModules(mods, null);
- learningSwitch = (LearningSwitch) fml.getModuleByName(LearningSwitch.class);
- mockFloodlightProvider =
- (MockFloodlightProvider) fml.getModuleByName(MockFloodlightProvider.class);
-
- // Build our test packet
- this.testPacket = new Ethernet()
- .setDestinationMACAddress("00:11:22:33:44:55")
- .setSourceMACAddress("00:44:33:22:11:00")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.1.2")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
- this.testPacketSerialized = testPacket.serialize();
- // Build a broadcast packet
- this.broadcastPacket = new Ethernet()
- .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
- .setSourceMACAddress("00:44:33:22:11:00")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.255.255")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
-
- this.broadcastPacketSerialized = broadcastPacket.serialize();
- this.testPacketReply = new Ethernet()
- .setDestinationMACAddress("00:44:33:22:11:00")
- .setSourceMACAddress("00:11:22:33:44:55")
- .setVlanID((short) 42)
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.2")
- .setDestinationAddress("192.168.1.1")
- .setPayload(new UDP()
- .setSourcePort((short) 5001)
- .setDestinationPort((short) 5000)
- .setPayload(new Data(new byte[] {0x02}))));
- this.testPacketReplySerialized = testPacketReply.serialize();
-
- // Build the PacketIn
- this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(this.testPacketSerialized)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) this.testPacketSerialized.length);
- }
-
- @Test
- public void testFlood() throws Exception {
- // build our expected flooded packetOut
- OFPacketOut po = new OFPacketOut()
- .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
- .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
- .setBufferId(-1)
- .setInPort((short)1)
- .setPacketData(this.testPacketSerialized);
- po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU()
- + this.testPacketSerialized.length);
-
- // Mock up our expected behavior
- IOFSwitch mockSwitch = createMock(IOFSwitch.class);
- expect(mockSwitch.getStringId()).andReturn("00:11:22:33:44:55:66:77").anyTimes();
- mockSwitch.write(po, null);
-
- // Start recording the replay on the mocks
- replay(mockSwitch);
- // Get the listener and trigger the packet in
- IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
- OFType.PACKET_IN).get(0);
- // Make sure it's the right listener
- listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
-
- // Verify the replay matched our expectations
- short result = learningSwitch.getFromPortMap(mockSwitch, Ethernet.toLong(Ethernet.toMACAddress("00:44:33:22:11:00")), (short) 42).shortValue();
- verify(mockSwitch);
-
- // Verify the MAC table inside the switch
- assertEquals(1, result);
- }
-
- @Test
- public void testFlowMod() throws Exception {
- // tweak the test packet in since we need a bufferId
- this.packetIn.setBufferId(50);
-
- // build expected flow mods
- OFMessage fm1 = ((OFFlowMod) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD))
- .setActions(Arrays.asList(new OFAction[] {
- new OFActionOutput().setPort((short) 2).setMaxLength((short) -1)}))
- .setBufferId(50)
- .setCommand(OFFlowMod.OFPFC_ADD)
- .setIdleTimeout((short) 5)
- .setMatch(new OFMatch()
- .loadFromPacket(testPacketSerialized, (short) 1)
- .setWildcards(OFMatch.OFPFW_NW_PROTO | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST
- | OFMatch.OFPFW_NW_TOS))
- .setOutPort(OFPort.OFPP_NONE.getValue())
- .setCookie(1L << 52)
- .setPriority((short) 100)
- .setFlags((short)(1 << 0))
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
- OFMessage fm2 = ((OFFlowMod) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD))
- .setActions(Arrays.asList(new OFAction[] {
- new OFActionOutput().setPort((short) 1).setMaxLength((short) -1)}))
- .setBufferId(-1)
- .setCommand(OFFlowMod.OFPFC_ADD)
- .setIdleTimeout((short) 5)
- .setMatch(new OFMatch()
- .loadFromPacket(testPacketReplySerialized, (short) 2)
- .setWildcards(OFMatch.OFPFW_NW_PROTO | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST
- | OFMatch.OFPFW_NW_TOS))
- .setOutPort(OFPort.OFPP_NONE.getValue())
- .setCookie(1L << 52)
- .setPriority((short) 100)
- .setFlags((short)(1 << 0))
- .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-
- // Mock up our expected behavior
- IOFSwitch mockSwitch = createMock(IOFSwitch.class);
- expect(mockSwitch.getId()).andReturn(1L).anyTimes();
- expect(mockSwitch.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer) (OFMatch.OFPFW_IN_PORT | OFMatch.OFPFW_NW_PROTO
- | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST | OFMatch.OFPFW_NW_SRC_ALL
- | OFMatch.OFPFW_NW_DST_ALL | OFMatch.OFPFW_NW_TOS));
- mockSwitch.write(fm1, null);
- mockSwitch.write(fm2, null);
-
- // Start recording the replay on the mocks
- replay(mockSwitch);
-
- // Populate the MAC table
- learningSwitch.addToPortMap(mockSwitch,
- Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:55")), (short) 42, (short) 2);
-
- // Get the listener and trigger the packet in
- IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
- OFType.PACKET_IN).get(0);
- listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
-
- // Verify the replay matched our expectations
- short result = learningSwitch.getFromPortMap(mockSwitch, Ethernet.toLong(Ethernet.toMACAddress("00:44:33:22:11:00")), (short) 42).shortValue();
- verify(mockSwitch);
-
- // Verify the MAC table inside the switch
- assertEquals(1, result);
- }
-}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
deleted file mode 100644
index 1e71138..0000000
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package net.floodlightcontroller.linkdiscovery.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Iterator;
-import java.util.List;
-
-import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION;
-import net.floodlightcontroller.core.internal.TestDatabaseManager;
-import net.floodlightcontroller.linkdiscovery.ILinkStorage;
-import net.floodlightcontroller.routing.Link;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-
-public class LinkStorageImplTest {
- private static ILinkStorage linkStorage;
- private static TitanGraph titanGraph;
-
- //TODO Future ideas:
- //Test add links with CREATE and UPDATE
- //Test adding existing link again
-
- @Before
- public void setUp() throws Exception{
- titanGraph = TestDatabaseManager.getTestDatabase();
- TestDatabaseManager.populateTestData(titanGraph);
-
- linkStorage = new TestableLinkStorageImpl(titanGraph);
- }
-
- @After
- public void tearDown() throws Exception {
- titanGraph.shutdown();
- }
-
- /*
- * Add a link between port 1.102 and 2.104
- * i.e SEA switch port 3 to LAX switch port 1
- */
- @Test
- public void testAddSingleLink(){
- Link linkToAdd = new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a02"), 1);
-
- //Use the link storage API to add the link
- linkStorage.update(linkToAdd, ILinkStorage.DM_OPERATION.INSERT);
-
- //Test if it was added correctly with the Gremlin API
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator();
-
- assertTrue(it.hasNext());
- Vertex sw1 = it.next();
- assertFalse(it.hasNext());
-
- pipe.start(sw1).out("on").has("number", (short)3).out("link").in("on");
-
- assertTrue(pipe.hasNext());
- Vertex sw2 = pipe.next();
- assertFalse(pipe.hasNext());
-
- //Check we ended up at the right vertex
- assertEquals((String)sw2.getProperty("dpid"), "00:00:00:00:00:00:0a:02");
- }
-
- //TODO enable once method is written
- @Ignore @Test
- public void testGetLinks(){
- //TODO Make sure this works when the implementation is written
- List<Link> list = linkStorage.getLinks(Long.decode("0x0000000000000a01"), (short)2);
-
- assertEquals(list.size(), 1);
-
- Link l = list.get(0);
- assertEquals(l.getSrc(), 2561L);
- assertEquals(l.getSrcPort(), (short)2);
- assertEquals(l.getDst(), 2563L);
- assertEquals(l.getDstPort(), (short)1);
- }
-
- //TODO enable once method is written
- @Ignore @Test
- public void testUpdateDelete(){
- Link linkToDelete = new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1);
-
- linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
-
- //Test if it was deleted correctly with the Gremlin API
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator();
-
- assertTrue(it.hasNext());
- Vertex sw1 = it.next();
- assertFalse(it.hasNext());
-
- pipe.start(sw1).out("on").has("number", 2).out("link");
-
- assertFalse(pipe.hasNext());
- }
-
- //TODO enable once method is written
- @Ignore @Test
- public void testDeleteLinks(){
- //TODO Make sure this works when the implementation is written
-
- linkStorage.deleteLinksOnPort(Long.decode("0x0000000000000a01"), (short)2);
-
- //Test if it was deleted correctly with the Gremlin API
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator();
-
- assertTrue(it.hasNext());
- Vertex sw1 = it.next();
- assertFalse(it.hasNext());
-
- pipe.start(sw1).out("on").has("number", 2).out("link");
-
- assertFalse(pipe.hasNext());
- }
-
-}
diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
index e72179d..9232bb5 100644
--- a/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
+++ b/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
@@ -11,11 +11,11 @@
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.test.MockFloodlightProvider;
import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.topology.TopologyInstance;
import net.floodlightcontroller.topology.TopologyManager;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
import org.junit.Before;
import org.junit.Test;
diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
index 113cecb..1cf344d 100644
--- a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
+++ b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
@@ -4,10 +4,10 @@
import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
import net.floodlightcontroller.test.FloodlightTestCase;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.topology.TopologyManager;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
import org.junit.Before;
import org.junit.Test;
diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
index ffabf6f..59e0a51 100644
--- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
+++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
@@ -346,10 +346,4 @@
return 0;
}
- @Override
- public void setupRemoteSwitch(Long dpid) {
- // TODO Auto-generated method stub
-
- }
-
}
\ No newline at end of file
diff --git a/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java b/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
deleted file mode 100644
index 32afe4e..0000000
--- a/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import static org.easymock.EasyMock.*;
-
-import java.util.List;
-
-import org.easymock.EasyMock;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IListener.Command;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.core.test.PacketFactory;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClassifierService;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
-import net.floodlightcontroller.flowcache.FlowReconcileManager;
-import net.floodlightcontroller.flowcache.IFlowReconcileService;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.util.MACAddress;
-import net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter;
-
-public class VirtualNetworkFilterTest extends FloodlightTestCase {
- protected VirtualNetworkFilter vns;
- protected MockDeviceManager deviceService;
-
- protected static String guid1 = "guid1";
- protected static String net1 = "net1";
- protected static String gw1 = "1.1.1.1";
- protected static String guid2 = "guid2";
- protected static String net2 = "net2";
- protected static String guid3 = "guid3";
- protected static String net3 = "net3";
- protected static String gw2 = "2.2.2.2";
-
- protected static MACAddress mac1 =
- new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:55"));
- protected static MACAddress mac2 =
- new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:66"));
- protected static MACAddress mac3 =
- new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:77"));
- protected static MACAddress mac4 =
- new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:88"));
- protected static String hostPort1 = "port1";
- protected static String hostPort2 = "port2";
- protected static String hostPort3 = "port3";
- protected static String hostPort4 = "port4";
-
- // For testing forwarding behavior
- protected IOFSwitch sw1;
- protected FloodlightContext cntx;
- protected OFPacketIn mac1ToMac2PacketIn;
- protected IPacket mac1ToMac2PacketIntestPacket;
- protected byte[] mac1ToMac2PacketIntestPacketSerialized;
- protected OFPacketIn mac1ToMac4PacketIn;
- protected IPacket mac1ToMac4PacketIntestPacket;
- protected byte[] mac1ToMac4PacketIntestPacketSerialized;
- protected OFPacketIn mac1ToGwPacketIn;
- protected IPacket mac1ToGwPacketIntestPacket;
- protected byte[] mac1ToGwPacketIntestPacketSerialized;
- protected OFPacketIn packetInDHCPDiscoveryRequest;
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- // Module loading stuff
- FloodlightModuleContext fmc = new FloodlightModuleContext();
- RestApiServer restApi = new RestApiServer();
- deviceService = new MockDeviceManager();
- FlowReconcileManager frm = new FlowReconcileManager();
- MockThreadPoolService tps = new MockThreadPoolService();
- ITopologyService topology = createMock(ITopologyService.class);
- vns = new VirtualNetworkFilter();
- DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
- fmc.addService(IRestApiService.class, restApi);
- fmc.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
- fmc.addService(IDeviceService.class, deviceService);
- fmc.addService(IFlowReconcileService.class, frm);
- fmc.addService(IThreadPoolService.class, tps);
- fmc.addService(IEntityClassifierService.class, entityClassifier);
- fmc.addService(ITopologyService.class, topology);
- tps.init(fmc);
- frm.init(fmc);
- deviceService.init(fmc);
- restApi.init(fmc);
- getMockFloodlightProvider().init(fmc);
- entityClassifier.init(fmc);
- tps.startUp(fmc);
- vns.init(fmc);
- frm.startUp(fmc);
- deviceService.startUp(fmc);
- restApi.startUp(fmc);
- getMockFloodlightProvider().startUp(fmc);
- vns.startUp(fmc);
- entityClassifier.startUp(fmc);
-
- topology.addListener(deviceService);
- expectLastCall().times(1);
- replay(topology);
- // Mock switches
- //fastWilcards mocked as this constant
- int fastWildcards =
- OFMatch.OFPFW_IN_PORT |
- OFMatch.OFPFW_NW_PROTO |
- OFMatch.OFPFW_TP_SRC |
- OFMatch.OFPFW_TP_DST |
- OFMatch.OFPFW_NW_SRC_ALL |
- OFMatch.OFPFW_NW_DST_ALL |
- OFMatch.OFPFW_NW_TOS;
- sw1 = EasyMock.createNiceMock(IOFSwitch.class);
- expect(sw1.getId()).andReturn(1L).anyTimes();
- expect(sw1.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer)fastWildcards).anyTimes();
- expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
- replay(sw1);
-
- // Mock packets
- // Mock from MAC1 -> MAC2
- mac1ToMac2PacketIntestPacket = new Ethernet()
- .setDestinationMACAddress(mac2.toBytes())
- .setSourceMACAddress(mac1.toBytes())
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.1.2")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
- mac1ToMac2PacketIntestPacketSerialized = mac1ToMac2PacketIntestPacket.serialize();
- mac1ToMac2PacketIn =
- ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(mac1ToMac2PacketIntestPacketSerialized)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) mac1ToMac2PacketIntestPacketSerialized.length);
-
- // Mock from MAC1 -> MAC4
- mac1ToMac4PacketIntestPacket = new Ethernet()
- .setDestinationMACAddress(mac4.toBytes())
- .setSourceMACAddress(mac1.toBytes())
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress("192.168.1.2")
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
- mac1ToMac4PacketIntestPacketSerialized = mac1ToMac4PacketIntestPacket.serialize();
- mac1ToMac4PacketIn =
- ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(mac1ToMac4PacketIntestPacketSerialized)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) mac1ToMac4PacketIntestPacketSerialized.length);
-
- // Mock from MAC1 to gateway1
- mac1ToGwPacketIntestPacket = new Ethernet()
- .setDestinationMACAddress("00:11:33:33:44:55") // mac shouldn't matter, can't be other host
- .setSourceMACAddress(mac1.toBytes())
- .setEtherType(Ethernet.TYPE_IPv4)
- .setPayload(
- new IPv4()
- .setTtl((byte) 128)
- .setSourceAddress("192.168.1.1")
- .setDestinationAddress(gw1)
- .setPayload(new UDP()
- .setSourcePort((short) 5000)
- .setDestinationPort((short) 5001)
- .setPayload(new Data(new byte[] {0x01}))));
- mac1ToGwPacketIntestPacketSerialized = mac1ToGwPacketIntestPacket.serialize();
- mac1ToGwPacketIn =
- ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
- getMessage(OFType.PACKET_IN))
- .setBufferId(-1)
- .setInPort((short) 1)
- .setPacketData(mac1ToGwPacketIntestPacketSerialized)
- .setReason(OFPacketInReason.NO_MATCH)
- .setTotalLength((short) mac1ToGwPacketIntestPacketSerialized.length);
- }
-
- @Test
- public void testCreateNetwork() {
- // Test creating a network with all parameters
- vns.createNetwork(guid1, net1, IPv4.toIPv4Address(gw1));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
- assertTrue(vns.nameToGuid.get(net1).equals(guid1));
- assertTrue(vns.guidToGateway.get(guid1).equals(IPv4.toIPv4Address(gw1)));
- assertTrue(vns.vNetsByGuid.get(guid1).name.equals(net1));
- assertTrue(vns.vNetsByGuid.get(guid1).guid.equals(guid1));
- assertTrue(vns.vNetsByGuid.get(guid1).gateway.equals(gw1));
- assertTrue(vns.vNetsByGuid.get(guid1).hosts.size()==0);
-
- // Test creating network without a gateway
- vns.createNetwork(guid2, net2, null);
- assertTrue(vns.nameToGuid.get(net2).equals(guid2));
- assertTrue(vns.guidToGateway.get(guid2) == null);
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 1);
- assertTrue(vns.vNetsByGuid.get(guid2).name.equals(net2));
- assertTrue(vns.vNetsByGuid.get(guid2).guid.equals(guid2));
- assertTrue(vns.vNetsByGuid.get(guid2).gateway == null);
- assertTrue(vns.vNetsByGuid.get(guid2).hosts.size()==0);
-
- // Test creating a network that shares the gateway with net1
- vns.createNetwork(guid3, net3, IPv4.toIPv4Address(gw1));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 2);
- assertTrue(vns.nameToGuid.get(net3).equals(guid3));
- assertTrue(vns.guidToGateway.get(guid3).equals(IPv4.toIPv4Address(gw1)));
- assertTrue(vns.vNetsByGuid.get(guid3).name.equals(net3));
- assertTrue(vns.vNetsByGuid.get(guid3).guid.equals(guid3));
- assertTrue(vns.vNetsByGuid.get(guid3).gateway.equals(gw1));
- assertTrue(vns.vNetsByGuid.get(guid3).hosts.size()==0);
-
- }
-
- @Test
- public void testModifyNetwork() {
- // Create some networks
-
- testCreateNetwork();
- // Modify net2 to add a gateway
- vns.createNetwork(guid2, net2, IPv4.toIPv4Address(gw1));
- assertTrue(vns.nameToGuid.get(net2).equals(guid2));
- assertTrue(vns.guidToGateway.get(guid2).equals(IPv4.toIPv4Address(gw1)));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid2));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 3);
- // Modify net2 to change it's name
- vns.createNetwork(guid2, "newnet2", null);
- // Make sure the gateway is still there
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid2));
- assertTrue(vns.vNetsByGuid.get(guid2).gateway.equals(gw1));
- // make sure the new name mapping was learned
- assertTrue(vns.nameToGuid.get("newnet2").equals(guid2));
- assertTrue(vns.vNetsByGuid.get(guid2).name.equals("newnet2"));
- // and the old one was deleted
- assertFalse(vns.nameToGuid.containsKey(net2));
- }
-
- @Test
- public void testDeleteNetwork() {
- testModifyNetwork();
- // Delete newnet2
- vns.deleteNetwork(guid2);
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
- assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 2);
- assertFalse(vns.nameToGuid.containsKey(net2));
- assertFalse(vns.guidToGateway.containsKey(net2));
- assertTrue(vns.vNetsByGuid.get(guid2)==null);
- }
-
- @Test
- public void testAddHost() {
- testModifyNetwork();
- vns.addHost(mac1, guid1, hostPort1);
- assertTrue(vns.macToGuid.get(mac1).equals(guid1));
- assertTrue(vns.portToMac.get(hostPort1).equals(mac1));
- assertTrue(vns.vNetsByGuid.get(guid1).hosts.contains(mac1));
- vns.addHost(mac2, guid1, hostPort2);
- assertTrue(vns.macToGuid.get(mac2).equals(guid1));
- assertTrue(vns.portToMac.get(hostPort2).equals(mac2));
- assertTrue(vns.vNetsByGuid.get(guid1).hosts.contains(mac2));
- vns.addHost(mac3, guid3, hostPort3);
- vns.addHost(mac4, guid3, hostPort4);
- assertTrue(vns.vNetsByGuid.get(guid3).hosts.contains(mac4));
- }
-
- @Test
- public void testDeleteHost() {
- testAddHost();
-
- String host1Guid = vns.macToGuid.get(mac1);
- vns.deleteHost(mac1, null);
- assertFalse(vns.macToGuid.containsKey(mac1));
- assertFalse(vns.portToMac.containsKey(hostPort1));
- assertFalse(vns.vNetsByGuid.get(host1Guid).hosts.contains(mac1));
-
- String host2Guid = vns.macToGuid.get(vns.portToMac.get(hostPort2));
- vns.deleteHost(null, hostPort2);
- assertFalse(vns.macToGuid.containsKey(mac2));
- assertFalse(vns.portToMac.containsKey(hostPort2));
- assertFalse(vns.vNetsByGuid.get(host2Guid).hosts.contains(mac2));
-
- String host3Guid = vns.macToGuid.get(mac3);
- vns.deleteHost(mac3, hostPort3);
- assertFalse(vns.macToGuid.containsKey(mac3));
- assertFalse(vns.portToMac.containsKey(hostPort3));
- assertFalse(vns.vNetsByGuid.get(host3Guid).hosts.contains(mac3));
-
- }
-
- @Test
- public void testForwarding() {
- testAddHost();
- // make sure mac1 can communicate with mac2
- IOFMessageListener listener = getVirtualNetworkListener();
- cntx = new FloodlightContext();
- IFloodlightProviderService.bcStore.put(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
- (Ethernet)mac1ToMac2PacketIntestPacket);
- Command ret = listener.receive(sw1, mac1ToMac2PacketIn, cntx);
- assertTrue(ret == Command.CONTINUE);
- // make sure mac1 can't communicate with mac4
- cntx = new FloodlightContext();
- IFloodlightProviderService.bcStore.put(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
- (Ethernet)mac1ToMac4PacketIntestPacket);
- ret = listener.receive(sw1, mac1ToMac4PacketIn, cntx);
- assertTrue(ret == Command.STOP);
- }
-
- @Test
- public void testDefaultGateway() {
- testAddHost();
- IOFMessageListener listener = getVirtualNetworkListener();
- cntx = new FloodlightContext();
- IFloodlightProviderService.bcStore.put(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
- (Ethernet)mac1ToGwPacketIntestPacket);
- deviceService.learnEntity(((Ethernet)mac1ToGwPacketIntestPacket).getDestinationMAC().toLong(),
- null, IPv4.toIPv4Address(gw1), null, null);
- Command ret = listener.receive(sw1, mac1ToGwPacketIn, cntx);
- assertTrue(ret == Command.CONTINUE);
- }
-
- @Test
- public void testDhcp() {
- IOFMessageListener listener = getVirtualNetworkListener();
- Ethernet dhcpPacket = PacketFactory.DhcpDiscoveryRequestEthernet(mac1);
- OFPacketIn dhcpPacketOf = PacketFactory.DhcpDiscoveryRequestOFPacketIn(mac1);
- cntx = new FloodlightContext();
- IFloodlightProviderService.bcStore.put(cntx,
- IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
- dhcpPacket);
- Command ret = listener.receive(sw1, dhcpPacketOf, cntx);
- assertTrue(ret == Command.CONTINUE);
- }
-
- protected IOFMessageListener getVirtualNetworkListener() {
- List<IOFMessageListener> listeners = mockFloodlightProvider.getListeners().get(OFType.PACKET_IN);
- return listeners.get(listeners.indexOf(vns));
- }
-}
diff --git a/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java b/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java
new file mode 100644
index 0000000..bee936d
--- /dev/null
+++ b/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java
@@ -0,0 +1,229 @@
+/**
+ *
+ */
+package net.onrc.onos.graph;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.expect;
+import static org.powermock.api.easymock.PowerMock.*;
+
+import java.util.*;
+
+import net.onrc.onos.graph.GraphDBOperation;
+
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
+import com.tinkerpop.frames.FramedGraph;
+
+/**
+ * @author Toshio Koide
+ *
+ */
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({
+ GraphDBConnection.class,
+ GraphDBOperation.class,
+ TitanFactory.class,
+ EventTransactionalGraph.class})
+public class GraphDBConnectionTest {
+ private static TitanGraph graph = null;
+ private static EventTransactionalGraph<TitanGraph> eg = null;
+ private static Boolean isGraphOpen = false;
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ }
+
+
+ private void expectDBConnectionAvailable() throws Exception {
+ isGraphOpen = false;
+
+ // create mock objects
+ mockStatic(TitanFactory.class);
+ mockStatic(EventTransactionalGraph.class);
+ graph = createMock(TitanGraph.class);
+ eg = createMock(EventTransactionalGraph.class);
+
+ // setup expectations
+ expect(graph.isOpen()).andAnswer(new IAnswer<Boolean>() {
+ @Override
+ public Boolean answer() throws Throwable {
+ return isGraphOpen;
+ }
+ }).anyTimes();
+ expect(TitanFactory.open("/path/to/dummy")).andAnswer(new IAnswer<TitanGraph>() {
+ @Override
+ public TitanGraph answer() throws Throwable {
+ isGraphOpen = true;
+ return graph;
+ }
+ }).anyTimes();
+ expect(graph.getIndexedKeys(Vertex.class)).andReturn(new TreeSet<String>());
+ graph.createKeyIndex("dpid", Vertex.class);
+ graph.createKeyIndex("port_id", Vertex.class);
+ graph.createKeyIndex("type", Vertex.class);
+ graph.createKeyIndex("dl_addr", Vertex.class);
+ graph.createKeyIndex("flow_id", Vertex.class);
+ graph.createKeyIndex("flow_entry_id", Vertex.class);
+ graph.createKeyIndex("switch_state", Vertex.class);
+ graph.commit();
+ expectNew(EventTransactionalGraph.class, graph).andReturn(eg);
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBConnection#getInstance(java.lang.String)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetInstance() throws Exception {
+ // setup expectations
+ expectDBConnectionAvailable();
+
+ // start the test
+ replayAll();
+ GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+
+ // verify the test
+ verifyAll();
+ assertNotNull(conn);
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBConnection#getFramedGraph()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetFramedGraph() throws Exception {
+ // setup expectations
+ expectDBConnectionAvailable();
+
+ // start the test
+ replayAll();
+ GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+
+ // verify the test
+ verifyAll();
+ assertNotNull(fg);
+ assertEquals(graph, fg.getBaseGraph());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBConnection#addEventListener(net.onrc.onos.graph.LocalGraphChangedListener)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testAddEventListener() throws Exception {
+ // instantiate required objects
+ LocalGraphChangedListener listener = new LocalTopologyEventListener(null);
+
+ // setup expectations
+ expectDBConnectionAvailable();
+ eg.addListener(listener);
+
+ // start the test
+ replayAll();
+ GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+ conn.addEventListener(listener);
+
+ // verify the test
+ verifyAll();
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBConnection#isValid()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testIsValid() throws Exception {
+ // setup expectations
+ expectDBConnectionAvailable();
+
+ // start the test
+ replayAll();
+ GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+ Boolean result = conn.isValid();
+
+ // verify the test
+ verifyAll();
+ assertTrue(result);
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBConnection#commit()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testCommit() throws Exception {
+ // setup expectations
+ expectDBConnectionAvailable();
+ graph.commit();
+
+ // start the test
+ replayAll();
+ GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+ conn.commit();
+
+ // verify the test
+ verifyAll();
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBConnection#rollback()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testRollback() throws Exception {
+ // setup expectations
+ expectDBConnectionAvailable();
+ graph.rollback();
+
+ // start the test
+ replayAll();
+ GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+ conn.rollback();
+
+ // verify the test
+ verifyAll();
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBConnection#close()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testClose() throws Exception {
+ // setup expectations
+ expectDBConnectionAvailable();
+ graph.commit();
+
+ // start the test
+ replayAll();
+ GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+ conn.close();
+
+ // verify the test
+ verifyAll();
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java b/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
new file mode 100644
index 0000000..e99ca81
--- /dev/null
+++ b/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
@@ -0,0 +1,596 @@
+/**
+ *
+ */
+package net.onrc.onos.graph;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import junit.framework.TestCase;
+
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+
+/**
+ * @author Toshio Koide
+ *
+ */
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class})
+public class GraphDBOperationTest extends TestCase {
+ private static TitanGraph testdb;
+ private static GraphDBOperation op;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ TestDatabaseManager.deleteTestDatabase();
+ testdb = TestDatabaseManager.getTestDatabase();
+// TestDatabaseManager.populateTestData(titanGraph);
+
+ String dummyPath = "/dummy/to/conf";
+ // replace return value of TitanFactory.open() to dummy DB created above
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open(dummyPath)).andReturn(testdb);
+ PowerMock.replay(TitanFactory.class);
+
+ op = new GraphDBOperation(dummyPath);
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ op.close();
+ testdb.shutdown();
+ PowerMock.verifyAll();
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newSwitch(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testNewSwitch() {
+ assertNull(op.searchSwitch("123"));
+
+ ISwitchObject sw = op.newSwitch("123");
+ assertEquals(sw.getDPID(), "123");
+ op.commit();
+
+ sw = op.searchSwitch("123");
+ assertNotNull(sw);
+ assertEquals("123", sw.getDPID());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchSwitch(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
+ */
+ @Test
+ public final void testSearchSwitch() {
+ op.newSwitch("123");
+ op.newSwitch("456");
+ op.commit();
+
+ ISwitchObject sw = op.searchSwitch("123");
+ assertNotNull(sw);
+ assertEquals("123", sw.getDPID());
+
+ sw = op.searchSwitch("789");
+ assertNull(sw);
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchActiveSwitch(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
+ */
+ @Test
+ public final void testSearchActiveSwitch() {
+ op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
+ op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
+ op.commit();
+
+ ISwitchObject sw = op.searchActiveSwitch("111");
+ assertNotNull(sw);
+ assertEquals("111", sw.getDPID());
+
+ sw = op.searchActiveSwitch("222");
+ assertNull(sw);
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getActiveSwitches(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testGetActiveSwitches() {
+ op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
+ op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
+ op.commit();
+
+ Iterator<ISwitchObject> i = op.getActiveSwitches().iterator();
+
+ assertTrue(i.hasNext());
+ assertEquals("111", i.next().getDPID());
+ assertFalse(i.hasNext());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllSwitches(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testGetAllSwitches() {
+ List<String> dpids = Arrays.asList("111", "222", "333");
+ Collections.sort(dpids);
+
+ for (String dpid: dpids) op.newSwitch(dpid);
+ op.commit();
+
+ List<String> actual_ids = new ArrayList<String>();
+ for (ISwitchObject switchObj: op.getAllSwitches()) actual_ids.add(switchObj.getDPID());
+ Collections.sort(actual_ids);
+
+ assertArrayEquals(dpids.toArray(), actual_ids.toArray());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getInactiveSwitches(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testGetInactiveSwitches() {
+ op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
+ op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
+ op.commit();
+
+ Iterator<ISwitchObject> i = op.getInactiveSwitches().iterator();
+
+ assertTrue(i.hasNext());
+ assertEquals("222", i.next().getDPID());
+ assertFalse(i.hasNext());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllSwitchNotUpdatedFlowEntries(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testGetAllSwitchNotUpdatedFlowEntries() {
+ FlowEntryId flowEntryId10 = new FlowEntryId(10);
+ FlowEntryId flowEntryId20 = new FlowEntryId(20);
+ IFlowEntry flowEntry10 = op.newFlowEntry();
+ IFlowEntry flowEntry20 = op.newFlowEntry();
+ flowEntry10.setFlowEntryId(flowEntryId10.toString());
+ flowEntry20.setFlowEntryId(flowEntryId20.toString());
+ flowEntry10.setSwitchState("FE_SWITCH_NOT_UPDATED");
+ flowEntry20.setSwitchState("FE_SWITCH_UPDATED");
+ op.commit();
+
+ Iterator<IFlowEntry> flowEntries = op.getAllSwitchNotUpdatedFlowEntries().iterator();
+ assertNotNull(flowEntries);
+ assertTrue(flowEntries.hasNext());
+ assertEquals(flowEntryId10.toString(), flowEntries.next().getFlowEntryId());
+ assertFalse(flowEntries.hasNext());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeSwitch(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject)}.
+ */
+ @Test
+ public final void testRemoveSwitch() {
+ ISwitchObject sw = op.newSwitch("123");
+ op.commit();
+ sw = op.searchSwitch("123");
+ assertNotNull(sw);
+
+ op.removeSwitch(sw);
+ op.commit();
+
+ assertNull(op.searchSwitch("123"));
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newPort(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testNewPort() {
+ assertFalse(testdb.getVertices("type", "port").iterator().hasNext());
+
+ IPortObject port = op.newPort("1", (short) 10);
+ assertTrue(port.getNumber() == 10);
+ op.commit();
+
+ Iterator<Vertex> vertices = testdb.getVertices("type", "port").iterator();
+ assertTrue(vertices.hasNext());
+ assertEquals(vertices.next().getProperty("number").toString(), "10");
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchPort(net.onrc.onos.graph.GraphDBConnection, java.lang.String, short)}.
+ */
+ @Test
+ public final void testSearchPort() {
+ ISwitchObject sw;
+ IPortObject port;
+
+ sw = op.newSwitch("1");
+ sw.addPort(op.newPort("1", (short) 1));
+ sw.addPort(op.newPort("1", (short) 2));
+
+ sw = op.newSwitch("2");
+ sw.addPort(op.newPort("2", (short) 1));
+ sw.addPort(op.newPort("2", (short) 2));
+
+ op.commit();
+
+ assertNull(op.searchPort("3", (short) 1));
+ assertNull(op.searchPort("1", (short) 3));
+
+ port = op.searchPort("1", (short) 1);
+ assertNotNull(port);
+ assertTrue(port.getNumber() == 1);
+ sw = port.getSwitch();
+ assertNotNull(sw);
+ assertEquals("1", sw.getDPID());
+
+ port = op.searchPort("1", (short) 2);
+ assertNotNull(port);
+ assertTrue(port.getNumber() == 2);
+ sw = port.getSwitch();
+ assertNotNull(sw);
+ assertEquals("1", sw.getDPID());
+
+ port = op.searchPort("2", (short) 1);
+ assertNotNull(port);
+ assertTrue(port.getNumber() == 1);
+ sw = port.getSwitch();
+ assertNotNull(sw);
+ assertEquals("2", sw.getDPID());
+
+ port = op.searchPort("2", (short) 2);
+ assertNotNull(port);
+ assertTrue(port.getNumber() == 2);
+ sw = port.getSwitch();
+ assertNotNull(sw);
+ assertEquals("2", sw.getDPID());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removePort(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject)}.
+ */
+ @Test
+ public final void testRemovePort() {
+ ISwitchObject sw;
+ IPortObject port;
+
+ sw = op.newSwitch("1");
+ sw.addPort(op.newPort("1", (short) 1));
+ sw.addPort(op.newPort("1", (short) 2));
+
+ op.commit();
+
+ port = op.searchPort("1", (short) 1);
+ assertNotNull(port);
+ assertNotNull(op.searchPort("1", (short) 2));
+ assertNull(op.searchPort("1", (short) 3));
+
+ op.removePort(port);
+ op.commit();
+
+ assertNull(op.searchPort("1", (short) 1));
+ port = op.searchPort("1", (short) 2);
+ assertNotNull(port);
+
+ op.removePort(port);
+ op.commit();
+
+ assertNull(op.searchPort("1", (short) 1));
+ assertNull(op.searchPort("1", (short) 2));
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newDevice(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testNewDevice() {
+ assertFalse(testdb.getVertices("type", "device").iterator().hasNext());
+
+ IDeviceObject device = op.newDevice();
+ device.setMACAddress("11:22:33:44:55:66");
+ device.setIPAddress("192.168.1.1");
+ op.commit();
+
+ Iterator<Vertex> vertices = testdb.getVertices("type", "device").iterator();
+ assertTrue(vertices.hasNext());
+ Vertex v = vertices.next();
+ assertEquals("11:22:33:44:55:66", v.getProperty("dl_addr").toString());
+ assertEquals("192.168.1.1", v.getProperty("nw_addr").toString());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchDevice(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
+ */
+ @Test
+ public final void testSearchDevice() {
+ assertNull(op.searchDevice("11:22:33:44:55:66"));
+ assertNull(op.searchDevice("66:55:44:33:22:11"));
+
+ op.newDevice().setMACAddress("11:22:33:44:55:66");
+ op.commit();
+
+ IDeviceObject device = op.searchDevice("11:22:33:44:55:66");
+ assertNotNull(device);
+ assertEquals("11:22:33:44:55:66", device.getMACAddress());
+
+ assertNull(op.searchDevice("66:55:44:33:22:11"));
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getDevices(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testGetDevices() {
+ List<String> original_macs = Arrays.asList(
+ "11:11:11:11:11:11",
+ "22:22:22:22:22:22",
+ "33:33:33:33:33:33"
+ );
+
+ for (String mac: original_macs) op.newDevice().setMACAddress(mac);
+ op.commit();
+
+ Iterable<IDeviceObject> devices = op.getDevices();
+ List<String> macs = new ArrayList<String>();
+ for (IDeviceObject device: devices) macs.add(device.getMACAddress());
+ Collections.sort(macs);
+ assertArrayEquals(original_macs.toArray(), macs.toArray());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeDevice(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject)}.
+ */
+ @Test
+ public final void testRemoveDevice() {
+ op.newDevice().setMACAddress("11:22:33:44:55:66");
+ op.commit();
+
+ op.removeDevice(op.searchDevice("11:22:33:44:55:66"));
+ op.commit();
+ assertNull(op.searchDevice("11:22:33:44:55:66"));
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newFlowPath(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testNewFlowPath() {
+ FlowId flowId = new FlowId(10);
+ IFlowPath flowPath = op.newFlowPath();
+ flowPath.setFlowId(flowId.toString());
+ op.commit();
+
+ Iterator<IFlowPath> flows = op.getAllFlowPaths().iterator();
+ assertTrue(flows.hasNext());
+ assertEquals(flowId.toString(), flows.next().getFlowId());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchFlowPath(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.util.FlowId)}.
+ */
+ @Test
+ public final void testSearchFlowPath() {
+ FlowId flowId = new FlowId(20);
+ assertNull(op.searchFlowPath(flowId));
+
+ op.newFlowPath().setFlowId(flowId.toString());
+ op.commit();
+
+ IFlowPath flowPath = op.searchFlowPath(flowId);
+ assertNotNull(flowPath);
+ assertEquals(flowId.toString(), flowPath.getFlowId());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getFlowPathByFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
+ */
+ @Test
+ public final void testGetFlowPathByFlowEntry() {
+ FlowId flowId10 = new FlowId(10);
+ FlowId flowId20 = new FlowId(20);
+ IFlowPath flowPath10 = op.newFlowPath();
+ IFlowPath flowPath20 = op.newFlowPath();
+ IFlowEntry flowEntry10 = op.newFlowEntry();
+ IFlowEntry flowEntry20 = op.newFlowEntry();
+ IFlowEntry flowEntry30 = op.newFlowEntry();
+ FlowEntryId flowEntryId10 = new FlowEntryId(10);
+ FlowEntryId flowEntryId20 = new FlowEntryId(20);
+ FlowEntryId flowEntryId30 = new FlowEntryId(30);
+ flowEntry10.setFlowEntryId(flowEntryId10.toString());
+ flowEntry20.setFlowEntryId(flowEntryId20.toString());
+ flowEntry30.setFlowEntryId(flowEntryId30.toString());
+ flowPath10.setFlowId(flowId10.toString());
+ flowPath10.addFlowEntry(flowEntry10);
+ flowPath20.setFlowId(flowId20.toString());
+ flowPath20.addFlowEntry(flowEntry20);
+ op.commit();
+
+ flowEntry10 = op.searchFlowEntry(flowEntryId10);
+ IFlowPath obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry10);
+ assertNotNull(obtainedFlowPath);
+ assertEquals(flowId10.toString(), obtainedFlowPath.getFlowId());
+
+ flowEntry20 = op.searchFlowEntry(flowEntryId20);
+ obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry20);
+ assertNotNull(obtainedFlowPath);
+ assertEquals(flowId20.toString(), obtainedFlowPath.getFlowId());
+
+ flowEntry30 = op.searchFlowEntry(flowEntryId30);
+ obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry30);
+ assertNull(obtainedFlowPath);
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllFlowPaths(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testGetAllFlowPaths() {
+ List<FlowId> flowids = Arrays.asList(
+ new FlowId(10), new FlowId(20), new FlowId(30)
+ );
+
+ for (FlowId flowId: flowids)
+ op.newFlowPath().setFlowId(flowId.toString());
+ op.commit();
+
+ List<String> actual_ids = new ArrayList<String>();
+ for (IFlowPath flowPath: op.getAllFlowPaths()) actual_ids.add(flowPath.getFlowId());
+ Collections.sort(actual_ids);
+
+ List<String> expected_ids = new ArrayList<String>();
+ for (FlowId flowid: flowids) expected_ids.add(flowid.toString());
+ Collections.sort(expected_ids);
+
+ assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeFlowPath(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath)}.
+ */
+ @Test
+ public final void testRemoveFlowPath() {
+ FlowId flowId10 = new FlowId(10);
+ FlowId flowId20 = new FlowId(20);
+ op.newFlowPath().setFlowId(flowId10.toString());
+ op.newFlowPath().setFlowId(flowId20.toString());
+ op.commit();
+
+ IFlowPath flowPath = op.searchFlowPath(flowId10);
+ assertNotNull(flowPath);
+ op.removeFlowPath(flowPath);
+ op.commit();
+
+ assertNull(op.searchFlowPath(flowId10));
+ assertNotNull(op.searchFlowPath(flowId20));
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newFlowEntry(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testNewFlowEntry() {
+ IFlowEntry flowEntry = op.newFlowEntry();
+ FlowEntryId flowEntryId = new FlowEntryId();
+ flowEntryId.setValue(12345);
+ flowEntry.setFlowEntryId(flowEntryId.toString());
+ op.commit();
+
+ flowEntry = op.searchFlowEntry(flowEntryId);
+ assertNotNull(flowEntry);
+ assertEquals(flowEntry.getFlowEntryId(), flowEntryId.toString());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.util.FlowEntryId)}.
+ */
+ @Test
+ public final void testSearchFlowEntry() {
+ FlowEntryId flowEntryId10 = new FlowEntryId();
+ flowEntryId10.setValue(10);
+ FlowEntryId flowEntryId20 = new FlowEntryId();
+ flowEntryId20.setValue(20);
+ FlowEntryId flowEntryId30 = new FlowEntryId();
+ flowEntryId30.setValue(30);
+
+ op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
+ op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
+ op.commit();
+
+ assertNull(op.searchFlowEntry(flowEntryId30));
+ IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
+ assertEquals(flowEntry.getFlowEntryId(), flowEntryId10.toString());
+ flowEntry = op.searchFlowEntry(flowEntryId20);
+ assertEquals(flowEntry.getFlowEntryId(), flowEntryId20.toString());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllFlowEntries(net.onrc.onos.graph.GraphDBConnection)}.
+ */
+ @Test
+ public final void testGetAllFlowEntries() {
+ List<FlowEntryId> flowEntryIds = Arrays.asList(
+ new FlowEntryId(10), new FlowEntryId(20), new FlowEntryId(30)
+ );
+
+ for (FlowEntryId flowEntryId: flowEntryIds)
+ op.newFlowEntry().setFlowEntryId(flowEntryId.toString());
+ op.commit();
+
+ List<String> actual_ids = new ArrayList<String>();
+ for (IFlowEntry flowEntry: op.getAllFlowEntries()) actual_ids.add(flowEntry.getFlowEntryId());
+ Collections.sort(actual_ids);
+
+ List<String> expected_ids = new ArrayList<String>();
+ for (FlowEntryId flowEntryId: flowEntryIds) expected_ids.add(flowEntryId.toString());
+ Collections.sort(expected_ids);
+
+ assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
+ }
+
+ /**
+ * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
+ */
+ @Test
+ public final void testRemoveFlowEntry() {
+ FlowEntryId flowEntryId10 = new FlowEntryId(10);
+ FlowEntryId flowEntryId20 = new FlowEntryId(20);
+ op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
+ op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
+ op.commit();
+
+ IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
+ assertNotNull(flowEntry);
+ op.removeFlowEntry(flowEntry);
+ op.commit();
+
+ assertNull(op.searchFlowEntry(flowEntryId10));
+ assertNotNull(op.searchFlowEntry(flowEntryId20));
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java
new file mode 100644
index 0000000..3ea90ba
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java
@@ -0,0 +1,206 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsIDeviceObjectTest {
+
+ //The test network is ./titan/schema/test-network.xml
+
+ protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ private GraphDBConnection conn = null;
+ private GraphDBOperation ope = null;
+ private TitanGraph titanGraph = null;
+
+ @Before
+ public void setUp() throws Exception {
+ conf = "/dummy/path/to/db";
+
+ // Make mock cassandra DB
+ // Replace TitanFactory.open() to return mock DB
+ TestDatabaseManager.deleteTestDatabase();
+ titanGraph = TestDatabaseManager.getTestDatabase();
+ //TestDatabaseManager.populateTestData(titanGraph);
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
+
+ conn = GraphDBConnection.getInstance(conf);
+ ope = new GraphDBOperation(conn);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set MacAddress method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the mac address.
+ * 2. Should get the mac address.
+ */
+ @Test
+ public void testSetGetMacAddress() {
+ String macaddr = "00:00:00:00:00:00:0a:07";
+ IDeviceObject devObj = ope.newDevice();
+ devObj.setMACAddress(macaddr);
+ assertEquals(devObj.getMACAddress(), macaddr);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set IPAddress method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the ip address.
+ * 2. Should get the ip address.
+ */
+ @Test
+ public void testSetGetIPAddress() {
+ String ipaddr = "192.168.0.1";
+ IDeviceObject devObj = ope.newDevice();
+ devObj.setIPAddress(ipaddr);
+ assertEquals(devObj.getIPAddress(), ipaddr);
+ }
+
+ /**
+ * Desc:
+ * Test method for get attached port.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get the attached ports.
+ */
+ @Test
+ public void testGetAttachedPort() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ Short number = 1;
+ Short number2 = 2;
+ IPortObject portObj = ope.newPort(dpid, number);
+ IPortObject portObj2 = ope.newPort(dpid, number2);
+
+ String ipaddr = "192.168.0.1";
+ IDeviceObject devObj = ope.newDevice();
+
+ portObj.setDevice(devObj);
+ portObj2.setDevice(devObj);
+
+ HashMap<Short, IPortObject> portObjectList = new HashMap<Short, IPortObject>();
+ for(IPortObject port : devObj.getAttachedPorts())
+ {
+ portObjectList.put(port.getNumber(), port);
+ }
+
+ assertTrue(portObjectList.containsValue(portObj));
+ assertTrue(portObjectList.containsValue(portObj2));
+
+ }
+
+ /**
+ * Desc:
+ * Test method for set and remove host port method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set host port from the device.
+ * 2. Should remove host port from the device.
+ */
+ @Test
+ public void testSetRemoveHostPort() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ Short number = 1;
+ Short number2 = 2;
+ IPortObject portObj = ope.newPort(dpid, number);
+ IPortObject portObj2 = ope.newPort(dpid, number2);
+
+ String ipaddr = "192.168.0.1";
+ IDeviceObject devObj = ope.newDevice();
+
+ devObj.setHostPort(portObj);
+
+ HashMap<String, IDeviceObject> portObjectList = new HashMap<String, IDeviceObject>();
+ for(IDeviceObject dev : portObj.getDevices())
+ {
+ portObjectList.put(dev.getMACAddress(), dev);
+ }
+ assertTrue(portObjectList.containsValue(devObj));
+
+ devObj.removeHostPort(portObj);
+
+ HashMap<String, IDeviceObject> portObjectList2 = new HashMap<String, IDeviceObject>();
+ for(IDeviceObject dev : portObj.getDevices())
+ {
+ portObjectList2.put(dev.getMACAddress(), dev);
+ }
+ assertTrue(!portObjectList2.containsValue(devObj));
+ }
+
+ /**
+ * Desc:
+ * Test method for getSwitch method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get the switch connected to the device.
+ */
+ @Test
+ public void testGetSwitches() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String dpid2 = "00:00:00:00:00:00:0a:08";
+ Short number = 1;
+ Short number2 = 2;
+ ISwitchObject swObj = ope.newSwitch(dpid);
+ ISwitchObject swObj2 = ope.newSwitch(dpid2);
+ IPortObject portObj = ope.newPort(dpid, number);
+ IPortObject portObj2 = ope.newPort(dpid2, number2);
+ swObj.addPort(portObj);
+ swObj2.addPort(portObj2);
+ IDeviceObject devObj = ope.newDevice();
+ portObj.setDevice(devObj);
+ portObj2.setDevice(devObj);
+
+ HashMap<String, ISwitchObject> switchObjectList = new HashMap<String, ISwitchObject>();
+ for(ISwitchObject sw : devObj.getSwitch())
+ {
+ switchObjectList.put(sw.getDPID(), sw);
+ }
+ assertTrue(switchObjectList.containsValue(swObj));
+ assertTrue(switchObjectList.containsValue(swObj2));
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
new file mode 100644
index 0000000..06d8522
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
@@ -0,0 +1,444 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsIFlowEntryTest {
+
+ //The test network is ./titan/schema/test-network.xml
+
+ protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ private GraphDBConnection conn = null;
+ private GraphDBOperation ope = null;
+ private TitanGraph titanGraph = null;
+ private IFlowEntry flowEntry = null;
+
+ @Before
+ public void setUp() throws Exception {
+ conf = "/dummy/path/to/db";
+
+ // Make mock cassandra DB
+ // Replace TitanFactory.open() to return mock DB
+ TestDatabaseManager.deleteTestDatabase();
+ titanGraph = TestDatabaseManager.getTestDatabase();
+ //TestDatabaseManager.populateTestData(titanGraph);
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
+
+ conn = GraphDBConnection.getInstance(conf);
+ ope = new GraphDBOperation(conn);
+
+ flowEntry = ope.newFlowEntry();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get FlowEntryId.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set FlowEntryId.
+ * 2. Should get FlowEntryId.
+ */
+ @Test
+ public void testSetGetFlowEntryId() {
+ String flowEntryId = "xx";
+ flowEntry.setFlowEntryId(flowEntryId);
+ assertEquals(flowEntry.getFlowEntryId(), flowEntryId);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get SwitchDpid.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set SwitchDpid.
+ * 2. Should get SwitchDpid.
+ */
+ @Test
+ public void testSetGetSwitchDpid() {
+ String switchDpid = "00:00:00:00:00:11";
+ flowEntry.setSwitchDpid(switchDpid);
+ assertEquals(flowEntry.getSwitchDpid(), switchDpid);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get UserState.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set UserState.
+ * 2. Should get UserState.
+ */
+ @Test
+ public void testSetGetUserState() {
+ String userStete = "good";
+ flowEntry.setUserState(userStete);
+ assertEquals(flowEntry.getUserState(), userStete);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get SwitchState.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set SwitchState.
+ * 2. Should get SwitchState.
+ */
+ @Test
+ public void testSetGetSwitchState() {
+ String switchStete = "ACTIVE";
+ flowEntry.setSwitchState(switchStete);
+ assertEquals(flowEntry.getSwitchState(), switchStete);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get ErrorStateType.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set ErrorStateType.
+ * 2. Should get ErrorStateType.
+ */
+ @Test
+ public void testSetGetErrorStateType() {
+ String errorSteteType = "error";
+ flowEntry.setErrorStateType(errorSteteType);
+ assertEquals(flowEntry.getErrorStateType(), errorSteteType);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get ErrorStateCode.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set ErrorStateCode.
+ * 2. Should get ErrorStateCode.
+ */
+ @Test
+ public void testSetGetErrorStateCode() {
+ String errorSteteCode = "error";
+ flowEntry.setErrorStateCode(errorSteteCode);
+ assertEquals(flowEntry.getErrorStateCode(), errorSteteCode);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchInPort.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchInPort.
+ * 2. Should get MatchInPort.
+ */
+ @Test
+ public void testSetGetMatchInPort() {
+ Short inPort = 1;
+ flowEntry.setMatchInPort(inPort);
+ assertEquals(flowEntry.getMatchInPort(), inPort);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchSrcMac.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchSrcMac.
+ * 2. Should get MatchSrcMac.
+ */
+ @Test
+ public void testSetGetMatchSrcMac() {
+ String matchSrcMac = "00:00:00:00:00:11";
+ flowEntry.setMatchSrcMac(matchSrcMac);
+ assertEquals(flowEntry.getMatchSrcMac(), matchSrcMac);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchDstMac.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchDstMac.
+ * 2. Should get MatchDstMac.
+ */
+ @Test
+ public void testSetGetMatchDstMac() {
+ String matchDstMac = "00:00:00:00:00:11";
+ flowEntry.setMatchDstMac(matchDstMac);
+ assertEquals(flowEntry.getMatchDstMac(), matchDstMac);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchEthernetFrameType.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchEthernetFrameType.
+ * 2. Should get MatchEthernetFrameType.
+ */
+ @Test
+ public void testSetGetMatchEthernetFrameType() {
+ Short matchEthernetFrameType = 1;
+ flowEntry.setMatchEthernetFrameType(matchEthernetFrameType);
+ assertEquals(flowEntry.getMatchEthernetFrameType(), matchEthernetFrameType);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchVlanId.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchVlanId.
+ * 2. Should get MatchVlanId.
+ */
+ @Test
+ public void testSetGetMatchVlanId() {
+ Short matchVlanId = 10;
+ flowEntry.setMatchVlanId(matchVlanId);
+ assertEquals(flowEntry.getMatchVlanId(), matchVlanId);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchVlanPriority.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchVlanPriority.
+ * 2. Should get MatchVlanPriority.
+ */
+ @Test
+ public void testSetGetMatchVlanPriority() {
+ Byte matchVlanPriority = 10;
+ flowEntry.setMatchVlanPriority(matchVlanPriority);
+ assertEquals(flowEntry.getMatchVlanPriority(), matchVlanPriority);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get SrcIPv4Net.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set SrcIPv4Net.
+ * 2. Should get SrcIPv4Net.
+ */
+ @Test
+ public void testSetGetMatchSrcIPv4Net() {
+ String srcIPv4Net = "192.168.0.1";
+ flowEntry.setMatchSrcIPv4Net(srcIPv4Net);
+ assertEquals(flowEntry.getMatchSrcIPv4Net(), srcIPv4Net);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchDstIPv4Net.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchDstIPv4Net.
+ * 2. Should get MatchDstIPv4Net.
+ */
+ @Test
+ public void testSetGetMatchDstIPv4Net() {
+ String dstIPv4Net = "192.168.0.1";
+ flowEntry.setMatchDstIPv4Net(dstIPv4Net);
+ assertEquals(flowEntry.getMatchDstIPv4Net(), dstIPv4Net);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchIpProto.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchIpProto.
+ * 2. Should get MatchIpProto.
+ */
+ @Test
+ public void testSetGetMatchIpProto() {
+ Byte matchIpProto = 20;
+ flowEntry.setMatchIpProto(matchIpProto);
+ assertEquals(flowEntry.getMatchIpProto(), matchIpProto);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchIpToS.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchIpToS.
+ * 2. Should get MatchIpToS.
+ */
+ @Test
+ public void testSetGetMatchIpToS() {
+ Byte matchIpToS = 20;
+ flowEntry.setMatchIpToS(matchIpToS);
+ assertEquals(flowEntry.getMatchIpToS(), matchIpToS);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchSrcTcpUdpPort.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchSrcTcpUdpPort.
+ * 2. Should get MatchSrcTcpUdpPort.
+ */
+ @Test
+ public void testSetGetMatchSrcTcpUdpPort() {
+ Short srcTcpUdpPort = (short)65535;
+ flowEntry.setMatchSrcTcpUdpPort(srcTcpUdpPort);
+ assertEquals(flowEntry.getMatchSrcTcpUdpPort(), srcTcpUdpPort);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchDstTcpUdpPort.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchDstTcpUdpPort.
+ * 2. Should get MatchDstTcpUdpPort.
+ */
+ @Test
+ public void testSetGetMatchDstTcpUdpPort() {
+ Short dstTcpUdpPort = (short)65535;
+ flowEntry.setMatchDstTcpUdpPort(dstTcpUdpPort);
+ assertEquals(flowEntry.getMatchDstTcpUdpPort(), dstTcpUdpPort);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get ActionOutputPort.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set ActionOutputPort.
+ * 2. Should get ActionOutputPort.
+ */
+ @Test
+ public void testSetGetActionOutputPort() {
+ Short actionOutputPort = 1;
+ flowEntry.setActionOutputPort(actionOutputPort);
+ assertEquals(flowEntry.getActionOutputPort(), actionOutputPort);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get FlowPath.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set FlowPath.
+ * 2. Should get FlowPath.
+ */
+ @Test
+ public void testSetGetFlowPath() {
+ IFlowPath fp = ope.newFlowPath();
+ String flowId = "xx";
+ fp.setFlowId(flowId);
+ flowEntry.setFlow(fp);
+ IFlowPath fp2 = flowEntry.getFlow();
+ assertEquals(fp2.getFlowId(), flowId);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get Switch.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set Switch.
+ * 2. Should get Switch.
+ */
+ @Test
+ public void testSetGetSwitch() {
+ String dpid = "00:00:00:00:00:22";
+ ISwitchObject sw1 = ope.newSwitch(dpid);
+ flowEntry.setSwitch(sw1);
+ ISwitchObject sw2 = flowEntry.getSwitch();
+ assertEquals(sw2, sw1);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get InPort.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set InPort.
+ * 2. Should get InPort.
+ */
+ @Test
+ public void testSetGetInPort() {
+ String dpid = "00:00:00:00:00:22";
+ Short portNum = 4;
+ IPortObject port1 = ope.newPort(dpid, portNum);
+ flowEntry.setInPort(port1);
+ IPortObject port2 = flowEntry.getInPort();
+ assertEquals(port2, port1);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get OutPort.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set OutPort.
+ * 2. Should get OutPort.
+ */
+ @Test
+ public void testSetGetOutPort() {
+ String dpid = "00:00:00:00:00:22";
+ Short portNum = 4;
+ IPortObject port1 = ope.newPort(dpid, portNum);
+ flowEntry.setOutPort(port1);
+ IPortObject port2 = flowEntry.getOutPort();
+ assertEquals(port2, port1);
+ }
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
new file mode 100644
index 0000000..bb0dbbf
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
@@ -0,0 +1,509 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsIFlowPathTest {
+
+ //The test network is ./titan/schema/test-network.xml
+
+ protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ private GraphDBConnection conn = null;
+ private GraphDBOperation ope = null;
+ private TitanGraph titanGraph = null;
+ private IFlowPath flowPath = null;
+ private IFlowEntry flowEntry = null;
+
+ @Before
+ public void setUp() throws Exception {
+ conf = "/dummy/path/to/db";
+
+ // Make mock cassandra DB
+ // Replace TitanFactory.open() to return mock DB
+ TestDatabaseManager.deleteTestDatabase();
+ titanGraph = TestDatabaseManager.getTestDatabase();
+ //TestDatabaseManager.populateTestData(titanGraph);
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
+
+ conn = GraphDBConnection.getInstance(conf);
+ ope = new GraphDBOperation(conn);
+
+ flowPath = ope.newFlowPath();
+ flowEntry = ope.newFlowEntry();
+ flowEntry.setState("zz");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set FlowId method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the flow id.
+ * 2. Should get the flow id.
+ */
+ @Test
+ public void testSetGetFlowId() {
+ String flowId = "xx";
+ flowPath.setFlowId(flowId);
+ assertEquals(flowPath.getFlowId(), flowId);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set InstallerId method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the installer id.
+ * 2. Should get the installer id.
+ */
+ @Test
+ public void testSetGetInstallerId() {
+ String flowId = "xx";
+ String installerId = "yy";
+ flowPath.setFlowId(flowId);
+ flowPath.setInstallerId(installerId);
+ assertEquals(flowPath.getInstallerId(), installerId);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set FlowPathFlags method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the Flow Path Flags.
+ * 2. Should get the Flow Path Flags.
+ */
+ @Test
+ public void testSetGetFlowPathFlags() {
+ String flowId = "xx";
+ Long flowPathFlags = new Long(0x3);
+ flowPath.setFlowId(flowId);
+ flowPath.setFlowPathFlags(flowPathFlags);
+ assertEquals(flowPath.getFlowPathFlags(), flowPathFlags);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set SourceSwitch method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the source switch.
+ * 2. Should get the source switch.
+ */
+ @Test
+ public void testSetGetSourceSwitch() {
+ String flowId = "xx";
+ String sourceSwitch = "aa";
+ flowPath.setFlowId(flowId);
+ flowPath.setSrcSwitch(sourceSwitch);
+ assertEquals(flowPath.getSrcSwitch(), sourceSwitch);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set SourcePort method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the source port.
+ * 2. Should get the source port.
+ */
+ @Test
+ public void testSetGetSourcePort() {
+ String flowId = "xx";
+ Short sourcePort = 1;
+ flowPath.setFlowId(flowId);
+ flowPath.setSrcPort(sourcePort);
+ assertEquals(flowPath.getSrcPort(), sourcePort);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set DestSwitch method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the dest switch.
+ * 2. Should get the dest switch.
+ */
+ @Test
+ public void testSetGetDestSwitch() {
+ String flowId = "xx";
+ String destSwitch = "bb";
+ flowPath.setFlowId(flowId);
+ flowPath.setDstSwitch(destSwitch);
+ assertEquals(flowPath.getDstSwitch(), destSwitch);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set DestPort method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the source dest port.
+ * 2. Should get the source dest port.
+ */
+ @Test
+ public void testSetGetDstPort() {
+ String flowId = "xx";
+ Short dstPort = 2;
+ flowPath.setFlowId(flowId);
+ flowPath.setDstPort(dstPort);
+ assertEquals(flowPath.getDstPort(), dstPort);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set DataPathSummary method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the data path summary.
+ * 2. Should get the data path summary.
+ */
+ @Test
+ public void testSetGetDataPathSummary() {
+ String flowId = "xx";
+ String dataPathSummary = "yy";
+ flowPath.setFlowId(flowId);
+ flowPath.setInstallerId(dataPathSummary);
+ assertEquals(flowPath.getInstallerId(), dataPathSummary);
+ }
+
+ public boolean testIFlowEntry(IFlowPath fp, IFlowEntry fe)
+ {
+ ArrayList<IFlowEntry> flowEntryList = new ArrayList<IFlowEntry>();
+ for(IFlowEntry inFlowEntry : fp.getFlowEntries())
+ {
+ flowEntryList.add(inFlowEntry);
+ }
+ return flowEntryList.contains(fe);
+ }
+
+ /**
+ * Desc:
+ * Test method for addFlowEntry and getFlorEntries method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should add the FlowEntry.
+ * 2. Should get the FlowEntries. It is tested in the testIFlowEntry method.
+ */
+ @Test
+ public void testAddFlowEntryAndGetFlowEntries() {
+ String flowId = "xx";
+ flowPath.setFlowId(flowId);
+ flowPath.addFlowEntry(flowEntry);
+ IFlowEntry flowEntry2 = ope.newFlowEntry();
+ flowPath.addFlowEntry(flowEntry2);
+ assertTrue(testIFlowEntry(flowPath, flowEntry));
+ assertTrue(testIFlowEntry(flowPath, flowEntry2));
+ }
+
+ /**
+ * Desc:
+ * Test method for remove FlowEntry.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should remove FlowEntry.
+ */
+ @Test
+ public void testRemoveFlowEntry() {
+ String flowId = "xx";
+ flowPath.setFlowId(flowId);
+ flowPath.addFlowEntry(flowEntry);
+ flowPath.removeFlowEntry(flowEntry);
+ assertTrue(!testIFlowEntry(flowPath, flowEntry));
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchSrcMac
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchSrcMac.
+ * 2. Should get MatchSrcMac.
+ */
+ @Test
+ public void testSetGetMatchSrcMac() {
+ String flowId = "xx";
+ String matchSrcMac = "00:00:00:00:00:11";
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchSrcMac(matchSrcMac);
+ assertEquals(flowPath.getMatchSrcMac(), matchSrcMac);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchDstMac.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchDstMac.
+ * 2. Should get MatchDstMac.
+ */
+ @Test
+ public void testSetGetMatchDstMac() {
+ String flowId = "xx";
+ String matchDstMac = "00:00:00:00:00:11";
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchDstMac(matchDstMac);
+ assertEquals(flowPath.getMatchDstMac(), matchDstMac);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchEthernetFrameType
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchEthernetFrameType.
+ * 2. Should get MatchEthernetFrameType.
+ */
+ @Test
+ public void testSetGetMatchEthernetFrameType() {
+ String flowId = "xx";
+ Short matchEthernetFrameType = 1;
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchEthernetFrameType(matchEthernetFrameType);
+ assertEquals(flowPath.getMatchEthernetFrameType(), matchEthernetFrameType);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchVlanId
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchVlanId.
+ * 2. Should get MatchVlanId.
+ */
+ @Test
+ public void testSetGetMatchVlanId() {
+ String flowId = "xx";
+ Short matchVlanId = 10;
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchVlanId(matchVlanId);
+ assertEquals(flowPath.getMatchVlanId(), matchVlanId);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchVlanPriority
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchVlanPriority.
+ * 2. Should get MatchVlanPriority.
+ */
+ @Test
+ public void testSetGetMatchVlanPriority() {
+ String flowId = "xx";
+ Byte matchVlanPriority = 20;
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchVlanPriority(matchVlanPriority);
+ assertEquals(flowPath.getMatchVlanPriority(), matchVlanPriority);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchSrcIPv4Net.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchSrcIPv4Net.
+ * 2. Should get MatchSrcIPv4Net.
+ */
+ @Test
+ public void testSetGetMatchSrcIPv4Net() {
+ String flowId = "xx";
+ String ip = "192.168.0.1";
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchSrcIPv4Net(ip);
+ assertEquals(flowPath.getMatchSrcIPv4Net(), ip);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchDstIPv4Net.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchDstIPv4Net.
+ * 2. Should get MatchDstIPv4Net.
+ */
+ @Test
+ public void testSetGetMatchDstIPv4Net() {
+ String flowId = "xx";
+ String ip = "192.168.0.1";
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchDstIPv4Net(ip);
+ assertEquals(flowPath.getMatchDstIPv4Net(), ip);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchIpProto
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchIpProto.
+ * 2. Should get MatchIpProto.
+ */
+ @Test
+ public void testSetGetMatchIpProto() {
+ String flowId = "xx";
+ Byte matchIpProto = 20;
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchIpProto(matchIpProto);
+ assertEquals(flowPath.getMatchIpProto(), matchIpProto);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchIpToS
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchIpToS.
+ * 2. Should get MatchIpToS.
+ */
+ @Test
+ public void testSetGetMatchIpToS() {
+ String flowId = "xx";
+ Byte matchIpToS = 20;
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchIpToS(matchIpToS);
+ assertEquals(flowPath.getMatchIpToS(), matchIpToS);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchSrcTcpUdpPort.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchSrcTcpUdpPort.
+ * 2. Should get MatchSrcTcpUdpPort.
+ */
+ @Test
+ public void testSetGetMatchSrcTcpUdpPort() {
+ String flowId = "xx";
+ Short srcTcpUdpPort = (short)65535;
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchSrcTcpUdpPort(srcTcpUdpPort);
+ assertEquals(flowPath.getMatchSrcTcpUdpPort(), srcTcpUdpPort);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get MatchDstTcpUdpPort.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set MatchDstTcpUdpPort.
+ * 2. Should get MatchDstTcpUdpPort.
+ */
+ @Test
+ public void testSetGetMatchDstTcpUdpPort() {
+ String flowId = "xx";
+ Short dstTcpUdpPort = (short)65535;
+ flowPath.setFlowId(flowId);
+ flowPath.setMatchDstTcpUdpPort(dstTcpUdpPort);
+ assertEquals(flowPath.getMatchDstTcpUdpPort(), dstTcpUdpPort);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get UserState.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set UserState.
+ * 2. Should get UserState.
+ */
+ @Test
+ public void testSetGetUserState() {
+ String flowId = "xx";
+ String userStatus = "Good";
+ flowPath.setFlowId(flowId);
+ flowPath.setUserState(userStatus);
+ assertEquals(flowPath.getUserState(), userStatus);
+ }
+
+ /**
+ * Desc:
+ * Test method for get Switches.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get switches.
+ */
+ @Test
+ public void testGetSwitches() {
+ String flowId = "xx";
+ String dpid = "1";
+ flowPath.setFlowId(flowId);
+ ISwitchObject sw = ope.newSwitch(dpid);
+ flowEntry.setSwitch(sw);
+ flowPath.addFlowEntry(flowEntry);
+
+ HashMap<String, ISwitchObject> swList = new HashMap<String, ISwitchObject>();
+ for(ISwitchObject insw : flowPath.getSwitches()){
+ swList.put(sw.getDPID(), insw);
+ }
+
+ assertTrue(swList.containsKey(dpid));
+ }
+
+ //TODO Dont know how to set the state property.
+ @Test
+ public void testGetState() {
+ String status = null;
+ assertEquals(flowPath.getState(), status);
+ }
+
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java
new file mode 100644
index 0000000..2ddab3d
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java
@@ -0,0 +1,359 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import net.onrc.onos.ofcontroller.flowmanager.FlowManager;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFPhysicalPort.OFPortState;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsIPortObjectTest {
+
+ //The test network is ./titan/schema/test-network.xml
+
+ protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ private GraphDBConnection conn = null;
+ private GraphDBOperation ope = null;
+ private TitanGraph titanGraph = null;
+
+ private ISwitchObject swObj;
+ private IPortObject portObj;
+ private IPortObject portObj2;
+ String dpid;
+ Short number;
+ Short number2;
+
+ private ISwitchObject swObjParty;
+ private IPortObject portObjParty1;
+ private IPortObject portObjParty2;
+ String dpidParty;
+ Short numberParty1;
+ Short numberParty2;
+
+
+ @Before
+ public void setUp() throws Exception {
+ conf = "/dummy/path/to/db";
+
+ // Make mock cassandra DB
+ // Replace TitanFactory.open() to return mock DB
+ TestDatabaseManager.deleteTestDatabase();
+ titanGraph = TestDatabaseManager.getTestDatabase();
+ //TestDatabaseManager.populateTestData(titanGraph);
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
+
+ conn = GraphDBConnection.getInstance(conf);
+ ope = new GraphDBOperation(conn);
+
+ dpid = "00:00:00:00:00:00:0a:07";
+ number = 1;
+ number2 = 2;
+ swObj = ope.newSwitch(dpid);
+ portObj = ope.newPort(dpid, number);
+ portObj2 = ope.newPort(dpid, number2);
+
+ swObj.addPort(portObj);
+ swObj.addPort(portObj2);
+
+ dpidParty = "00:00:00:00:00:00:0a:08";
+ numberParty1 = 1;
+ numberParty2 = 2;
+ swObjParty = ope.newSwitch(dpidParty);
+ portObjParty1 = ope.newPort(dpidParty, numberParty1);
+ portObjParty2 = ope.newPort(dpidParty, numberParty2);
+ swObjParty.addPort(portObjParty1);
+ swObjParty.addPort(portObjParty2);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get port number property.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the port number.
+ * 2. Should get the port number.
+ */
+ @Test
+ public void testSetGetNumber() {
+ assertEquals(portObj.getNumber(), number);
+ Short testedNumber = 4;
+ portObj.setNumber(testedNumber);
+ assertEquals(portObj.getNumber(), testedNumber);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get port id property.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the port id.
+ * 2. Should get the port id.
+ */
+ @Test
+ public void testSetGetPortId() {
+ String portId = "test1";
+ portObj.setPortId(portId);
+ assertEquals(portObj.getPortId(), portId);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and get port desc property.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the port desc.
+ * 2. Should get the port desc.
+ */
+ @Test
+ public void testSetGetDesc() {
+ String testedDesc = "port 4 at ATL Switch";
+ portObj.setDesc(testedDesc);
+ assertEquals(portObj.getDesc(), testedDesc);
+ }
+
+
+ /**
+ * Desc:
+ * Test method for set and get port status property.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the port status.
+ * 2. Should get the port status.
+ */
+ @Test
+ public void testSetGetPortState() {
+ Integer portState = OFPortState.OFPPS_STP_FORWARD.getValue();
+ portObj.setPortState(portState);
+ assertEquals(portObj.getPortState(), portState);
+ }
+
+ /**
+ * Desc:
+ * Test method for get switch object.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get the switch status.
+ */
+ @Test
+ public void testGetSwitch() {
+ ISwitchObject sw = portObj.getSwitch();
+ assertEquals(sw.getDPID(), dpid);
+ }
+
+ private boolean checkIDeviceObject(IPortObject IportObj, String mac)
+ {
+ HashMap<String, IDeviceObject> devList = new HashMap<String, IDeviceObject>();
+ for(IDeviceObject IdevObj : IportObj.getDevices())
+ {
+ devList.put(IdevObj.getMACAddress(), IdevObj);
+ }
+ return devList.containsKey(mac);
+ }
+
+ /**
+ * Desc:
+ * Test method for set and remove device object.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the device object.
+ * 2. SHould remove the device object.
+ */
+ @Test
+ public void testSetAndRemoveDevice() {
+ IDeviceObject devObj = ope.newDevice();
+ String devMac = "00:00:00:00:00:11";
+ devObj.setMACAddress(devMac);
+
+ boolean b = checkIDeviceObject(portObj, devMac);
+ assertTrue(!b);
+ portObj.setDevice(devObj);
+ boolean b2 = checkIDeviceObject(portObj, devMac);
+ assertTrue(b2);
+
+ portObj.removeDevice(devObj);
+ boolean b3 = checkIDeviceObject(portObj, devMac);
+ assertTrue(!b3);
+
+ }
+
+ /**
+ * Desc:
+ * Test method for get devices object.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get the device objects.
+ */
+ @Test
+ public void testGetDevices() {
+ IDeviceObject devObj = ope.newDevice();
+ String devMac = "58:55:ca:c4:1b:a0";
+ devObj.setMACAddress(devMac);
+
+ portObj.setDevice(devObj);
+ boolean b = checkIDeviceObject(portObj, devMac);
+ assertTrue(b);
+ }
+
+ /**
+ * Desc:
+ * Test method for set, get and remove linked port.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the linked objects.
+ * 2. Should get the linked objects.
+ * 3. SHould remove the liked objects.
+ */
+ @Test
+ public void testSetGetRemoveLinkedPorts() {
+ String dpidParty = "00:00:00:00:00:00:00:08";
+ ISwitchObject swParty = ope.newSwitch(dpidParty);
+ Short poShort = 1;
+ IPortObject poParty = ope.newPort(dpidParty, poShort);
+ swParty.addPort(poParty);
+
+ portObj.setLinkPort(poParty);
+
+ ArrayList<IPortObject> iPortList = new ArrayList<IPortObject>();
+ for(IPortObject port : portObj.getLinkedPorts()) {
+ iPortList.add(port);
+ }
+ assertTrue(iPortList.contains(poParty));
+
+ portObj.removeLink(poParty);
+
+ ArrayList<IPortObject> iPortList2 = new ArrayList<IPortObject>();
+ for(IPortObject port : portObj.getLinkedPorts()) {
+ iPortList2.add(port);
+ }
+
+ assertTrue(!iPortList2.contains(poParty));
+ }
+
+ /**
+ * Desc:
+ * Test method for get inbound flowEntry
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get the inbound flowEntry.
+ */
+ @Test
+ public void testGetInFlowEntries() {
+
+ portObj.setLinkPort(portObj2);
+
+ IFlowPath flowPathObj = ope.newFlowPath();
+
+ String flowEId = "1";
+ IFlowEntry flowEntryObj = ope.newFlowEntry();
+ flowEntryObj.setFlowEntryId(flowEId);
+ flowEntryObj.setInPort(portObj);
+ flowEntryObj.setOutPort(portObj2);
+ flowEntryObj.setSwitch(swObj);
+ flowEntryObj.setFlow(flowPathObj);
+
+ String flowEId2 = "2";
+ IFlowEntry flowEntryObj2 = ope.newFlowEntry();
+ flowEntryObj2.setFlowEntryId(flowEId2);
+ flowEntryObj2.setInPort(portObjParty1);
+ flowEntryObj2.setOutPort(portObjParty2);
+ flowEntryObj.setSwitch(swObjParty);
+ flowEntryObj2.setFlow(flowPathObj);
+
+ HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
+ for(IFlowEntry flowEnt : portObj.getInFlowEntries())
+ {
+ flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
+ }
+
+ assertTrue(flowEntryList.containsValue(flowEntryObj));
+
+ }
+
+ /**
+ * Desc:
+ * Test method for get outbound flowEntry
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get the outbound flowEntry.
+ */
+ @Test
+ public void testGetOutFlowEntries() {
+
+ portObj.setLinkPort(portObj2);
+
+ IFlowPath flowPathObj = ope.newFlowPath();
+
+ String flowEId = "1";
+ IFlowEntry flowEntryObj = ope.newFlowEntry();
+ flowEntryObj.setFlowEntryId(flowEId);
+ flowEntryObj.setInPort(portObj);
+ flowEntryObj.setOutPort(portObj2);
+ flowEntryObj.setSwitch(swObj);
+ flowEntryObj.setFlow(flowPathObj);
+
+ String flowEId2 = "2";
+ IFlowEntry flowEntryObj2 = ope.newFlowEntry();
+ flowEntryObj2.setFlowEntryId(flowEId2);
+ flowEntryObj2.setInPort(portObjParty1);
+ flowEntryObj2.setOutPort(portObjParty2);
+ flowEntryObj.setSwitch(swObjParty);
+ flowEntryObj2.setFlow(flowPathObj);
+
+ HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
+ for(IFlowEntry flowEnt : portObj2.getOutFlowEntries())
+ {
+ flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
+ }
+
+ assertTrue(flowEntryList.containsValue(flowEntryObj));
+
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java
new file mode 100644
index 0000000..c4dca4b
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java
@@ -0,0 +1,285 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsISwitchObjectTest {
+
+ //The test network is ./titan/schema/test-network.xml
+
+ protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ private GraphDBConnection conn = null;
+ private GraphDBOperation ope = null;
+ private TitanGraph titanGraph = null;
+
+ @Before
+ public void setUp() throws Exception {
+ conf = "/dummy/path/to/db";
+
+ // Make mock cassandra DB
+ // Replace TitanFactory.open() to return mock DB
+ TestDatabaseManager.deleteTestDatabase();
+ titanGraph = TestDatabaseManager.getTestDatabase();
+ //TestDatabaseManager.populateTestData(titanGraph);
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
+
+ conn = GraphDBConnection.getInstance(conf);
+ ope = new GraphDBOperation(conn);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set state method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the status of the switch.
+ * 2. Should get the status of the switch.
+ */
+ @Test
+ public void testSetGetState() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String state = "ACTIVE";
+ ISwitchObject swObj = ope.newSwitch(dpid);
+ swObj.setState(state);
+ assertEquals(swObj.getState(), state);
+ }
+
+ /**
+ * Desc:
+ * Test method for get and set Type method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the Type of the switch.
+ * 2. Should get the Type of the switch.
+ */
+ @Test
+ public void testSetGetType() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String type = "Switch";
+ ISwitchObject swObj = ope.newSwitch(dpid);
+ swObj.setType("Switch");
+ assertEquals(swObj.getType(), type);
+ }
+
+ /**
+ * Desc:
+ * Test method for getDPID method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get the dpid of the switch.
+ */
+ @Test
+ public void testGetDPID() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ ISwitchObject swObj = ope.newSwitch(dpid);
+
+ assertEquals(swObj.getDPID(), dpid);
+ }
+
+ /**
+ * Desc:
+ * Test method for setDPID method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should set the dpid of the switch.
+ */
+ @Test
+ public void testSetDPID() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String dpid2 = "00:00:00:00:00:00:0a:08";
+ ISwitchObject obj = ope.newSwitch(dpid);
+ assertEquals(obj.getDPID(), dpid);
+
+ obj.setDPID(dpid2);
+ assertEquals(obj.getDPID(), dpid2);
+ }
+
+ /**
+ * Desc:
+ * Test method for getPorts method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get all of ports taken by the switch.
+ */
+ @Test
+ public void testGetPorts() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ Short portNumber = 1;
+ int testSwitchPortNumber = 1;
+ ISwitchObject swObj = ope.newSwitch(dpid);
+ IPortObject portObj = ope.newPort(dpid, portNumber);
+
+ swObj.addPort(portObj);
+ int i = 0;
+ for(IPortObject port : swObj.getPorts()){
+ i++;
+ }
+ assertEquals(testSwitchPortNumber, 1);
+ }
+
+ /**
+ * Desc:
+ * Test method for add and getPort method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should add the port.
+ * 1. Should get the port.
+ */
+ @Test
+ public void testGetPort() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ Short portNumber = 1;
+ ISwitchObject swObj = ope.newSwitch(dpid);
+ IPortObject portObj = ope.newPort(dpid, portNumber);
+
+ swObj.addPort(portObj);
+ IPortObject portObj2 = swObj.getPort(portNumber);
+ assertEquals(portObj, portObj2);
+ }
+
+ /**
+ * Desc:
+ * Test method for add and removePort method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should add a port to the switch.
+ * 1. Should remove a port from the switch.
+ */
+ @Test
+ public void testAddRemovePorts() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ Short portNum = 1;
+ ISwitchObject swObj = ope.newSwitch(dpid);
+ IPortObject portObj = ope.newPort(dpid, portNum);
+ swObj.addPort(portObj);
+
+ IPortObject portObj2 = swObj.getPort(portNum);
+ assertEquals(portObj2, portObj);
+ swObj.removePort(portObj);
+ assertNull(swObj.getPort(portNum));
+ }
+
+ /**
+ * Desc:
+ * Test method for getDevices method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get all devices attached to the switch.
+ */
+ @Test
+ public void testGetDevices() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ Short portNum = 1;
+ String devMac = "00:00:00:00:00:11";
+ int numOfDev = 1;
+
+ ISwitchObject swObj = ope.newSwitch(dpid);
+ IPortObject portObj = ope.newPort(dpid, portNum);
+ IDeviceObject devObj = ope.newDevice();
+ devObj.setMACAddress(devMac);
+ swObj.addPort(portObj);
+ portObj.setDevice(devObj);
+
+ int i = 0;
+ for(IDeviceObject dev : swObj.getDevices()){
+ i++;
+ }
+ assertEquals(i, numOfDev);
+ }
+
+ /**
+ * Desc:
+ * Test method for getFlowEntries method.
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Should get all flowEntries attached to the switch.
+ */
+ @Test
+ public void testGetFlowEntries() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ Short number = 1;
+ Short number2 = 2;
+ Short number3 = 3;
+ ISwitchObject swObj = ope.newSwitch(dpid);
+ IPortObject portObj = ope.newPort(dpid, number);
+ IPortObject portObj2 = ope.newPort(dpid, number2);
+ IPortObject portObj3 = ope.newPort(dpid, number3);
+
+ swObj.addPort(portObj);
+ swObj.addPort(portObj2);
+ swObj.addPort(portObj3);
+
+ IFlowPath flowPathObj = ope.newFlowPath();
+
+ String flowEId = "1";
+ IFlowEntry flowEntryObj = ope.newFlowEntry();
+ flowEntryObj.setFlowEntryId(flowEId);
+ flowEntryObj.setInPort(portObj);
+ flowEntryObj.setOutPort(portObj2);
+ flowEntryObj.setSwitch(swObj);
+ flowEntryObj.setFlow(flowPathObj);
+
+ String flowEId2 = "2";
+ IFlowEntry flowEntryObj2 = ope.newFlowEntry();
+ flowEntryObj2.setFlowEntryId(flowEId2);
+ flowEntryObj2.setInPort(portObj);
+ flowEntryObj2.setOutPort(portObj3);
+ flowEntryObj2.setSwitch(swObj);
+ flowEntryObj2.setFlow(flowPathObj);
+
+ HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
+ for(IFlowEntry flowEnt : swObj.getFlowEntries())
+ {
+ flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
+ }
+
+ assertTrue(flowEntryList.containsValue(flowEntryObj));
+ assertTrue(flowEntryList.containsValue(flowEntryObj2));
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
new file mode 100644
index 0000000..9b1c4d6
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
@@ -0,0 +1,802 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.ILinkStorage;
+import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+
+import org.easymock.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.util.HexString;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Unit test for {@link LinkStorageImpl}.
+ * @author Naoki Shiota
+ *
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
+public class LinkStorageImplTest {
+ protected static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
+
+ private static ILinkStorage linkStorage;
+
+ // Mock GraphDBConnection (do nothing)
+ private static GraphDBConnection conn;
+
+ // Mock GraphDBOperation (mocks port-related methods only)
+ private static GraphDBOperation ope;
+
+ // Uncommitted actions executed in LinkStorageImpl
+ private static ArrayList<LinkEvent> actions;
+
+ // Dictionary of mock IPortObject to information of port
+ // -> Used to refer DPID from IPortObject
+ private static Map<IPortObject,PortInfo> mockToPortInfoMap;
+
+
+ // Links existing in virtual graph
+ private List<Link> links;
+
+ //================ Utility classes for logging actions in LinkStorageImpl ===========
+ private enum LinkEventType {
+ ADD, DELETE
+ }
+
+ private class LinkEvent {
+ private Long src_dpid = null;
+ private Long dst_dpid = null;
+ private Short src_port = null;
+ private Short dst_port = null;
+
+ public LinkEventType type;
+
+ public LinkEvent(Link link, LinkEventType type) {
+ this.src_dpid = link.getSrc();
+ this.src_port = link.getSrcPort();
+ this.dst_dpid = link.getDst();
+ this.dst_port = link.getDstPort();
+
+ this.type = type;
+ }
+
+ public Long getSrcDpid() { return src_dpid; }
+ public Short getSrcPort() { return src_port; }
+ public Long getDstDpid() { return dst_dpid; }
+ public Short getDstPort() { return dst_port; }
+ public LinkEventType getType() { return type; }
+ }
+
+ private class PortInfo {
+ public Long dpid = null;
+ public Short port = null;
+
+ public PortInfo(Long dpid, Short port) { this.dpid = dpid; this.port = port; }
+ }
+
+ /**
+ * Setup code called before each tests.
+ * Read test graph data and replace DB access by test graph data.
+ * @throws Exception
+ */
+ @Before
+ public void setUp() throws Exception{
+ // Create mock GraphDBConnection (replace Singleton object to mock one)
+ PowerMock.mockStatic(GraphDBConnection.class);
+ PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
+ conn = PowerMock.createMock(GraphDBConnection.class);
+ EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
+ PowerMock.replay(GraphDBConnection.class);
+
+ // Create mock GraphDBOperation
+ ope = createMockGraphDBOperation();
+ PowerMock.expectNew(GraphDBOperation.class, new Class<?>[] {GraphDBConnection.class}, EasyMock.anyObject(GraphDBConnection.class)).andReturn(ope).anyTimes();
+ PowerMock.replay(GraphDBOperation.class);
+
+ actions = new ArrayList<LinkEvent>();
+ mockToPortInfoMap = new HashMap<IPortObject,PortInfo>();
+
+ linkStorage = new LinkStorageImpl();
+ linkStorage.init("/dummy/path/to/conf");
+
+ initLinks();
+ }
+
+ /**
+ * Closing code called after each tests.
+ * @throws Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ linkStorage.close();
+ }
+
+ // TODO: remove @Ignore after UPDATE method is implemented
+ /**
+ * Test if {@link LinkStorageImpl#update(Link, LinkInfo, DM_OPERATION)} can correctly updates LinkInfo for a Link.
+ */
+ @Ignore @Test
+ public void testUpdate_UpdateSingleLink() {
+ Link linkToUpdate= createExistingLink();
+ long currentTime = System.currentTimeMillis();
+ LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
+ LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
+
+ linkStorage.update(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
+
+ doTestLinkHasStateOf(linkToUpdate, infoToVerify);
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)} can correctly creates a Link.
+ */
+ @Test
+ public void testUpdate_CreateSingleLink() {
+ Link linkToCreate = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkExist(linkToVerify);
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)}can correctly inserts a Link.
+ */
+ @Test
+ public void testUpdate_InsertSingleLink(){
+ Link linkToInsert = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
+ doTestLinkExist(linkToVerify);
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)} can correctly deletes a Link.
+ */
+ @Test
+ public void testUpdate_DeleteSingleLink(){
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ // Test deletion of existing link
+ linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
+ doTestLinkNotExist(linkToVerify);
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#update(List, DM_OPERATION)} can correctly creates multiple Links.
+ */
+ @Test
+ public void testUpdate_CreateLinks(){
+ List<Link> linksToCreate = createFeasibleLinks();
+ List<Link> linksToVerify = createFeasibleLinks();
+
+ // Test creation of new links
+ linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ for(Link l : linksToVerify) {
+ doTestLinkExist(l);
+ }
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#update(List, DM_OPERATION)} can correctly inserts multiple Links.
+ */
+ @Test
+ public void testUpdate_InsertLinks(){
+ List<Link> linksToInsert = createFeasibleLinks();
+ List<Link> linksToVerify = createFeasibleLinks();
+
+ // Test insertion of new links
+ linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
+ for(Link l : linksToVerify) {
+ doTestLinkExist(l);
+ }
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#update(List, DM_OPERATION)} can correctly deletes multiple Links.
+ */
+ @Test
+ public void testUpdate_DeleteLinks(){
+ List<Link> linksToDelete = createExistingLinks();
+ List<Link> linksToVerify = createExistingLinks();
+
+ // Test deletion of existing links
+ linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
+ for(Link l : linksToVerify) {
+ doTestLinkNotExist(l);
+ }
+ }
+
+ // TODO: remove @Ignore after UPDATE method is implemented
+ /**
+ * Test if {@link LinkStorageImpl#updateLink(Link, LinkInfo, DM_OPERATION)} can correctly updates LinkInfo for a Link.
+ */
+ @Ignore @Test
+ public void testUpdateLink_Update() {
+ Link linkToUpdate= createExistingLink();
+ long currentTime = System.currentTimeMillis();
+ LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
+ LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
+
+ linkStorage.updateLink(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
+
+ doTestLinkHasStateOf(linkToUpdate, infoToVerify);
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#updateLink(Link, LinkInfo, DM_OPERATION)} can correctly creates a Link.
+ */
+ @Test
+ public void testUpdateLink_Create() {
+ Link linkToCreate = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.updateLink(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkExist(linkToVerify);
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#updateLink(Link, LinkInfo, DM_OPERATION)} can correctly inserts a Link.
+ */
+ @Test
+ public void testUpdateLink_Insert() {
+ Link linkToInsert = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.updateLink(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
+
+ doTestLinkExist(linkToVerify);
+ }
+
+ // TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
+ /**
+ * Test if {@link LinkStorageImpl#updateLink(Link, LinkInfo, DM_OPERATION)} can correctly deletes a Link.
+ */
+ @Ignore @Test
+ public void testUpdateLink_Delete() {
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ // Test deletion of existing link
+ linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
+ doTestLinkNotExist(linkToVerify);
+
+ linkToDelete = createFeasibleLink();
+ linkToVerify = createFeasibleLink();
+
+ // Test deletion of not-existing link
+ linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
+ doTestLinkNotExist(linkToVerify);
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#getLinks(Long, short)} can correctly return Links connected to specific DPID and port.
+ */
+ @Test
+ public void testGetLinks_ByDpidPort(){
+ Link linkToVerify = createExistingLink();
+ Long dpid = linkToVerify.getSrc();
+ short port = (short)linkToVerify.getSrcPort();
+
+ List<Link> list = linkStorage.getLinks(dpid, port);
+
+ assertEquals(1, list.size());
+
+ Link l = list.get(0);
+ assertEquals(l.getSrc(), linkToVerify.getSrc());
+ assertEquals(l.getSrcPort(), linkToVerify.getSrcPort());
+ assertEquals(l.getDst(), linkToVerify.getDst());
+ assertEquals(l.getDstPort(), linkToVerify.getDstPort());
+
+ Link linkToVerifyNot = createFeasibleLink();
+
+ List<Link> list2 = linkStorage.getLinks(linkToVerifyNot.getSrc(), (short)linkToVerifyNot.getSrcPort());
+
+ assertEquals(0, list2.size());
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#getLinks(String)} can correctly return Links connected to specific MAC address.
+ */
+ @Test
+ public void testGetLinks_ByString() {
+ Link linkToVeryfy = createExistingLink();
+ String dpid = HexString.toHexString(linkToVeryfy.getSrc());
+
+ List<Link> links = linkStorage.getLinks(dpid);
+ assertTrue(links.contains(linkToVeryfy));
+
+ Link linkToVerifyNot = createFeasibleLink();
+ assertFalse(links.contains(linkToVerifyNot));
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#deleteLink(Link)} can correctly delete a Link.
+ */
+ @Test
+ public void testDeleteLink() {
+ // Deletion of existing link
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ linkStorage.deleteLink(linkToDelete);
+ doTestLinkNotExist(linkToVerify);
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#deleteLinks(List)} can correctly delete Links.
+ */
+ @Test
+ public void testDeleteLinks(){
+ List<Link> linksToDelete = createExistingLinks();
+ List<Link> linksToVerify = createExistingLinks();
+
+ linkStorage.deleteLinks(linksToDelete);
+ for(Link l : linksToVerify) {
+ doTestLinkNotExist(l);
+ }
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#getActiveLinks()} can correctly return active Links.
+ */
+ @Test
+ public void testGetActiveLinks() {
+ Link existingLink = createExistingLink();
+ Link notExistingLink = createFeasibleLink();
+
+ List<Link> links = linkStorage.getActiveLinks();
+
+ assertTrue(links.contains(existingLink));
+ assertFalse(links.contains(notExistingLink));
+ }
+
+ /**
+ * Test if {@link LinkStorageImpl#deleteLinksOnPort(Long, short)} can delete Links.
+ */
+ @Test
+ public void testDeleteLinksOnPort() {
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
+
+ doTestLinkNotExist(linkToVerify);
+ }
+
+ /**
+ * Test if specific link exists
+ * @param link
+ */
+ private void doTestLinkExist(Link link) {
+ int count = 0;
+ for(Link lt : links) {
+ if(lt.equals(link)) {
+ ++count;
+ }
+ }
+
+ assertTrue(count == 1);
+ }
+
+ /**
+ * Test if specific link doesn't exist
+ * @param link
+ */
+ private void doTestLinkNotExist(Link link) {
+ assertFalse(links.contains(link));
+ }
+
+ /**
+ * Test if titanGraph has specific Link with specific LinkInfo
+ * @param link
+ */
+ // TODO: Fix me
+ private void doTestLinkHasStateOf(Link link, LinkInfo info) {
+ }
+
+ /**
+ * Class defines a function called back when {@link IPortObject#removeLink(IPortObject)} is called.
+ * @author Naoki Shiota
+ *
+ */
+ private class RemoveLinkCallback implements IAnswer<Object> {
+ private long dpid;
+ private short port;
+ public RemoveLinkCallback(long dpid, short port) {
+ this.dpid = dpid; this.port = port;
+ }
+
+ @Override
+ public Object answer() throws Throwable {
+ IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
+ PortInfo dst = mockToPortInfoMap.get(dstPort);
+
+ Link linkToRemove = new Link(this.dpid,this.port,dst.dpid,dst.port);
+ actions.add(new LinkEvent(linkToRemove,LinkEventType.DELETE));
+
+ return null;
+ }
+ }
+
+ /**
+ * Class defines a function called back when {@link IPortObject#setLinkPort(IPortObject)} is called.
+ * @author Naoki Shiota
+ */
+ private class SetLinkPortCallback implements IAnswer<Object> {
+ private long dpid;
+ private short port;
+ public SetLinkPortCallback(long dpid, short port) {
+ this.dpid = dpid; this.port = port;
+ }
+
+ @Override
+ public Object answer() throws Throwable {
+ IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
+ PortInfo dst = mockToPortInfoMap.get(dstPort);
+
+ Link linkToAdd = new Link(this.dpid,this.port,dst.dpid,dst.port);
+ actions.add(new LinkEvent(linkToAdd,LinkEventType.ADD));
+
+ return null;
+ }
+
+ }
+
+ /**
+ * Class defines a function called back when {@link IPortObject#getSwitch()} is called.
+ * @author Naoki Shiota
+ *
+ */
+ private class GetSwitchCallback implements IAnswer<ISwitchObject> {
+ private long dpid;
+
+ public GetSwitchCallback(long dpid) {
+ this.dpid = dpid;
+ }
+
+ @Override
+ public ISwitchObject answer() throws Throwable {
+ ISwitchObject sw = createMockSwitch(dpid);
+ return sw;
+ }
+ }
+
+ /**
+ * Class defines a function called back when {@link IPortObject#getLinkedPorts()} is called.
+ * @author Naoki Shiota
+ *
+ */
+ private class GetLinkedPortsCallback implements IAnswer< Iterable<IPortObject> > {
+ private long dpid;
+ private short port;
+
+ public GetLinkedPortsCallback(long dpid, short port) {
+ this.dpid = dpid;
+ this.port = port;
+ }
+
+ @Override
+ public Iterable<IPortObject> answer() throws Throwable {
+ List<IPortObject> ports = new ArrayList<IPortObject>();
+
+ for(Link lk : links) {
+ if(lk.getSrc() == dpid && lk.getSrcPort() == port) {
+ ports.add(createMockPort(lk.getDst(), lk.getDstPort()));
+ }
+ }
+
+ return ports;
+ }
+
+ }
+
+ /**
+ * Class defines a function called back when {@link LinkStorageImplTest} is called.
+ * @author Naoki Shiota
+ *
+ */
+ private class GetPortsCallback implements IAnswer< Iterable <IPortObject> > {
+ private long dpid;
+
+ public GetPortsCallback(long dpid) {
+ this.dpid = dpid;
+ }
+
+ @Override
+ public Iterable<IPortObject> answer() throws Throwable {
+ List<IPortObject> ports = new ArrayList<IPortObject>();
+
+ for(Short number : getPorts(dpid)) {
+ ports.add(createMockPort(dpid, number));
+ }
+
+ return ports;
+ }
+ }
+
+ // ------------------------Creation of Mock-----------------------------
+ /**
+ * Create a mock {@link GraphDBOperation} which hooks port-related methods.
+ * @return EasyMock-wrapped GraphDBOperation object.
+ */
+ @SuppressWarnings("serial")
+ private GraphDBOperation createMockGraphDBOperation() {
+ GraphDBOperation mockDBOpe = EasyMock.createNiceMock(GraphDBOperation.class);
+
+ // Mock searchPort() method to create new mock IPortObject.
+ EasyMock.expect(mockDBOpe.searchPort((String)EasyMock.anyObject(), EasyMock.anyShort())).
+ andAnswer(new IAnswer<IPortObject>() {
+ @Override
+ public IPortObject answer() throws Throwable {
+ long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
+ short port = (Short) EasyMock.getCurrentArguments()[1];
+ IPortObject ret = createMockPort(dpid,port);
+
+ return ret;
+ }
+ }).anyTimes();
+
+ // Mock searchSwitch() method to create new mock ISwitchObject.
+ EasyMock.expect(mockDBOpe.searchSwitch((String)EasyMock.anyObject())).
+ andAnswer(new IAnswer<ISwitchObject>() {
+ @Override
+ public ISwitchObject answer() throws Throwable {
+ long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
+ ISwitchObject ret = createMockSwitch(dpid);
+
+ return ret;
+ }
+ }).anyTimes();
+
+ // Mock getActiveSwitches() method to create list of mock ISwitchObject.
+ EasyMock.expect(mockDBOpe.getActiveSwitches()).andReturn(new ArrayList<ISwitchObject> () {{
+ for(Long dpid : getDpids()) {
+ add(createMockSwitch(dpid));
+ }
+ }}).anyTimes();
+
+ // Mock commit() method to commit change of link information
+ mockDBOpe.commit();
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ for(LinkEvent action : actions) {
+ if(action.getType().equals(LinkEventType.ADD)) {
+ Link linkToAdd = new Link(
+ action.getSrcDpid(),
+ action.getSrcPort(),
+ action.getDstDpid(),
+ action.getDstPort());
+ links.add(linkToAdd);
+ } else if(action.getType().equals(LinkEventType.DELETE)) {
+ Link linkToRemove = new Link(
+ action.getSrcDpid(),
+ action.getSrcPort(),
+ action.getDstDpid(),
+ action.getDstPort());
+ links.remove(linkToRemove);
+ } else {
+ log.error("mock commit(): unexpected action {}", new Object[]{action.getType()});
+ }
+ }
+ actions.clear();
+ return null;
+ }
+ }).atLeastOnce();
+
+ EasyMock.replay(mockDBOpe);
+ return mockDBOpe;
+ }
+
+ /**
+ * Create a mock {@link IPortObject} using given DPID and port number.
+ * {@link IPortObject} can't store DPID, so DPID is stored to mockToPortInfoMap for later use.
+ * Duplication is not checked.
+ * @param dpid DPID of a port
+ * @param number Port Number
+ * @return EasyMock-wrapped IPortObject
+ */
+ private IPortObject createMockPort(long dpid, short number) {
+ IPortObject mockPort = EasyMock.createNiceMock(IPortObject.class);
+
+ EasyMock.expect(mockPort.getNumber()).andReturn(number);
+
+ // Mock removeLink() method
+ mockPort.removeLink((IPortObject) EasyMock.anyObject());
+ EasyMock.expectLastCall().andAnswer(new RemoveLinkCallback(dpid, number)).anyTimes();
+
+ // Mock setLinkPort() method
+ mockPort.setLinkPort((IPortObject) EasyMock.anyObject());
+ EasyMock.expectLastCall().andAnswer(new SetLinkPortCallback(dpid, number)).anyTimes();
+
+ // Mock getLinkPorts() method
+ EasyMock.expect(mockPort.getLinkedPorts()).andAnswer(new GetLinkedPortsCallback(dpid, number)).anyTimes();
+
+ // Mock getSwitch() method
+ EasyMock.expect(mockPort.getSwitch()).andAnswer(new GetSwitchCallback(dpid)).anyTimes();
+
+ mockToPortInfoMap.put(mockPort, new PortInfo(dpid,number));
+ EasyMock.replay(mockPort);
+
+ return mockPort;
+ }
+
+ /**
+ * Create a mock {@link ISwitchObject} using given DPID number.
+ * Duplication is not checked.
+ * @param dpid DPID of a switch
+ * @return EasyMock-wrapped ISwitchObject
+ */
+ private ISwitchObject createMockSwitch(long dpid) {
+ ISwitchObject mockSw = EasyMock.createNiceMock(ISwitchObject.class);
+
+ EasyMock.expect(mockSw.getPorts()).andAnswer(new GetPortsCallback(dpid)).anyTimes();
+ EasyMock.expect(mockSw.getDPID()).andReturn(HexString.toHexString(dpid)).anyTimes();
+ EasyMock.expect(mockSw.getState()).andReturn("ACTIVE").anyTimes();
+
+ EasyMock.replay(mockSw);
+ return mockSw;
+ }
+
+
+ //----------------- Creation of test data -----------------------
+ // Assume a network shown below.
+ //
+ // [dpid1]--+--[port:1]----[port:1]--+--[dpid2]
+ // | |
+ // +--[port:2] [port:2]--+
+ // |
+ // +--[port:3] [port:1]--+--[dpid3]
+ // | |
+ // +--[port:4]----[port:2]--+
+ //
+ // dpid1 : 00:00:00:00:0a:01
+ // dpid2 : 00:00:00:00:0a:02
+ // dpid3 : 00:00:00:00:0a:03
+
+ /**
+ * Initialize links member to represent test topology above.
+ */
+ private void initLinks() {
+ links = new ArrayList<Link>();
+
+ links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
+ }
+
+ /**
+ * Returns list of port number attached to the switch specified by given DPID.
+ * @param dpid DPID of the switch
+ * @return List of port number
+ */
+ @SuppressWarnings("serial")
+ private List<Short> getPorts(long dpid) {
+ List<Short> ports;
+
+ if(dpid == Long.decode("0x0000000000000a01")) {
+ ports = new ArrayList<Short>() {{
+ add((short)1);
+ add((short)2);
+ add((short)3);
+ add((short)4);
+ }};
+ } else if(dpid == Long.decode("0x0000000000000a02") || dpid == Long.decode("0x0000000000000a03")) {
+ ports = new ArrayList<Short>() {{
+ add((short)1);
+ add((short)2);
+ }};
+ } else {
+ ports = new ArrayList<Short>();
+ }
+
+ return ports;
+ }
+
+ /**
+ * Returns list of DPIDs in test topology.
+ * @return List of DPIDs
+ */
+ @SuppressWarnings("serial")
+ private List<Long> getDpids() {
+ List<Long> dpids = new ArrayList<Long>() {{
+ add(Long.decode("0x0000000000000a01"));
+ add(Long.decode("0x0000000000000a02"));
+ add(Long.decode("0x0000000000000a03"));
+ }};
+
+ return dpids;
+ }
+
+ /**
+ * Returns new {@link Link} object of an existing link
+ * @return new Link object
+ */
+ private Link createExistingLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
+ }
+
+ /**
+ * Returns new {@link Link} object of a not-existing but feasible link
+ * @return new Link object
+ */
+ private Link createFeasibleLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
+ }
+
+ // make NO sense while test-network data doesn't define physical network (i.e. any link is feasible)
+ @SuppressWarnings("unused")
+ private Link createInfeasibleLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a03"), 3);
+ }
+
+ /**
+ * Returns list of existing {@link Link} objects
+ * @return ArrayList of new Link objects
+ */
+ private List<Link> createExistingLinks() {
+ List<Link> links = new ArrayList<Link>();
+ links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
+ return links;
+ }
+
+ /**
+ * Returns list of {@link Link} objects that are all not-existing but feasible
+ * @return ArrayList of new Link objects
+ */
+ private List<Link> createFeasibleLinks() {
+ List<Link> links = new ArrayList<Link>();
+ links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a02"), 2));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1));
+ return links;
+ }
+
+ /**
+ * Returns new {@link LinkInfo} object with convenient values.
+ * @return LinkInfo object
+ */
+ private LinkInfo createFeasibleLinkInfo(long time) {
+ long time_first = time;
+ long time_last_lldp = time + 50;
+ long time_last_bddp = time + 100;
+ int state_src = OFPhysicalPort.OFPortState.OFPPS_STP_FORWARD.getValue();
+ int state_dst = OFPhysicalPort.OFPortState.OFPPS_STP_LISTEN.getValue();
+
+ return new LinkInfo(time_first,
+ time_last_lldp,
+ time_last_bddp,
+ state_src,
+ state_dst);
+ }
+ //---------------------------------------------------------------
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
new file mode 100644
index 0000000..4956136
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
@@ -0,0 +1,767 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import static org.easymock.EasyMock.*;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.protocol.OFPhysicalPort.OFPortState;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.slf4j.LoggerFactory;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class SwitchStorageImplTest {
+
+ protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ private GraphDBConnection mockConn = null;
+ private GraphDBOperation mockOpe = null;
+ private GraphDBOperation realOpe = null;
+ private TitanGraph titanGraph = null;
+ ISwitchStorage swSt = null;
+
+ @Before
+ public void setUp() throws Exception {
+
+ swSt = new SwitchStorageImpl();
+ conf = "/dummy/path/to/db";
+
+ // Make mock cassandra DB
+ // Replace TitanFactory.open() to return mock DB
+
+ PowerMock.mockStatic(GraphDBConnection.class);
+ mockConn = createMock(GraphDBConnection.class);
+ PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
+ EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(mockConn);
+ PowerMock.replay(GraphDBConnection.class);
+
+ PowerMock.mockStatic(GraphDBOperation.class);
+ mockOpe = PowerMock.createStrictMock(GraphDBOperation.class);
+ PowerMock.expectNew(GraphDBOperation.class, mockConn).andReturn(mockOpe);
+ PowerMock.replay(GraphDBOperation.class);
+ // Replace the conf to dummy conf
+ // String conf = "/tmp/cassandra.titan";
+
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ swSt.close();
+ swSt = null;
+
+ }
+
+ /**
+ * Desc:
+ * Test method for addSwitch method.
+ * Condition:
+ * Normal
+ * Expect:
+ * Call SwitchStorageImpl.addSwitch func with proper properties.
+ */
+ @Test
+ public void testAddSwitch() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String state = "ACTIVE";
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ }
+
+ /**
+ * Desc:
+ * Test method for addSwitch method.
+ * Condition:
+ * The switch is already existing.
+ * Expect:
+ * Call SwitchStorageImpl.addSwitch func with proper properties.
+ */
+ //@Ignore
+ @Test
+ public void testAddSwitchExisting() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String state = "ACTIVE";
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ mockISw.setState(state);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.addSwitch(dpid);
+ }
+
+ /**
+ * Desc:
+ * Test method for addSwitch method.
+ * Condition:
+ * The switch construction is fail and return null
+ * Expect:
+ * Write the status as info log.
+ */
+ @Test
+ public void testAddSwitchAbnormal() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(null);
+ mockOpe.rollback();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ }
+
+ /**
+ * Desc:
+ * Test method for addSwitch method.
+ * Condition:
+ * Throw runtimeException.
+ * Expect:
+ * The rollback method is called.
+ */
+ //@Ignore
+ @Test
+ public void testAddSwitchException() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String state = "ACTIVE";
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expectLastCall().andThrow(new RuntimeException());
+ mockOpe.rollback();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ }
+
+ /**
+ * Desc:
+ * Test method for updateSwitch method.
+ * Condition:
+ * SwitchState : INACTIVE
+ * DMOPERATION : UPDATE
+ * Expect:
+ * Should call addSwitch function and commit.
+ */
+ //@Ignore
+ @Test
+ public void testUpdateUPDATE() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ SwitchState stateINACTIVE = SwitchState.INACTIVE;
+ DM_OPERATION opUPDATE = DM_OPERATION.UPDATE;
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState("ACTIVE");
+ mockISw.setState(stateINACTIVE.toString());
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.update(dpid, stateINACTIVE, opUPDATE);
+ }
+
+ /**
+ * Desc:
+ * Test method for updateSwitch method.
+ * Condition:
+ * SwitchState : INACTIVE
+ * DMOPERATION : CREATE
+ * Expect:
+ * Should call addSwitch function and commit.
+ */
+ //@Ignore
+ @Test
+ public void testUpdateCREATE() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ SwitchState stateINACTIVE = SwitchState.INACTIVE;
+ DM_OPERATION opCREATE = DM_OPERATION.CREATE;
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState("ACTIVE");
+ mockISw.setState(stateINACTIVE.toString());
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.update(dpid, stateINACTIVE, opCREATE);
+ }
+
+ /**
+ * Desc:
+ * Test method for updateSwitch method.
+ * Condition:
+ * SwitchState : INACTIVE
+ * DMOPERATION : INSERT
+ * Expect:
+ * Should call addSwitch function and commit.
+ */
+ //@Ignore
+ @Test
+ public void testUpdateINSERT() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ SwitchState stateINACTIVE = SwitchState.INACTIVE;
+ DM_OPERATION opINSERT = DM_OPERATION.INSERT;
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState("ACTIVE");
+ mockISw.setState(stateINACTIVE.toString());
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.update(dpid, stateINACTIVE, opINSERT);
+ }
+
+ /**
+ * Desc:
+ * Test method for updateSwitch method.
+ * Condition:
+ * SwitchState : ACTIVE
+ * DMOPERATION : DELETE
+ * Expect:
+ * Should call removeSwitch function and commit.
+ */
+ //@Ignore
+ @Test
+ public void testUpdateDELETE() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ SwitchState stateACTIVE = SwitchState.ACTIVE;
+ DM_OPERATION opDELETE = DM_OPERATION.DELETE;
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(stateACTIVE.toString());
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ mockOpe.removeSwitch(mockISw);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.update(dpid, stateACTIVE, opDELETE);
+ }
+
+ /**
+ * Desc:
+ * Test method for deleteSwitch method.
+ * Condition:
+ * The switch is existing.
+ * Expect:
+ * Should call removeSwitch function and commit.
+ */
+ //@Ignore
+ @Test
+ public void testDeleteSwitch() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String state = "ACTIVE";
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ mockOpe.removeSwitch(mockISw);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.deleteSwitch(dpid);
+
+ //Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
+ //assertFalse(it.hasNext());
+ }
+
+ /**
+ * Desc:
+ * Test method for deleteSwitch method.
+ * Condition:
+ * The commit func throw exception.
+ * Expect:
+ * Should call rollback.
+ */
+ //@Ignore
+ @Test
+ public void testDeleteSwitchException() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ String state = "ACTIVE";
+ String type = "";
+
+ //Mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ mockOpe.removeSwitch(mockISw);
+ mockOpe.commit();
+ expectLastCall().andThrow(new RuntimeException());
+ mockOpe.rollback();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.deleteSwitch(dpid);
+ }
+
+ /**
+ * Desc:
+ * Test method for addPort method.
+ * Condition:
+ * port is existing.
+ * Expect:
+ * Should call addPort and commit.
+ */
+ //@Ignore
+ @Test
+ public void testAddPort() {
+ String dpid = "00:00:00:00:00:00:0a:01";
+ short portNumber = 5;
+ String state = "ACTIVE";
+ String name = "port 5 at SEA switch";
+
+ OFPhysicalPort portToAdd = new OFPhysicalPort();
+ portToAdd.setName(name);
+ portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
+ portToAdd.setPortNumber(portNumber);
+ portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
+
+ //Expectation of mock Port
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setState(state);
+ mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
+ mockIPort.setDesc(name);
+ replay(mockIPort);
+
+ //Expectation of mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ mockISw.addPort(mockIPort);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
+ expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.addPort(dpid, portToAdd);
+ }
+
+ /**
+ * Desc:
+ * Test method for addPort method.
+ * Condition:
+ * Port status is down.
+ * Expect:
+ * Should call removePort and commit.
+ */
+ //@Ignore
+ @Test
+ public void testAddPortWithPortLinkDown() {
+ String dpid = "00:00:00:00:00:00:0a:01";
+ short portNumber = 5;
+ String state = "ACTIVE";
+ String name = "port 5 at SEA switch";
+
+ OFPhysicalPort portToAdd = new OFPhysicalPort();
+ portToAdd.setName(name);
+ portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
+ portToAdd.setPortNumber(portNumber);
+ portToAdd.setState(OFPortState.OFPPS_LINK_DOWN.getValue());
+
+ //Expectation of mock Port
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setState(state);
+ mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
+ mockIPort.setDesc(name);
+ replay(mockIPort);
+
+ //Expectation of mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ mockISw.removePort(mockIPort);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
+ mockOpe.removePort(mockIPort);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.addPort(dpid, portToAdd);
+ }
+
+ /**
+ * Desc:
+ * Test method for addPort method.
+ * Condition:
+ * The switch is not existing.
+ * Expect:
+ * Nothing happens.
+ */
+ //@Ignore
+ @Test
+ public void testAddPortAbnormalNoSwitch() {
+ String dpid = "00:00:00:00:00:00:0a:01";
+ short portNumber = 5;
+ String state = "ACTIVE";
+ String name = "port 5 at SEA switch";
+
+ OFPhysicalPort portToAdd = new OFPhysicalPort();
+ portToAdd.setName(name);
+ portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
+ portToAdd.setPortNumber(portNumber);
+ portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
+
+ //Expectation of mock Port
+ IPortObject mockIPort = createStrictMock(IPortObject.class);
+ replay(mockIPort);
+
+ //Expectation of mock Switch
+ ISwitchObject mockISw = createStrictMock(ISwitchObject.class);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addPort(dpid, portToAdd);
+ }
+
+ /**
+ * Desc:
+ * Test method for addPort method.
+ * Condition:
+ * port is not existing.
+ * Expect:
+ * Should call addPort and commit.
+ */
+ //@Ignore
+ @Test
+ public void testAddPortAbnormalNoPort() {
+ String dpid = "00:00:00:00:00:00:0a:01";
+ short portNumber = 5;
+ String state = "ACTIVE";
+ String name = "port 5 at SEA switch";
+
+ OFPhysicalPort portToAdd = new OFPhysicalPort();
+ portToAdd.setName(name);
+ portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
+ portToAdd.setPortNumber(portNumber);
+ portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
+
+ //Expectation of mock Port
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setState(state);
+ mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
+ mockIPort.setDesc(name);
+ replay(mockIPort);
+
+ //Expectation of mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ mockISw.addPort(mockIPort);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
+ expect(mockOpe.newPort(dpid, portNumber)).andReturn(null);
+ mockOpe.rollback();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.addPort(dpid, portToAdd);
+ }
+
+ /**
+ * Desc:
+ * Test method for addPort method.
+ * Condition:
+ * commit throw the exception.
+ * Expect:
+ * Should call rollback.
+ */
+ //@Ignore
+ @Test
+ public void testAddPortWithException() {
+ String dpid = "00:00:00:00:00:00:0a:01";
+ short portNumber = 5;
+ String state = "ACTIVE";
+ String name = "port 5 at SEA switch";
+
+ OFPhysicalPort portToAdd = new OFPhysicalPort();
+ portToAdd.setName(name);
+ portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
+ portToAdd.setPortNumber(portNumber);
+ portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
+
+ //Expectation of mock Port
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setState(state);
+ mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
+ mockIPort.setDesc(name);
+ replay(mockIPort);
+
+ //Expectation of mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ mockISw.addPort(mockIPort);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
+ expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);
+ mockOpe.commit();
+ expectLastCall().andThrow(new RuntimeException());
+ mockOpe.rollback();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.addPort(dpid, portToAdd);
+ }
+
+ /**
+ * Desc:
+ * Test method for deletePort method.
+ * Condition:
+ * port is existing.
+ * Expect:
+ * Should call removePort and commit.
+ */
+ //@Ignore
+ @Test
+ public void testDeletePort() {
+ String dpid = "00:00:00:00:00:00:0a:01";
+ short portNumber = 5;
+ String state = "ACTIVE";
+ String name = "port 5 at SEA switch";
+
+ OFPhysicalPort portToAdd = new OFPhysicalPort();
+ portToAdd.setName(name);
+ portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
+ portToAdd.setPortNumber(portNumber);
+ portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
+
+ //Expectation of mock Port
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setState(state);
+ mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
+ mockIPort.setDesc(name);
+ replay(mockIPort);
+
+ //Expectation of mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ mockISw.addPort(mockIPort);
+ mockISw.removePort(mockIPort);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
+ expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
+ mockOpe.removePort(mockIPort);
+ mockOpe.commit();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.addPort(dpid, portToAdd);
+ swSt.deletePort(dpid, portNumber);
+ }
+
+ /**
+ * Desc:
+ * Test method for addPort method.
+ * Condition:
+ * commit throws the exception.
+ * Expect:
+ * Should call rollback.
+ */
+ //@Ignore
+ @Test
+ public void testDeletePortException() {
+ String dpid = "00:00:00:00:00:00:0a:01";
+ short portNumber = 5;
+ String state = "ACTIVE";
+ String name = "port 5 at SEA switch";
+
+ OFPhysicalPort portToAdd = new OFPhysicalPort();
+ portToAdd.setName(name);
+ portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
+ portToAdd.setPortNumber(portNumber);
+ portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
+
+ //Expectation of mock Port
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setState(state);
+ mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
+ mockIPort.setDesc(name);
+ replay(mockIPort);
+
+ //Expectation of mock Switch
+ ISwitchObject mockISw = createMock(ISwitchObject.class);
+ mockISw.setState(state);
+ mockISw.addPort(mockIPort);
+ mockISw.removePort(mockIPort);
+ replay(mockISw);
+
+ //Expectation of mock operation.
+ expect(mockOpe.searchSwitch(dpid)).andReturn(null);
+ expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
+ expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
+ expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
+ mockOpe.removePort(mockIPort);
+ expectLastCall().andThrow(new RuntimeException());
+ mockOpe.rollback();
+ mockOpe.close();
+ replay(mockOpe);
+
+ swSt.init(conf);
+ swSt.addSwitch(dpid);
+ swSt.addPort(dpid, portToAdd);
+ swSt.deletePort(dpid, portNumber);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
new file mode 100644
index 0000000..57aefd3
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
@@ -0,0 +1,334 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import static org.junit.Assert.*;
+
+import net.floodlightcontroller.core.internal.TestDatabaseManager;
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.INetMapStorage;
+import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.protocol.OFPhysicalPort.OFPortState;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.slf4j.LoggerFactory;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class SwitchStorageImplTestBB {
+
+ protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ private GraphDBConnection conn = null;
+ private GraphDBOperation ope = null;
+ private TitanGraph titanGraph = null;
+ ISwitchStorage swSt = null;
+
+ @Before
+ public void setUp() throws Exception {
+
+ swSt = new SwitchStorageImpl();
+ conf = "/dummy/path/to/db";
+
+ // Make mock cassandra DB
+ // Replace TitanFactory.open() to return mock DB
+ titanGraph = TestDatabaseManager.getTestDatabase();
+ TestDatabaseManager.populateTestData(titanGraph);
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
+
+ conn = GraphDBConnection.getInstance(conf);
+ ope = new GraphDBOperation(conn);
+
+ swSt.init(conf);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
+
+ swSt.close();
+ swSt = null;
+ }
+
+ /**
+ * Desc:
+ * Test method for addSwitch method.
+ * Condition:
+ * Normal
+ * Expect:
+ * 1. Switch should be generated.
+ * 2. The status of switch should be ACTIVE
+ */
+ //@Ignore
+ @Test
+ public void testAddSwitch() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw == null);
+ swSt.addSwitch(dpid);
+ ISwitchObject sw2 = ope.searchSwitch(dpid);
+ assertTrue(sw2 != null);
+ assertEquals(sw2.getState(), "ACTIVE");
+ }
+
+ /**
+ * Desc:
+ * Test method for addSwitch method.
+ * Condition:
+ * The existing switch status is INACTIVE.
+ * The switch is already existing.
+ * Expect:
+ * 1. After add the same switch, the status of switch should be ACTIVE
+ */
+ //@Ignore
+ @Test
+ public void testAddSwitchExisting() {
+ String dpid = "00:00:00:00:00:00:0a:06";
+
+ swSt.update(dpid, SwitchState.INACTIVE, DM_OPERATION.UPDATE);
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw != null);
+ assertEquals(sw.getState(), SwitchState.INACTIVE.toString());
+ swSt.addSwitch(dpid);
+ ISwitchObject sw2 = ope.searchSwitch(dpid);
+ assertTrue(sw2 != null);
+ assertEquals(sw2.getState(), SwitchState.ACTIVE.toString());
+ }
+
+ /**
+ * Desc:
+ * Test method for testUpdate method.
+ * Condition:
+ * The switch is not existing.
+ * The status of added switch is INACTIVE.
+ * DM_OPERATION is CREATE.
+ * Expect:
+ * 1. Switch should be created.
+ * 2. The status of switch should be INACTIVE.
+ */
+ //@Ignore
+ @Test
+ public void testUpdate() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+ SwitchState state = ISwitchStorage.SwitchState.INACTIVE;
+ DM_OPERATION dmope = INetMapStorage.DM_OPERATION.CREATE;
+
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw == null);
+ swSt.update(dpid, state, dmope);
+ ISwitchObject sw2 = ope.searchSwitch(dpid);
+ assertTrue(sw2 != null);
+ assertEquals(sw2.getState(), state.toString());
+ }
+
+ /**
+ * Desc:
+ * Test method for testUpdate method.
+ * Condition:
+ * The switch is existing.
+ * The status of added switch is ACTIVE.
+ * DM_OPERATION is DELETE.
+ * Expect:
+ * 1. Switch should be deleted.
+ */
+ //@Ignore
+ @Test
+ public void testUpdateWithDELETE() {
+ String dpid = "00:00:00:00:00:00:0a:06";
+ SwitchState state = ISwitchStorage.SwitchState.ACTIVE;
+ DM_OPERATION dmope = INetMapStorage.DM_OPERATION.DELETE;
+
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw != null);
+ swSt.update(dpid, state, dmope);
+ ISwitchObject sw2 = ope.searchSwitch(dpid);
+ assertTrue(sw2 == null);
+ }
+
+ /**
+ * Desc:
+ * Test method for delete switch method.
+ * Condition:
+ * The switch is existing.
+ * Expect:
+ * 1. Switch should be deleted.
+ */
+ //@Ignore
+ @Test
+ public void testDeleteSwitch() {
+ String dpid = "00:00:00:00:00:00:0a:06";
+
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw != null);
+ swSt.deleteSwitch(dpid);
+ ISwitchObject sw2 = ope.searchSwitch(dpid);
+ assertTrue(sw2 == null);
+ }
+
+ /**
+ * Desc:
+ * Test method for delete switch method.
+ * Condition:
+ * The switch is not existing.
+ * Expect:
+ * Nothing happens.
+ */
+ //@Ignore
+ @Test
+ public void testDeleteNonExistingSwitch() {
+ String dpid = "00:00:00:00:00:00:0a:07";
+
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw == null);
+ swSt.deleteSwitch(dpid);
+ ISwitchObject sw2 = ope.searchSwitch(dpid);
+ assertTrue(sw2 == null);
+ }
+
+ /**
+ * Desc:
+ * Test method for delete port method.
+ * Condition:
+ * The port is existing.
+ * Expect:
+ * Deleted the port.
+ */
+ //@Ignore
+ @Test
+ public void testDeletePort() {
+ String dpid = "00:00:00:00:00:00:0a:06";
+ short portNumber = 3;
+
+ IPortObject portObj1 = ope.searchPort(dpid, portNumber);
+ assertTrue(portObj1 != null);
+ swSt.deletePort(dpid, portNumber);
+ IPortObject portObj2 = ope.searchPort(dpid, portNumber);
+ assertTrue(portObj2 == null);
+ }
+
+ /**
+ * Desc:
+ * Test method for delete port method.
+ * Condition:
+ * The port is not existing.
+ * Expect:
+ * Nothing happens.
+ */
+ //@Ignore
+ @Test
+ public void testDeleteNonExistingPort() {
+ String dpid = "00:00:00:00:00:00:0a:06";
+ short portNumber = 4;
+
+ IPortObject portObj1 = ope.searchPort(dpid, portNumber);
+ assertTrue(portObj1 == null);
+ swSt.deletePort(dpid, portNumber);
+ IPortObject portObj2 = ope.searchPort(dpid, portNumber);
+ assertTrue(portObj2 == null);
+ }
+
+ /**
+ * Desc:
+ * Test method for add port method.
+ * Condition:
+ * The port is not existing.
+ * Expect:
+ * The port should be added.
+ * The desc of IPortObject is the same as the name of OFPhysicalPort.
+ */
+ //@Ignore
+ @Test
+ public void testAddPort() {
+ String dpid = "00:00:00:00:00:00:0a:06";
+ short portNumber = 4;
+ String name = "port 4 at ATL Switch";
+ int state = OFPortState.OFPPS_STP_FORWARD.getValue();
+ OFPhysicalPort port = new OFPhysicalPort();
+ port.setPortNumber(portNumber);
+ port.setName(name);
+ port.setState(state);
+
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw != null);
+ swSt.addPort(dpid, port);
+ IPortObject portObj = ope.searchPort(dpid, portNumber);
+ assertTrue(portObj != null);
+ assertEquals(portObj.getDesc(), name);
+ }
+
+ /**
+ * Desc:
+ * Test method for add method.
+ * Condition:
+ * The port is existing.
+ * Expect:
+ * Nothing happens.
+ */
+ //@Ignore
+ @Test
+ public void testAddExistingPort() {
+ String dpid = "00:00:00:00:00:00:0a:06";
+ short portNumber = 3;
+ String name = "xxx";
+ int state = OFPortState.OFPPS_STP_FORWARD.getValue();
+ OFPhysicalPort port = new OFPhysicalPort();
+ port.setPortNumber(portNumber);
+ port.setName(name);
+ port.setState(state);
+
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw != null);
+ swSt.addPort(dpid, port);
+ IPortObject portObj = ope.searchPort(dpid, portNumber);
+ assertTrue(portObj != null);
+ }
+
+ /**
+ * Desc:
+ * Test method for add method.
+ * Condition:
+ * The port status is down.
+ * Expect:
+ * Delete the port.
+ */
+ //@Ignore
+ @Test
+ public void testAddDownPort() {
+ String dpid = "00:00:00:00:00:00:0a:06";
+ short portNumber = 3;
+ String name = "port 3 at ATL Switch";
+ int state = OFPortState.OFPPS_LINK_DOWN.getValue();
+ OFPhysicalPort port = new OFPhysicalPort();
+ port.setPortNumber(portNumber);
+ port.setName(name);
+ port.setState(state);
+
+ ISwitchObject sw = ope.searchSwitch(dpid);
+ assertTrue(sw != null);
+ swSt.addPort(dpid, port);
+ IPortObject portObj = ope.searchPort(dpid, portNumber);
+ assertTrue(portObj == null);
+ }
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
new file mode 100644
index 0000000..5b0a5b1
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
@@ -0,0 +1,87 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.io.graphml.GraphMLReader;
+
+public class TestDatabaseManager {
+ private static final String testDbLocation = "/tmp/onos-testdb";
+
+ //private static final String testDbGraphML = "<?xml version=\"1.0\" ?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"> <key id=\"id\" for=\"node\" attr.name=\"id\" attr.type=\"string\"></key> <key id=\"type\" for=\"node\" attr.name=\"type\" attr.type=\"string\"></key> <key id=\"dpid\" for=\"node\" attr.name=\"dpid\" attr.type=\"string\"></key> <key id=\"desc\" for=\"node\" attr.name=\"desc\" attr.type=\"string\"></key> <key id=\"number\" for=\"node\" attr.name=\"number\" attr.type=\"int\"></key> <key id=\"dl_addr\" for=\"node\" attr.name=\"dl_addr\" attr.type=\"string\"></key> <key id=\"nw_addr\" for=\"node\" attr.name=\"nw_addr\" attr.type=\"string\"></key> <key id=\"id\" for=\"edge\" attr.name=\"id\" attr.type=\"string\"></key> <key id=\"source\" for=\"edge\" attr.name=\"source\" attr.type=\"string\"></key> <key id=\"target\" for=\"edge\" attr.name=\"target\" attr.type=\"string\"></key> <key id=\"label\" for=\"edge\" attr.name=\"label\" attr.type=\"string\"></key> <graph id=\"G\" edgedefault=\"directed\"> <node id=\"1\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:01</data> <data key=\"desc\">OpenFlow Switch at SEA</data> </node> <node id=\"2\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:02</data> <data key=\"desc\">OpenFlow Switch at LAX</data> </node> <node id=\"3\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:03</data> <data key=\"desc\">OpenFlow Switch at CHI</data> </node> <node id=\"4\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:04</data> <data key=\"desc\">OpenFlow Switch at IAH</data> </node> <node id=\"5\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:05</data> <data key=\"desc\">OpenFlow Switch at NYC</data> </node> <node id=\"6\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:06</data> <data key=\"desc\">OpenFlow Switch at ATL</data> </node> <node id=\"100\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at SEA Switch</data> </node> <node id=\"101\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at SEA Switch</data> </node> <node id=\"102\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at SEA Switch</data> </node> <node id=\"103\"> <data key=\"type\">port</data> <data key=\"number\">4</data> <data key=\"desc\">port 4 at SEA Switch</data> </node> <node id=\"104\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at LAX Switch</data> </node> <node id=\"105\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at LAX Switch</data> </node> <node id=\"106\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at LAX Switch</data> </node> <node id=\"107\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at CHI Switch</data> </node> <node id=\"108\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at CHI Switch</data> </node> <node id=\"109\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at CHI Switch</data> </node> <node id=\"110\"> <data key=\"type\">port</data> <data key=\"number\">4</data> <data key=\"desc\">port 4 at CHI Switch</data> </node> <node id=\"111\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at IAH Switch</data> </node> <node id=\"112\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at IAH Switch</data> </node> <node id=\"113\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at IAH Switch</data> </node> <node id=\"114\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at NYC Switch</data> </node> <node id=\"115\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at NYC Switch</data> </node> <node id=\"116\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at NYC Switch</data> </node> <node id=\"117\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at ATL Switch</data> </node> <node id=\"118\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at ATL Switch</data> </node> <node id=\"119\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at ATL Switch</data> </node> <node id=\"1000\"> <data key=\"type\">device</data> <data key=\"dl_addr\">20:c9:d0:4a:e1:73</data> <data key=\"nw_addr\">192.168.10.101</data> </node> <node id=\"1001\"> <data key=\"type\">device</data> <data key=\"dl_addr\">20:c9:d0:4a:e1:62</data> <data key=\"nw_addr\">192.168.20.101</data> </node> <node id=\"1002\"> <data key=\"type\">device</data> <data key=\"dl_addr\">10:40:f3:e6:8d:55</data> <data key=\"nw_addr\">192.168.10.1</data> </node> <node id=\"1003\"> <data key=\"type\">device</data> <data key=\"dl_addr\">a0:b3:cc:9c:c6:88</data> <data key=\"nw_addr\">192.168.20.1</data> </node> <node id=\"1004\"> <data key=\"type\">device</data> <data key=\"dl_addr\">00:04:20:e2:50:a2</data> <data key=\"nw_addr\">192.168.30.1</data> </node> <node id=\"1005\"> <data key=\"type\">device</data> <data key=\"dl_addr\">58:55:ca:c4:1b:a0</data> <data key=\"nw_addr\">192.168.40.1</data> </node> <edge id=\"10000\" source=\"1\" target=\"101\" label=\"on\"></edge> <edge id=\"10001\" source=\"1\" target=\"102\" label=\"on\"></edge> <edge id=\"10002\" source=\"1\" target=\"103\" label=\"on\"></edge> <edge id=\"10003\" source=\"2\" target=\"104\" label=\"on\"></edge> <edge id=\"10004\" source=\"2\" target=\"105\" label=\"on\"></edge> <edge id=\"10005\" source=\"2\" target=\"106\" label=\"on\"></edge> <edge id=\"10006\" source=\"3\" target=\"107\" label=\"on\"></edge> <edge id=\"10007\" source=\"3\" target=\"108\" label=\"on\"></edge> <edge id=\"10008\" source=\"3\" target=\"109\" label=\"on\"></edge> <edge id=\"10009\" source=\"3\" target=\"110\" label=\"on\"></edge> <edge id=\"10010\" source=\"4\" target=\"111\" label=\"on\"></edge> <edge id=\"10011\" source=\"4\" target=\"112\" label=\"on\"></edge> <edge id=\"10012\" source=\"4\" target=\"113\" label=\"on\"></edge> <edge id=\"10013\" source=\"5\" target=\"114\" label=\"on\"></edge> <edge id=\"10014\" source=\"5\" target=\"115\" label=\"on\"></edge> <edge id=\"10015\" source=\"5\" target=\"116\" label=\"on\"></edge> <edge id=\"10016\" source=\"6\" target=\"117\" label=\"on\"></edge> <edge id=\"10017\" source=\"6\" target=\"118\" label=\"on\"></edge> <edge id=\"10018\" source=\"6\" target=\"119\" label=\"on\"></edge> <edge id=\"11000\" source=\"101\" target=\"107\" label=\"link\"></edge> <edge id=\"11003\" source=\"105\" target=\"111\" label=\"link\"></edge> <edge id=\"11004\" source=\"107\" target=\"101\" label=\"link\"></edge> <edge id=\"11005\" source=\"108\" target=\"112\" label=\"link\"></edge> <edge id=\"11006\" source=\"109\" target=\"114\" label=\"link\"></edge> <edge id=\"11007\" source=\"111\" target=\"105\" label=\"link\"></edge> <edge id=\"11008\" source=\"112\" target=\"108\" label=\"link\"></edge> <edge id=\"11009\" source=\"113\" target=\"117\" label=\"link\"></edge> <edge id=\"11010\" source=\"114\" target=\"109\" label=\"link\"></edge> <edge id=\"11011\" source=\"115\" target=\"118\" label=\"link\"></edge> <edge id=\"11012\" source=\"117\" target=\"113\" label=\"link\"></edge> <edge id=\"11013\" source=\"118\" target=\"115\" label=\"link\"></edge> <edge id=\"12000\" source=\"103\" target=\"1000\" label=\"host\"></edge> <edge id=\"12001\" source=\"103\" target=\"1001\" label=\"host\"></edge> <edge id=\"12002\" source=\"110\" target=\"1002\" label=\"host\"></edge> <edge id=\"12003\" source=\"116\" target=\"1003\" label=\"host\"></edge> <edge id=\"12004\" source=\"106\" target=\"1004\" label=\"host\"></edge> <edge id=\"12005\" source=\"119\" target=\"1005\" label=\"host\"></edge> </graph> </graphml>";
+
+ private static final String testDataLocation = "titan/schema/test-network.xml";
+
+ public static TitanGraph getTestDatabase(){
+ //return TitanFactory.open(testDbLocation);
+// return TitanFactory.openInMemoryGraph();
+ return TitanFactory.open(testDbLocation);
+ }
+
+ public static void populateTestData(TitanGraph titanGraph){
+ Set<String> s = titanGraph.getIndexedKeys(Vertex.class);
+ if (!s.contains("dpid")) {
+ titanGraph.createKeyIndex("dpid", Vertex.class);
+ titanGraph.stopTransaction(Conclusion.SUCCESS);
+ }
+ if (!s.contains("type")) {
+ titanGraph.createKeyIndex("type", Vertex.class);
+ titanGraph.stopTransaction(Conclusion.SUCCESS);
+ }
+
+ //InputStream graphMLStream = new ByteArrayInputStream(testDbGraphML.getBytes());
+
+ try {
+ InputStream graphMLStream = new FileInputStream(testDataLocation);
+ GraphMLReader.inputGraph(titanGraph, graphMLStream);
+ } catch (FileNotFoundException e) {
+ Assert.fail("Test data file not found: " + testDataLocation);
+ } catch (IOException e) {
+ e.printStackTrace();
+ Assert.fail("IOException thrown");
+ }
+
+ //Change the type of all port numbers to short in the database
+ Iterator<Vertex> it = titanGraph.getVertices("type", "port").iterator();
+
+ while (it.hasNext()){
+ Vertex port = it.next();
+
+ if(port.getProperty("number") instanceof Short)
+ {
+ Short portNum = (Short) port.getProperty("number");
+ port.setProperty("number", portNum.shortValue());
+ }
+ else{
+ Integer portNum = (Integer) port.getProperty("number");
+ port.setProperty("number", portNum.shortValue());
+ }
+
+ }
+
+ titanGraph.stopTransaction(Conclusion.SUCCESS);
+ }
+
+ public static void deleteTestDatabase(){
+ try {
+ FileUtils.deleteDirectory(new File(testDbLocation));
+ } catch (IOException e) {
+ System.out.println("delete failed");
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
new file mode 100644
index 0000000..bcff36a
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
@@ -0,0 +1,1523 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.easymock.EasyMock;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.frames.Property;
+import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.IDBConnection;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
+/**
+ * Mock class of GraphDBOperation which provides additional setter to construct a graph for test.
+ * This object simply caches parameters set up by override interfaces and reflect them when commit().
+ * *ForTest() methods are exempt from cache, parameters through those methods are reflected soon.
+ * @author Naoki Shiota
+ *
+ */
+public class TestableGraphDBOperation extends GraphDBOperation {
+ protected static Logger log = LoggerFactory.getLogger(TestableGraphDBOperation.class);
+
+ protected List<TestSwitchObject> switches;
+ protected List<TestPortObject> ports;
+ protected List<TestDeviceObject> devices;
+ protected List<TestFlowPath> paths;
+ protected List<TestFlowEntry> entries;
+
+ protected List<TestSwitchObject> switchesToAdd;
+ protected List<TestPortObject> portsToAdd;
+ protected List<TestDeviceObject> devicesToAdd;
+ protected List<TestFlowPath> pathsToAdd;
+ protected List<TestFlowEntry> entriesToAdd;
+
+ protected List<TestSwitchObject> switchesToRemove;
+ protected List<TestPortObject> portsToRemove;
+ protected List<TestDeviceObject> devicesToRemove;
+ protected List<TestFlowPath> pathsToRemove;
+ protected List<TestFlowEntry> entriesToRemove;
+
+ // Testable implementations of INetMapTopologyObject interfaces
+
+ public static class TestSwitchObject implements ISwitchObject {
+ private String state,type,dpid;
+ private List<IPortObject> ports;
+ private List<IDeviceObject> devices;
+ private List<IFlowEntry> entries;
+
+ private String stateToUpdate, typeToUpdate, dpidToUpdate;
+ private List<IPortObject> portsToAdd;
+ private List<IPortObject> portsToRemove;
+
+ public TestSwitchObject() {
+ type = "switch";
+
+ ports = new ArrayList<IPortObject>();
+ portsToAdd = new ArrayList<IPortObject>();
+ portsToRemove = new ArrayList<IPortObject>();
+ devices = new ArrayList<IDeviceObject>();
+ entries = new ArrayList<IFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(IPortObject port : portsToRemove) {
+ ports.remove(port);
+ }
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(dpidToUpdate != null) { dpid = dpidToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ portsToAdd.clear();
+ portsToRemove.clear();
+ stateToUpdate = typeToUpdate = dpidToUpdate = null;
+ }
+
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setDpidForTest(String dpid) { this.dpid = dpid; }
+ public void addPortForTest(TestPortObject port) { ports.add(port); }
+ public void addDeviceForTest(TestDeviceObject dev) { devices.add(dev); }
+ public void addEntryForTest(TestFlowEntry entry) { entries.add(entry); }
+
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { this.stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type ; }
+
+ @Override
+ public void setType(String type) { this.typeToUpdate = type; }
+
+ // Not support for test
+ @Override
+ public Vertex asVertex() { return null; }
+
+ @Override
+ public String getDPID() { return dpid; }
+
+ @Override
+ public void setDPID(String dpid) { this.dpidToUpdate = dpid; }
+
+ @Override
+ public Iterable<IPortObject> getPorts() { return ports; }
+
+ @Override
+ public IPortObject getPort(@GremlinParam("port_num") short port_num) {
+ for(IPortObject port : ports) {
+ if(port.getNumber() == port_num) {
+ return port;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void addPort(IPortObject port) { portsToAdd.add(port); }
+
+ @Override
+ public void removePort(IPortObject port) { portsToRemove.add(port); }
+
+ @Override
+ public Iterable<IDeviceObject> getDevices() { return devices; }
+
+ @Override
+ public Iterable<IFlowEntry> getFlowEntries() { return entries; }
+ }
+
+ public static class TestPortObject implements IPortObject {
+ private String state,type,desc;
+ private Short number;
+ private Integer port_state;
+ private ISwitchObject sw;
+
+ private List<IPortObject> linkedPorts;
+ private List<IDeviceObject> devices;
+ private List<IFlowEntry> inflows,outflows;
+
+ private String stateToUpdate,typeToUpdate,descToUpdate;
+ private Short numberToUpdate;
+ private Integer port_stateToUpdate;
+
+ private List<IPortObject> linkedPortsToAdd;
+ private List<IPortObject> linkedPortsToRemove;
+ private List<IDeviceObject> devicesToAdd;
+ private List<IDeviceObject> devicesToRemove;
+
+
+ public TestPortObject() {
+ type = "port";
+
+ linkedPorts = new ArrayList<IPortObject>();
+ linkedPortsToAdd = new ArrayList<IPortObject>();
+ linkedPortsToRemove = new ArrayList<IPortObject>();
+ devices = new ArrayList<IDeviceObject>();
+ devicesToAdd = new ArrayList<IDeviceObject>();
+ devicesToRemove = new ArrayList<IDeviceObject>();
+ inflows = new ArrayList<IFlowEntry>();
+ outflows = new ArrayList<IFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : linkedPortsToAdd) { linkedPorts.add(port); }
+ for(IPortObject port : linkedPortsToRemove) { linkedPorts.remove(port); }
+ for(IDeviceObject dev : devicesToAdd) { devices.add(dev); }
+ for(IDeviceObject dev : devicesToRemove) { devices.remove(dev); }
+
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(descToUpdate != null) { desc = descToUpdate; }
+ if(numberToUpdate != null) { number = numberToUpdate; }
+ if(port_stateToUpdate != null) { port_state = port_stateToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ linkedPortsToAdd.clear();
+ linkedPortsToRemove.clear();
+ devicesToAdd.clear();
+ devicesToRemove.clear();
+ stateToUpdate = typeToUpdate = descToUpdate = null;
+ port_stateToUpdate = null;
+ numberToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setDescForTest(String desc) { this.desc = desc; }
+ public void setNumberForTest(Short number) { this.number = number; }
+ public void setPortStateForTest(Integer state) { this.port_state = state; }
+ public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
+ public void addLinkedPortForTest(TestPortObject port) { this.linkedPorts.add(port); }
+ public void addInflowForTest(TestFlowEntry entry) { inflows.add(entry); }
+ public void addOutflowForTest(TestFlowEntry entry) { outflows.add(entry); }
+
+ // Override methods for mock IPortObject
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { this.stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type; }
+
+ @Override
+ public void setType(String type) { this.typeToUpdate = type; }
+
+ // not support for test
+ @Override
+ public Vertex asVertex() {
+ return null;
+ }
+
+ @Override
+ public Short getNumber() { return number; }
+
+ @Override
+ public void setNumber(Short n) { this.numberToUpdate = n; }
+
+ @Override
+ public String getDesc() { return desc; }
+
+ @Override
+ public void setDesc(String s) { this.descToUpdate = s; }
+
+ @Override
+ public Integer getPortState() { return port_state; }
+
+ @Override
+ public void setPortState(Integer s) { this.port_stateToUpdate = s; }
+
+ @Override
+ public ISwitchObject getSwitch() { return sw; }
+
+ @Override
+ public Iterable<IDeviceObject> getDevices() { return devices; }
+
+ @Override
+ public void setDevice(IDeviceObject device) { devicesToAdd.add(device); }
+
+ @Override
+ public void removeDevice(IDeviceObject device) { devicesToRemove.add(device); }
+
+ @Override
+ public Iterable<IFlowEntry> getInFlowEntries() { return inflows; }
+
+ @Override
+ public Iterable<IFlowEntry> getOutFlowEntries() { return outflows; }
+
+ @Override
+ public Iterable<IPortObject> getLinkedPorts() { return linkedPorts; }
+
+ @Override
+ public void removeLink(IPortObject dest_port) { linkedPortsToRemove.add(dest_port); }
+
+ @Override
+ public void setLinkPort(IPortObject dest_port) { linkedPortsToAdd.add(dest_port); }
+
+ @Override
+ @JsonIgnore
+ @Property("port_id")
+ public void setPortId(String id) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ @JsonIgnore
+ @Property("port_id")
+ public String getPortId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ }
+
+ public static class TestDeviceObject implements IDeviceObject {
+ private String state,type,mac,ipaddr;
+ private List<IPortObject> ports;
+ private List<ISwitchObject> switches;
+
+ private String stateToUpdate,typeToUpdate,macToUpdate,ipaddrToUpdate;
+ private List<IPortObject> portsToAdd;
+ private List<IPortObject> portsToRemove;
+
+ public TestDeviceObject() {
+ type = "device";
+
+ ports = new ArrayList<IPortObject>();
+ portsToAdd = new ArrayList<IPortObject>();
+ portsToRemove = new ArrayList<IPortObject>();
+ switches = new ArrayList<ISwitchObject>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(IPortObject port : portsToRemove) {
+ ports.remove(port);
+ }
+
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(macToUpdate != null) { mac = macToUpdate; }
+ if(ipaddrToUpdate != null) { ipaddr = ipaddrToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ ports.clear();
+ portsToAdd.clear();
+ portsToRemove.clear();
+
+ stateToUpdate = typeToUpdate = macToUpdate = ipaddrToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setMacForTest(String mac) { this.mac = mac; }
+ public void setIpaddrForTest(String ipaddr) { this.ipaddr = ipaddr; }
+ public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
+ public void addPortForTest(IPortObject port) { ports.add(port); }
+
+
+ // Override methods
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type; }
+
+ @Override
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getMACAddress() { return mac; }
+
+ @Override
+ public void setMACAddress(String macaddr) { macToUpdate = macaddr; }
+
+ @Override
+ public String getIPAddress() { return ipaddr; }
+
+ @Override
+ public void setIPAddress(String ipaddr) { ipaddrToUpdate = ipaddr; }
+
+ @Override
+ public Iterable<IPortObject> getAttachedPorts() {
+ return ports; }
+
+ @Override
+ public void setHostPort(IPortObject port) { portsToAdd.add(port); }
+
+ @Override
+ public void removeHostPort(IPortObject port) { portsToRemove.add(port); }
+
+ @Override
+ public Iterable<ISwitchObject> getSwitch() { return switches; }
+ }
+
+ public static class TestFlowPath implements IFlowPath {
+ private String state,type,flowId,installerId,srcSw,dstSw;
+ private Long flowPathFlags;
+ private String dataPathSummary,userState;
+ private Short srcPort,dstPort;
+ private String matchSrcMac,matchDstMac;
+ private Short matchEthernetFrameType;
+ private Short matchVlanId;
+ private Byte matchVlanPriority;
+ private String matchSrcIpaddr,matchDstIpaddr;
+ private Byte matchIpProto, matchIpToS;
+ private Short matchSrcTcpUdpPort, matchDstTcpUdpPort;
+ private String actions;
+
+ private List<IFlowEntry> entries;
+ private List<ISwitchObject> switches;
+
+ private String stateToUpdate,typeToUpdate,flowIdToUpdate,installerIdToUpdate,srcSwToUpdate,dstSwToUpdate;
+ private Long flowPathFlagsToUpdate;
+ private String dataPathSummaryToUpdate,userStateToUpdate;
+ private Short srcPortToUpdate,dstPortToUpdate;
+ private String matchSrcMacToUpdate,matchDstMacToUpdate;
+ private Short matchEthernetFrameTypeToUpdate;
+ private Short matchVlanIdToUpdate;
+ private Byte matchVlanPriorityToUpdate;
+ private String matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
+ private Byte matchIpProtoToUpdate, matchIpToSToUpdate;
+ private Short matchSrcTcpUdpPortToUpdate, matchDstTcpUdpPortToUpdate;
+ private String actionsToUpdate;
+
+ private List<IFlowEntry> flowsToAdd;
+ private List<IFlowEntry> flowsToRemove;
+
+ public TestFlowPath() {
+ type = "flow";
+
+ entries = new ArrayList<IFlowEntry>();
+ flowsToAdd = new ArrayList<IFlowEntry>();
+ flowsToRemove = new ArrayList<IFlowEntry>();
+
+ switches = new ArrayList<ISwitchObject>();
+
+ clear();
+ }
+
+ public void commit() {
+ for(IFlowEntry flow : flowsToAdd) {
+ entries.add(flow);
+ }
+ for(IFlowEntry flow : flowsToRemove) {
+ entries.remove(flow);
+ }
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(flowIdToUpdate != null) { flowId = flowIdToUpdate; }
+ if(installerIdToUpdate != null) { installerId = installerIdToUpdate; }
+ if(flowPathFlagsToUpdate != null) { flowPathFlags = flowPathFlagsToUpdate; }
+ if(srcSwToUpdate != null) { srcSw = srcSwToUpdate; }
+ if(dstSwToUpdate != null) { dstSw = dstSwToUpdate; }
+ if(dataPathSummaryToUpdate != null) { dataPathSummary = dataPathSummaryToUpdate; }
+ if(userStateToUpdate != null) { userState = userStateToUpdate; }
+ if(srcPortToUpdate != null) { srcPort = srcPortToUpdate; }
+ if(dstPortToUpdate != null) { dstPort = dstPortToUpdate; }
+ if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
+ if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
+ if(matchEthernetFrameTypeToUpdate != null) { matchEthernetFrameType = matchEthernetFrameTypeToUpdate; }
+ if(matchVlanIdToUpdate != null) { matchVlanId = matchVlanIdToUpdate; }
+ if(matchVlanPriorityToUpdate != null) { matchVlanPriority = matchVlanPriorityToUpdate; }
+ if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
+ if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
+ if(matchIpProtoToUpdate != null) { matchIpProto = matchIpProtoToUpdate; }
+ if(matchIpToSToUpdate != null) { matchIpToS = matchIpToSToUpdate; }
+ if(matchSrcTcpUdpPortToUpdate != null) { matchSrcTcpUdpPort = matchSrcTcpUdpPortToUpdate; }
+ if(matchDstTcpUdpPortToUpdate != null) { matchDstTcpUdpPort = matchDstTcpUdpPortToUpdate; }
+ if(actionsToUpdate != null) { actions = actionsToUpdate; }
+ }
+
+ public void rollback() {
+ clear();
+ }
+
+ public void clear() {
+ flowsToAdd.clear();
+ flowsToRemove.clear();
+
+ stateToUpdate = typeToUpdate = flowIdToUpdate = installerIdToUpdate = null;
+ flowPathFlagsToUpdate = null;
+ srcSwToUpdate = dstSwToUpdate = dataPathSummaryToUpdate = userStateToUpdate = null;
+ srcPortToUpdate = dstPortToUpdate = null;
+ matchSrcMacToUpdate = matchDstMacToUpdate = null;
+ matchEthernetFrameTypeToUpdate = null;
+ matchVlanIdToUpdate = null;
+ matchVlanPriorityToUpdate = null;
+ matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
+ matchIpProtoToUpdate = matchIpToSToUpdate = null;
+ matchSrcTcpUdpPortToUpdate = matchDstTcpUdpPortToUpdate = null;
+ actionsToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setFlowIdForTest(String flowId) { this.flowId = flowId; }
+ public void setInstallerIdForTest(String installerId) { this.installerId = installerId; }
+ public void setFlowPathFlagsForTest(Long flowPathFlags) { this.flowPathFlags = flowPathFlags; }
+ public void setSrcSwForTest(String srcSw) { this.srcSw = srcSw; }
+ public void setDstSwForTest(String dstSw) { this.dstSw = dstSw; }
+ public void setDataPathSummaryForTest(String dataPathSummary) { this.dataPathSummary = dataPathSummary; }
+ public void setUserStateForTest(String userState) { this.userState = userState; }
+ public void setSrcPortForTest(Short srcPort) { this.srcPort = srcPort; }
+ public void setDstPortForTest(Short dstPort) { this.dstPort = dstPort; }
+ public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
+ public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
+ public void setMatchEthernetFrameTypeForTest(Short matchEthernetFrameType) { this.matchEthernetFrameType = matchEthernetFrameType; }
+ public void setMatchVlanIdForTest(Short matchVlanId) { this.matchVlanId = matchVlanId; }
+ public void setMatchVlanPriorityForTest(Byte matchVlanPriority) { this.matchVlanPriority = matchVlanPriority; }
+ public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
+ public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
+ public void setMatchIpProtoForTest(Byte matchIpProto) { this.matchIpProto = matchIpProto; }
+ public void setMatchIpToSForTest(Byte matchIpToS) { this.matchIpToS = matchIpToS; }
+ public void setMatchSrcTcpUdpPortForTest(Short matchSrcTcpUdpPort) { this.matchSrcTcpUdpPort = matchSrcTcpUdpPort; }
+ public void setMatchDstTcpUdpPortForTest(Short matchDstTcpUdpPort) { this.matchDstTcpUdpPort = matchDstTcpUdpPort; }
+ public void setActionsForTest(String actions) { this.actions = actions; }
+ public void addFlowEntryForTest(IFlowEntry entry) { entries.add(entry); }
+ public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
+
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type; }
+
+ @Override
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getFlowId() { return flowId; }
+
+ @Override
+ public void setFlowId(String flowId) { flowIdToUpdate = flowId; }
+
+ @Override
+ public String getInstallerId() { return installerId; }
+
+ @Override
+ public void setInstallerId(String installerId) { installerIdToUpdate = installerId; }
+
+ @Override
+ public Long getFlowPathFlags() { return flowPathFlags; }
+
+ @Override
+ public void setFlowPathFlags(Long flowPathFlags) { flowPathFlagsToUpdate = flowPathFlags; }
+
+ @Override
+ public String getSrcSwitch() { return srcSw; }
+
+ @Override
+ public void setSrcSwitch(String srcSwitch) { srcSwToUpdate = srcSwitch; }
+
+ @Override
+ public Short getSrcPort() { return srcPort; }
+
+ @Override
+ public void setSrcPort(Short srcPort) { srcPortToUpdate = srcPort; }
+
+ @Override
+ public String getDstSwitch() { return dstSw; }
+
+ @Override
+ public void setDstSwitch(String dstSwitch) { dstSwToUpdate = dstSwitch; }
+
+ @Override
+ public Short getDstPort() { return dstPort; }
+
+ @Override
+ public void setDstPort(Short dstPort) { dstPortToUpdate = dstPort; }
+
+ @Override
+ public String getDataPathSummary() { return dataPathSummary; }
+
+ @Override
+ public void setDataPathSummary(String dataPathSummary) { dataPathSummaryToUpdate = dataPathSummary; }
+
+ @Override
+ public Iterable<IFlowEntry> getFlowEntries() { return entries; }
+
+ @Override
+ public void addFlowEntry(IFlowEntry flowEntry) {
+ if(! entries.contains(flowEntry)) {
+ flowsToAdd.add(flowEntry);
+ }
+ }
+
+ @Override
+ public void removeFlowEntry(IFlowEntry flowEntry) {
+ if(entries.contains(flowEntry)) {
+ flowsToAdd.add(flowEntry);
+ }
+ }
+
+ @Override
+ public String getMatchSrcMac() { return matchSrcMac; }
+
+ @Override
+ public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
+
+ @Override
+ public String getMatchDstMac() { return matchDstMac; }
+
+ @Override
+ public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
+
+ @Override
+ public Short getMatchEthernetFrameType() { return matchEthernetFrameType; }
+
+ @Override
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
+ matchEthernetFrameTypeToUpdate = matchEthernetFrameType; }
+
+ @Override
+ public Short getMatchVlanId() { return matchVlanId; }
+
+ @Override
+ public void setMatchVlanId(Short matchVlanId) {
+ matchVlanIdToUpdate = matchVlanId; }
+
+ @Override
+ public Byte getMatchVlanPriority() { return matchVlanPriority; }
+
+ @Override
+ public void setMatchVlanPriority(Byte matchVlanPriority) {
+ matchVlanPriorityToUpdate = matchVlanPriority; }
+
+ @Override
+ public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
+
+ @Override
+ public void setMatchSrcIPv4Net(String matchSrcIPv4Net) {
+ matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
+
+ @Override
+ public String getMatchDstIPv4Net() { return matchDstIpaddr; }
+
+ @Override
+ public void setMatchDstIPv4Net(String matchDstIPv4Net) {
+ matchDstIpaddrToUpdate = matchDstIPv4Net; }
+
+ @Override
+ public Byte getMatchIpProto() { return matchIpProto; }
+
+ @Override
+ public void setMatchIpProto(Byte matchIpProto) {
+ matchIpProtoToUpdate = matchIpProto; }
+
+ @Override
+ public Byte getMatchIpToS() { return matchIpToS; }
+
+ @Override
+ public void setMatchIpToS(Byte matchIpToS) {
+ matchIpToSToUpdate = matchIpToS; }
+
+ @Override
+ public Short getMatchSrcTcpUdpPort() { return matchSrcTcpUdpPort; }
+
+ @Override
+ public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort) {
+ matchSrcTcpUdpPortToUpdate = matchSrcTcpUdpPort; }
+
+ @Override
+ public Short getMatchDstTcpUdpPort() { return matchDstTcpUdpPort; }
+
+ @Override
+ public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort) {
+ matchDstTcpUdpPortToUpdate = matchDstTcpUdpPort; }
+
+ @Override
+ public String getActions() { return actions; }
+
+ @Override
+ public void setActions(String actions) {
+ actionsToUpdate = actions; }
+
+ @Override
+ public Iterable<ISwitchObject> getSwitches() { return switches; }
+
+ @Override
+ public String getUserState() { return userState; }
+
+ @Override
+ public void setUserState(String userState) { userStateToUpdate = userState; }
+ }
+
+ public static class TestFlowEntry implements IFlowEntry {
+ private String state,type,entryId,dpid,userState,switchState,errorStateType,errorStateCode;
+ private Short matchInPort;
+ private String matchSrcMac,matchDstMac;
+ private Short matchEtherFrameType;
+ private Short matchVlanId;
+ private Byte matchVlanPriority;
+ private String matchSrcIpaddr,matchDstIpaddr;
+ private Byte matchIpProto, matchIpToS;
+ private Short matchSrcTcpUdpPort, matchDstTcpUdpPort;
+ private Short actionOutputPort;
+ private String actions;
+
+ private IFlowPath flowPath;
+ private ISwitchObject sw;
+ private IPortObject inport,outport;
+
+ private String stateToUpdate,typeToUpdate,entryIdToUpdate,dpidToUpdate,
+ userStateToUpdate,switchStateToUpdate,errorStateTypeToUpdate,errorStateCodeToUpdate;
+ private Short matchInPortToUpdate;
+ private String matchSrcMacToUpdate,matchDstMacToUpdate;
+ private Short matchEtherFrameTypeToUpdate;
+ private Short matchVlanIdToUpdate;
+ private Byte matchVlanPriorityToUpdate;
+ private String matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
+ private Byte matchIpProtoToUpdate, matchIpToSToUpdate;
+ private Short matchSrcTcpUdpPortToUpdate, matchDstTcpUdpPortToUpdate;
+ private Short actionOutputPortToUpdate;
+ private String actionsToUpdate;
+
+ private IFlowPath flowPathToUpdate;
+ private ISwitchObject swToUpdate;
+ private IPortObject inportToUpdate,outportToUpdate;
+
+ public TestFlowEntry() {
+ type = "flow_entry";
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(entryIdToUpdate != null) { entryId = entryIdToUpdate; }
+ if(dpidToUpdate != null) { dpid = dpidToUpdate; }
+ if(userStateToUpdate != null) { userState = userStateToUpdate; }
+ if(switchStateToUpdate != null) { switchState = switchStateToUpdate; }
+ if(errorStateTypeToUpdate != null) { errorStateType = errorStateTypeToUpdate; }
+ if(errorStateCodeToUpdate != null) { errorStateCode = errorStateCodeToUpdate; }
+ if(matchInPortToUpdate != null) { matchInPort = matchInPortToUpdate; }
+ if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
+ if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
+ if(matchEtherFrameTypeToUpdate != null) { matchEtherFrameType = matchEtherFrameTypeToUpdate; }
+ if(matchVlanIdToUpdate != null) { matchVlanId = matchVlanIdToUpdate; }
+ if(matchVlanPriorityToUpdate != null) { matchVlanPriority = matchVlanPriorityToUpdate; }
+ if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
+ if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
+ if(matchIpProtoToUpdate != null) { matchIpProto = matchIpProtoToUpdate; }
+ if(matchIpToSToUpdate != null) { matchIpToS = matchIpToSToUpdate; }
+ if(matchSrcTcpUdpPortToUpdate != null) { matchSrcTcpUdpPort = matchSrcTcpUdpPortToUpdate; }
+ if(matchDstTcpUdpPortToUpdate != null) { matchDstTcpUdpPort = matchDstTcpUdpPortToUpdate; }
+ if(actionOutputPortToUpdate != null) { actionOutputPort = actionOutputPortToUpdate; }
+ if(actionsToUpdate != null) { actions = actionsToUpdate; }
+
+ if(flowPathToUpdate != null) { flowPath = flowPathToUpdate; }
+ if(swToUpdate != null) { sw = swToUpdate; }
+ if(inportToUpdate != null) { inport = inportToUpdate; }
+ if(outportToUpdate != null) { outport = outportToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ stateToUpdate = typeToUpdate = entryIdToUpdate = dpidToUpdate = null;
+ userStateToUpdate = switchStateToUpdate = errorStateTypeToUpdate = errorStateCodeToUpdate = null;
+ matchInPortToUpdate = null;
+ matchSrcMacToUpdate = matchDstMacToUpdate = null;
+ matchEtherFrameTypeToUpdate = null;
+ matchVlanIdToUpdate = null;
+ matchVlanPriorityToUpdate = null;
+ matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
+ matchIpProtoToUpdate = matchIpToSToUpdate = null;
+ matchSrcTcpUdpPortToUpdate = matchDstTcpUdpPortToUpdate = null;
+ actionOutputPortToUpdate = null;
+ actionsToUpdate = null;
+ flowPathToUpdate = null;
+ swToUpdate = null;
+ inportToUpdate = outportToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setEntryIdForTest(String entryId) { this.entryId = entryId; }
+ public void setDpidForTest(String dpid) { this.dpid = dpid; }
+ public void setUserStateForTest(String userState) { this.userState = userState; }
+ public void setSwitchStateForTest(String switchState) { this.switchState = switchState; }
+ public void setErrorStateTypeForTest(String errorStateType) { this.errorStateType = errorStateType; }
+ public void setErrorStateCodeForTest(String errorStateCode) { this.errorStateCode = errorStateCode; }
+ public void setMatchInPortForTest(Short matchInPort) { this.matchInPort = matchInPort; }
+ public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
+ public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
+ public void setMatchEtherFrameTypeForTest(Short matchEtherFrameType) { this.matchEtherFrameType = matchEtherFrameType; }
+ public void setMatchVlanIdForTest(Short matchVlanId) { this.matchVlanId = matchVlanId; }
+ public void setMatchVlanPriorityForTest(Byte matchVlanPriority) { this.matchVlanPriority = matchVlanPriority; }
+ public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
+ public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
+ public void setMatchIpProtoForTest(Byte matchIpProto) { this.matchIpProto = matchIpProto; }
+ public void setMatchIpToSForTest(Byte matchIpToS) { this.matchIpToS = matchIpToS; }
+ public void setMatchSrcTcpUdpPortForTest(Short matchSrcTcpUdpPort) { this.matchSrcTcpUdpPort = matchSrcTcpUdpPort; }
+ public void setMatchDstTcpUdpPortForTest(Short matchDstTcpUdpPort) { this.matchDstTcpUdpPort = matchDstTcpUdpPort; }
+ public void setActionOutputPortForTest(Short actionOutputPort) { this.actionOutputPort = actionOutputPort; }
+ public void setActionsForTest(String actions) { this.actions = actions; }
+ public void setFlowPathForTest(IFlowPath flowPath) { this.flowPath = flowPath; }
+ public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
+ public void setInportForTest(IPortObject inport) { this.inport = inport; }
+ public void setOutportForTest(IPortObject outport) { this.outport = outport; }
+
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type; }
+
+ @Override
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getFlowEntryId() { return entryId; }
+
+ @Override
+ public void setFlowEntryId(String flowEntryId) { entryIdToUpdate = flowEntryId; }
+
+ @Override
+ public String getSwitchDpid() { return dpid; }
+
+ @Override
+ public void setSwitchDpid(String switchDpid) { dpidToUpdate = switchDpid; }
+
+ @Override
+ public String getUserState() { return userState; }
+
+ @Override
+ public void setUserState(String userState) { userStateToUpdate = userState; }
+
+ @Override
+ public String getSwitchState() { return switchState; }
+
+ @Override
+ public void setSwitchState(String switchState) { switchStateToUpdate = switchState; }
+
+ @Override
+ public String getErrorStateType() { return errorStateType; }
+
+ @Override
+ public void setErrorStateType(String errorStateType) { errorStateTypeToUpdate = errorStateType; }
+
+ @Override
+ public String getErrorStateCode() { return errorStateCode; }
+
+ @Override
+ public void setErrorStateCode(String errorStateCode) { errorStateCodeToUpdate = errorStateCode; }
+
+ @Override
+ public Short getMatchInPort() { return matchInPort; }
+
+ @Override
+ public void setMatchInPort(Short matchInPort) { matchInPortToUpdate = matchInPort; }
+
+ @Override
+ public String getMatchSrcMac() { return matchSrcMac; }
+
+ @Override
+ public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
+
+ @Override
+ public String getMatchDstMac() { return matchDstMac; }
+
+ @Override
+ public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
+
+ @Override
+ public Short getMatchEthernetFrameType() {return matchEtherFrameType; }
+
+ @Override
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType) { matchEtherFrameTypeToUpdate = matchEthernetFrameType; }
+
+ @Override
+ public Short getMatchVlanId() {return matchVlanId; }
+
+ @Override
+ public void setMatchVlanId(Short matchVlanId) { matchVlanId = matchVlanId; }
+
+ @Override
+ public Byte getMatchVlanPriority() {return matchVlanPriority; }
+
+ @Override
+ public void setMatchVlanPriority(Byte matchVlanPriority) { matchVlanPriority = matchVlanPriority; }
+
+ @Override
+ public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
+
+ @Override
+ public void setMatchSrcIPv4Net(String matchSrcIPv4Net) { matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
+
+ @Override
+ public String getMatchDstIPv4Net() { return matchDstIpaddr; }
+
+ @Override
+ public void setMatchDstIPv4Net(String matchDstIPv4Net) { matchDstIpaddrToUpdate = matchDstIPv4Net; }
+
+ @Override
+ public Byte getMatchIpProto() {return matchIpProto; }
+
+ @Override
+ public void setMatchIpProto(Byte matchIpProto) { matchIpProto = matchIpProto; }
+
+ @Override
+ public Byte getMatchIpToS() {return matchIpToS; }
+
+ @Override
+ public void setMatchIpToS(Byte matchIpToS) { matchIpToS = matchIpToS; }
+
+ @Override
+ public Short getMatchSrcTcpUdpPort() {return matchSrcTcpUdpPort; }
+
+ @Override
+ public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort) { matchSrcTcpUdpPortToUpdate = matchSrcTcpUdpPort; }
+
+ @Override
+ public Short getMatchDstTcpUdpPort() {return matchDstTcpUdpPort; }
+
+ @Override
+ public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort) { matchDstTcpUdpPortToUpdate = matchDstTcpUdpPort; }
+
+ @Override
+ public Short getActionOutputPort() { return actionOutputPort; }
+
+ @Override
+ public void setActionOutputPort(Short actionOutputPort) { actionOutputPortToUpdate = actionOutputPort; }
+
+ @Override
+ public String getActions() { return actions; }
+
+ @Override
+ public void setActions(String actions) { actionsToUpdate = actions; }
+
+ @Override
+ public IFlowPath getFlow() { return flowPath; }
+
+ @Override
+ public void setFlow(IFlowPath flow) { flowPathToUpdate = flow; }
+
+ @Override
+ public ISwitchObject getSwitch() { return sw; }
+
+ @Override
+ public void setSwitch(ISwitchObject sw) { swToUpdate = sw; }
+
+ @Override
+ public IPortObject getInPort() { return inport; }
+
+ @Override
+ public void setInPort(IPortObject port) { inportToUpdate = port; }
+
+ @Override
+ public IPortObject getOutPort() { return outport; }
+
+ @Override
+ public void setOutPort(IPortObject port) { outportToUpdate = port; }
+ }
+
+
+ public TestableGraphDBOperation() {
+ super(EasyMock.createNiceMock(GraphDBConnection.class));
+
+ switches = new ArrayList<TestSwitchObject>();
+ ports = new ArrayList<TestPortObject>();
+ devices = new ArrayList<TestDeviceObject>();
+ paths = new ArrayList<TestFlowPath>();
+ entries = new ArrayList<TestFlowEntry>();
+
+ switchesToAdd = new ArrayList<TestSwitchObject>();
+ portsToAdd = new ArrayList<TestPortObject>();
+ devicesToAdd = new ArrayList<TestDeviceObject>();
+ pathsToAdd = new ArrayList<TestFlowPath>();
+ entriesToAdd = new ArrayList<TestFlowEntry>();
+
+ switchesToRemove = new ArrayList<TestSwitchObject>();
+ portsToRemove = new ArrayList<TestPortObject>();
+ devicesToRemove = new ArrayList<TestDeviceObject>();
+ pathsToRemove = new ArrayList<TestFlowPath>();
+ entriesToRemove = new ArrayList<TestFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ private void clearUncommitedData() {
+ for(TestFlowEntry flow : entries) {
+ flow.clearUncommitedData();
+ }
+ for(TestFlowEntry flow : entriesToAdd) {
+ flow.clearUncommitedData();
+ }
+
+ for(TestDeviceObject dev : devices) {
+ dev.clearUncommitedData();
+ }
+ for(TestDeviceObject dev : devicesToAdd) {
+ dev.clearUncommitedData();
+ }
+
+ for(TestSwitchObject sw : switches) {
+ sw.clearUncommitedData();
+ }
+ for(TestSwitchObject sw : switchesToAdd) {
+ sw.clearUncommitedData();
+ }
+
+ for(TestPortObject port : ports) {
+ port.clearUncommitedData();
+ }
+ for(TestPortObject port : portsToAdd) {
+ port.clearUncommitedData();
+ }
+
+ entriesToAdd.clear();
+ entriesToRemove.clear();
+ devicesToAdd.clear();
+ devicesToRemove.clear();
+ switchesToAdd.clear();
+ switchesToRemove.clear();
+ portsToAdd.clear();
+ portsToRemove.clear();
+ }
+
+
+ // this.*ForTest() methods below are supposed to be used for creation of test topology.
+ /**
+ * Create new empty TestSwitchObject.
+ * @return New TestSwitchObject
+ */
+ public TestSwitchObject createNewSwitchForTest() {
+ TestSwitchObject sw = new TestSwitchObject();
+ switches.add(sw);
+ return sw;
+ }
+
+ /**
+ * Create new TestSwitchObject with specific DPID.
+ * @param dpid DPID to be set
+ * @return New TestSwitchObject
+ */
+ public TestSwitchObject createNewSwitchForTest(String dpid) {
+ for(TestSwitchObject sw_loop : switches) {
+ if(sw_loop.getDPID().equals(dpid)) {
+ // Already created
+ log.error("switch already exists : " + dpid);
+ return sw_loop;
+ }
+ }
+
+ TestSwitchObject sw = new TestSwitchObject();
+
+ sw.setDpidForTest(dpid);
+ switches.add(sw);
+
+ return sw;
+ }
+
+ /**
+ * Create new empty TestPortObject.
+ * @return New TestPortObject
+ */
+ public TestPortObject createNewPortForTest() {
+ TestPortObject port = new TestPortObject();
+ ports.add(port);
+ return port;
+ }
+
+ /**
+ * Create new TestPortObject with specific DPID and port number.
+ * @param dpid DPID to be set
+ * @param number Port number to be set
+ * @return New TestPortObject
+ */
+ public TestPortObject createNewPortForTest(String dpid, Short number) {
+ TestSwitchObject sw = null;
+
+ for(TestSwitchObject sw_loop : switches) {
+ if(sw_loop.getDPID().equals(dpid)) {
+ sw = sw_loop;
+ }
+ }
+
+ if(sw != null) {
+ TestPortObject port = new TestPortObject();
+ port.setNumberForTest(number);
+ port.setSwitchForTest(sw);
+ sw.addPortForTest(port);
+
+ ports.add(port);
+
+ return port;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Link a TestPortObject to other TestPortObject.
+ * @param src TestPortObjecgt of source port.
+ * @param dst TestPortObjecgt of destination port.
+ */
+ public void setLinkBetweenPortsForTest(TestPortObject src, TestPortObject dst) {
+ src.addLinkedPortForTest(dst);
+ }
+
+ /**
+ * Create new empty TestDeviceObject.
+ * @return New TestDeviceObject
+ */
+ public TestDeviceObject createNewDeviceForTest() {
+ TestDeviceObject dev = new TestDeviceObject();
+
+ return dev;
+ }
+
+ /**
+ * Create new empty TestFlowPathObject.
+ * @return New TestFlowPathObject
+ */
+ public TestFlowPath createNewFlowPathForTest() {
+ TestFlowPath path = new TestFlowPath();
+ paths.add(path);
+ return path;
+ }
+
+ /**
+ * Create new empty TestFlowEntryObject.
+ * @return New TestFlowEntryObject
+ */
+ public TestFlowEntry createNewFlowEntryForTest() {
+ TestFlowEntry entry = new TestFlowEntry();
+ entries.add(entry);
+ return entry;
+ }
+
+
+ public boolean hasLinkBetween(String srcSw_str, Short srcNumber, String dstSw_str, Short dstNumber) {
+ IPortObject srcPort = null, dstPort = null;
+ long srcSw = HexString.toLong(srcSw_str);
+ long dstSw = HexString.toLong(dstSw_str);
+
+ for(TestSwitchObject sw : switches) {
+ long swLong = HexString.toLong(sw.getDPID());
+ if(swLong == srcSw) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(srcNumber)) {
+ srcPort = port;
+ }
+ }
+ } else if(swLong == dstSw) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(dstNumber)) {
+ dstPort = port;
+ }
+ }
+ }
+ }
+
+ if(srcPort != null && dstPort != null) {
+ for(IPortObject port : srcPort.getLinkedPorts()) {
+ if(port.equals(dstPort)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ // Overriding methods below are to mock GraphDBOperation class.
+ @Override
+ public ISwitchObject newSwitch(String dpid) {
+ TestSwitchObject sw = new TestSwitchObject();
+ sw.setDPID(dpid);
+ switchesToAdd.add(sw);
+
+ return sw;
+ }
+
+ @Override
+ public ISwitchObject searchSwitch(String dpid_str) {
+ Long dpid = HexString.toLong(dpid_str);
+
+ for(ISwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid) {
+ return sw;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ISwitchObject searchActiveSwitch(String dpid_str) {
+ Long dpid = HexString.toLong(dpid_str);
+
+ for(ISwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid && sw.getState().equals("ACTIVE")) {
+ return sw;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getActiveSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ if(sw.getState() != null && sw.getState().equals("ACTIVE")) {
+ list.add(sw);
+ }
+ }
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getAllSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ list.add(sw);
+ }
+
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getInactiveSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ if(! sw.getState().equals("ACTIVE")) {
+ list.add(sw);
+ }
+ }
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
+ List<IFlowEntry> list = new ArrayList<IFlowEntry>();
+
+ for(TestFlowEntry entry : entries) {
+ if(entry.getSwitchState().equals("FE_SWITCH_NOT_UPDATED")) {
+ list.add(entry);
+ }
+ }
+ return list;
+ }
+
+ @Override
+ public void removeSwitch(ISwitchObject sw) {
+ if(switches.contains(sw)) {
+ switchesToRemove.add((TestSwitchObject)sw);
+ }
+ }
+
+ @Override
+ public IPortObject newPort(Short portNumber) {
+ TestPortObject port = new TestPortObject();
+ port.setNumber(portNumber);
+
+ return port;
+ }
+
+ public IPortObject newPort(Long dpid, Short portNumber) {
+ TestPortObject port = null;
+ TestSwitchObject sw = (TestSwitchObject)searchSwitch(HexString.toHexString(dpid));
+
+ if(sw != null) {
+ port = (TestPortObject)newPort(portNumber);
+ portsToAdd.add(port);
+ sw.addPort(port);
+ }
+
+ return port;
+ }
+
+ @Override
+ public IPortObject searchPort(String dpid_str, Short number) {
+ long dpid = HexString.toLong(dpid_str);
+
+ for(TestSwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(number)) {
+ return port;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void removePort(IPortObject port) {
+ for(TestSwitchObject sw : switches) {
+ for(IPortObject pt : sw.getPorts()) {
+ if(pt.equals(port)) {
+ sw.removePort(port);
+ }
+ }
+ }
+ portsToRemove.add((TestPortObject)port);
+ }
+
+ @Override
+ public IDeviceObject newDevice() {
+ TestDeviceObject dev = new TestDeviceObject();
+ devicesToAdd.add(dev);
+
+ return dev;
+ }
+
+ @Override
+ public IDeviceObject searchDevice(String macAddr) {
+ for(IDeviceObject dev : devices) {
+ if(dev.getMACAddress().equals(macAddr)) {
+ return dev;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IDeviceObject> getDevices() {
+ List<IDeviceObject> list = new ArrayList<IDeviceObject>();
+
+ for(TestDeviceObject dev : devices) {
+ list.add(dev);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeDevice(IDeviceObject dev) {
+ if(devices.contains((TestDeviceObject)dev)) {
+ devicesToRemove.add((TestDeviceObject)dev);
+ }
+ }
+
+ @Override
+ public IFlowPath newFlowPath() {
+ TestFlowPath path = new TestFlowPath();
+ pathsToAdd.add(path);
+
+ return path;
+ }
+
+ @Override
+ public IFlowPath searchFlowPath(FlowId flowId) {
+ for(IFlowPath path : paths) {
+ if(path.getFlowId().equals(flowId)) {
+ return path;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
+ for(IFlowPath path : paths) {
+ for(IFlowEntry entry : path.getFlowEntries()) {
+ if(entry.equals(flowEntry)) {
+ return path;
+ }
+ }
+
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IFlowPath> getAllFlowPaths() {
+ List<IFlowPath> list = new ArrayList<IFlowPath>();
+
+ for(IFlowPath path : paths) {
+ list.add(path);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeFlowPath(IFlowPath flowPath) {
+ if(paths.contains((TestFlowPath)flowPath)) {
+ pathsToRemove.add((TestFlowPath)flowPath);
+ }
+ }
+
+ @Override
+ public IFlowEntry newFlowEntry() {
+ TestFlowEntry entry = new TestFlowEntry();
+ entriesToAdd.add(entry);
+ return entry;
+ }
+
+ @Override
+ public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
+ for(TestFlowEntry entry : entries) {
+ // TODO check if this matching works
+ if(entry.getFlowEntryId().equals(flowEntryId)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IFlowEntry> getAllFlowEntries() {
+ List<IFlowEntry> list = new ArrayList<IFlowEntry>();
+
+ for(TestFlowEntry entry : entries) {
+ list.add(entry);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeFlowEntry(IFlowEntry flowEntry) {
+ if(entries.contains((TestFlowEntry)flowEntry)) {
+ entriesToRemove.add((TestFlowEntry)flowEntry);
+ }
+ }
+
+ @Override
+ public IDBConnection getDBConnection() {
+ return super.getDBConnection();
+ }
+
+ @Override
+ public void commit() {
+ for(TestSwitchObject sw : switchesToAdd) {
+ switches.add(sw);
+ }
+ for(TestSwitchObject sw : switchesToRemove) {
+ sw.commit();
+ switches.remove(sw);
+ }
+ for(TestSwitchObject sw : switches) {
+ sw.commit();
+ }
+
+ for(TestPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(TestPortObject port : portsToRemove) {
+ port.commit();
+ ports.remove(port);
+ }
+ for(TestPortObject port : ports) {
+ port.commit();
+ }
+
+ for(TestDeviceObject dev : devicesToAdd) {
+ devices.add(dev);
+ }
+ for(TestDeviceObject dev : devicesToRemove) {
+ dev.commit();
+ devices.remove(dev);
+ }
+ for(TestDeviceObject dev : devices) {
+ dev.commit();
+ }
+
+ clearUncommitedData();
+ }
+
+ @Override
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ @Override
+ public void close() {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
similarity index 87%
rename from src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java
rename to src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
index 223b8a1..2f90d48 100644
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
@@ -1,7 +1,9 @@
-package net.floodlightcontroller.linkdiscovery.internal;
+package net.onrc.onos.ofcontroller.core.internal;
import java.util.Set;
+import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
+
import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
import com.tinkerpop.blueprints.Vertex;
@@ -17,6 +19,7 @@
*/
public class TestableLinkStorageImpl extends LinkStorageImpl {
+ protected TitanGraph graph;
public TestableLinkStorageImpl(TitanGraph graph){
this.graph = graph;
diff --git a/src/test/java/net/floodlightcontroller/core/internal/TestableSwitchStorageImpl.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
similarity index 84%
rename from src/test/java/net/floodlightcontroller/core/internal/TestableSwitchStorageImpl.java
rename to src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
index 73d517f..e78a1b6 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/TestableSwitchStorageImpl.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
@@ -1,7 +1,9 @@
-package net.floodlightcontroller.core.internal;
+package net.onrc.onos.ofcontroller.core.internal;
import java.util.Set;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+
import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
diff --git a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
new file mode 100644
index 0000000..de8be4e
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
@@ -0,0 +1,837 @@
+package net.onrc.onos.ofcontroller.devicemanager.internal;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.devicemanager.IDevice;
+import net.floodlightcontroller.devicemanager.SwitchPort;
+import net.floodlightcontroller.packet.IPv4;
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.floodlightcontroller.devicemanager.internal.Device;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.util.HexString;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.thinkaurelius.titan.core.TitanFactory;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, DeviceStorageImpl.class})
+public class DeviceStorageImplTest{ //extends FloodlightTestCase{
+
+ protected static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ DeviceStorageImpl deviceImpl;
+ private GraphDBConnection mockConn;
+ private GraphDBOperation mockOpe;
+
+ @Before
+ public void setUp() throws Exception {
+ deviceImpl = new DeviceStorageImpl();
+ conf = "/dummy/path/to/db";
+
+ PowerMock.mockStatic(GraphDBConnection.class);
+ mockConn = createMock(GraphDBConnection.class);
+ PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
+ EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(mockConn);
+ PowerMock.replay(GraphDBConnection.class);
+
+ //PowerMock.mockStatic(GraphDBOperation.class);
+ mockOpe = PowerMock.createMock(GraphDBOperation.class);
+ PowerMock.expectNew(GraphDBOperation.class, new Class<?>[]{String.class}, conf).andReturn(mockOpe);
+ mockOpe.close();
+ PowerMock.replay(GraphDBOperation.class);
+ // Replace the conf to dummy conf
+ // String conf = "/tmp/cassandra.titan";
+
+
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ deviceImpl.close();
+ deviceImpl = null;
+
+ verify(mockOpe);
+ }
+
+ private String makeIPStringFromArray(Integer[] ipaddresses){
+ String multiIntString = "";
+ for(Integer intValue : ipaddresses)
+ {
+ if (multiIntString == null || multiIntString.isEmpty()){
+ multiIntString = "[" + IPv4.fromIPv4Address(intValue);
+ }
+ else{
+ multiIntString += "," + IPv4.fromIPv4Address(intValue);
+ }
+ }
+ return multiIntString + "]";
+ }
+
+
+ /**
+ * Desc:
+ * Test method for addDevice method.
+ * Codition:
+ * N/A
+ * Expect:
+ * Get proper IDeviceObject
+ */
+ //@Ignore
+ @Test
+ public void testAddNewDevice() {
+ try
+ {
+ //Make mockDevice
+ IDevice mockDev = createMock(Device.class);
+ // Mac addr for test device.
+ String macAddr = "99:99:99:99:99:99";
+ // IP addr for test device
+ String ip = "192.168.100.1";
+ Integer[] ipaddrs = {IPv4.toIPv4Address(ip)};
+ // Mac addr for attached switch
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ // Port number for attached switch
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ expect(mockDev.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs).anyTimes();
+ expect(mockDev.getAttachmentPoints()).andReturn(sps).anyTimes();
+ replay(mockDev);
+
+ //Mock IPortObject 1 with dpid "00:00:00:00:00:00:0a:01" and port "1"
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setNumber(portNum);
+ mockIPort.setType("port");
+ String iPortDesc = "port 1 at SEA Switch";
+ expect(mockIPort.getNumber()).andReturn(portNum).anyTimes();
+ expect(mockIPort.getDesc()).andReturn(iPortDesc).anyTimes();
+ replay(mockIPort);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList = new ArrayList<IPortObject>();
+ portList.add(mockIPort);
+
+ //Expectation for mockIDeviceObject
+ IDeviceObject mockIDev = createMock(IDeviceObject.class);
+ expect(mockIDev.getAttachedPorts()).andReturn(portList);
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ replay(mockIDev);
+
+ //Expectation for mockOpe
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ expect(mockOpe.newDevice()).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ replay(mockOpe);
+
+ deviceImpl.init(conf);
+
+ //Add the device
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ verify(mockIDev);
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for addDevice method.
+ * Condition:
+ * Already added device is existed.
+ * Expect:
+ * Get proper IDeviceObject still.
+ * Check the IDeviceObject properties set expectedly.
+ */
+ //@Ignore
+ @Test
+ public void testAddDeviceExisting() {
+ try
+ {
+ IDevice mockDev = createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer[] ipaddrs = {IPv4.toIPv4Address(ip)};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ expect(mockDev.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs).times(2);
+ expect(mockDev.getAttachmentPoints()).andReturn(sps).times(2);
+ replay(mockDev);
+
+ //Mock IPortObject 1 with dpid "00:00:00:00:00:00:0a:01" and port "1"
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setNumber(portNum);
+ mockIPort.setType("port");
+ String iPortDesc = "port 1 at SEA Switch";
+ expect(mockIPort.getNumber()).andReturn(portNum).anyTimes();
+ expect(mockIPort.getDesc()).andReturn(iPortDesc).anyTimes();
+ replay(mockIPort);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList = new ArrayList<IPortObject>();
+ portList.add(mockIPort);
+
+ //Expectation for mockIDeviceObject
+ IDeviceObject mockIDev = createMock(IDeviceObject.class);
+ expect(mockIDev.getAttachedPorts()).andReturn(portList).anyTimes();
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ replay(mockIDev);
+
+ //Expectation for mockOpe
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ expect(mockOpe.newDevice()).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.searchDevice(macAddr)).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ replay(mockOpe);
+
+ deviceImpl.init(conf);
+
+ //Add the device
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ //Add the same device
+ IDeviceObject obj2 = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj2);
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for updateDevice method.
+ * Condition:
+ * The mac address and attachment point are the same.
+ * All of the other parameter are different.
+ * Expect:
+ * Changed parameters are set expectedly.
+ */
+ //@Ignore
+ @Test
+ public void testUpdateDevice() {
+ try
+ {
+ IDevice mockDev = createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ expect(mockDev.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ replay(mockDev);
+
+ //Dev2 (attached port is the same)
+ IDevice mockDev2 = createMock(Device.class);
+ String ip2 = "192.168.100.2";
+ Integer ipInt2 = IPv4.toIPv4Address(ip2);
+ Integer[] ipaddrs2 = {ipInt2};
+
+ expect(mockDev2.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
+ expect(mockDev2.getAttachmentPoints()).andReturn(sps);
+ replay(mockDev2);
+
+ //Mock IPortObject 1 with dpid "00:00:00:00:00:00:0a:01" and port "1"
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setNumber(portNum);
+ mockIPort.setType("port");
+ String iPortDesc = "port 1 at SEA Switch";
+ expect(mockIPort.getNumber()).andReturn(portNum).anyTimes();
+ expect(mockIPort.getDesc()).andReturn(iPortDesc).anyTimes();
+ replay(mockIPort);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList = new ArrayList<IPortObject>();
+ portList.add(mockIPort);
+
+ //Expectation for mockIDeviceObject
+ IDeviceObject mockIDev = createMock(IDeviceObject.class);
+ expect(mockIDev.getAttachedPorts()).andReturn(portList).anyTimes();
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs2));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ replay(mockIDev);
+
+ //Expectation for mockOpe
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ expect(mockOpe.newDevice()).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.searchDevice(macAddr)).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ replay(mockOpe);
+
+ deviceImpl.init(conf);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ //update theDevice
+ IDeviceObject obj2 = deviceImpl.updateDevice(mockDev2);
+ assertNotNull(obj2);
+
+ verify(mockIDev);
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for testRemoveDevice method.
+ * Condition:
+ * 1. Unregistered IDeviceObject argument is put.
+ * Expect:
+ * 1. Nothing happen when unregistered IDeviceObject is put
+ * 2. IDeviceObject will be removed.
+ */
+ //@Ignore
+ @Test
+ public void testRemoveDevice() {
+ try
+ {
+ IDevice mockDev = createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ expect(mockDev.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ replay(mockDev);
+
+ //Dev2 (attached port is the same)
+ IDevice mockDev2 = createMock(Device.class);
+ String macAddr2 = "33:33:33:33:33:33";
+ expect(mockDev2.getMACAddressString()).andReturn(macAddr2).anyTimes();
+ expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs);
+ expect(mockDev2.getAttachmentPoints()).andReturn(sps);
+ replay(mockDev2);
+
+ //Mock IPortObject 1 with dpid "00:00:00:00:00:00:0a:01" and port "1"
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setNumber(portNum);
+ mockIPort.setType("port");
+ String iPortDesc = "port 1 at SEA Switch";
+ expect(mockIPort.getNumber()).andReturn(portNum).anyTimes();
+ expect(mockIPort.getDesc()).andReturn(iPortDesc).anyTimes();
+ replay(mockIPort);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList = new ArrayList<IPortObject>();
+ portList.add(mockIPort);
+
+ //Expectation for mockIDeviceObject
+ IDeviceObject mockIDev = createMock(IDeviceObject.class);
+ expect(mockIDev.getAttachedPorts()).andReturn(portList);
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ replay(mockIDev);
+
+ //Expectation for mockOpe
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ expect(mockOpe.newDevice()).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.searchDevice(macAddr2)).andReturn(null);
+ expect(mockOpe.searchDevice(macAddr)).andReturn(mockIDev);
+ expect(mockOpe.searchDevice(macAddr)).andReturn(mockIDev);
+ mockOpe.removeDevice(mockIDev);
+ mockOpe.commit();
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ replay(mockOpe);
+
+ deviceImpl.init(conf);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ deviceImpl.removeDevice(mockDev2);
+ IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
+ assertNotNull(dev);
+
+ deviceImpl.removeDevice(mockDev);
+ IDeviceObject dev2 = deviceImpl.getDeviceByMac(macAddr);
+ assertNull(dev2);
+
+ verify(mockIDev);
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for getDeviceByMac
+ * Condition:
+ * 1. Unregistered mac address argument is set
+ * Expect:
+ * 1.Nothing happen when you put unregistered mac address
+ * 2.Get the proper IDeviceObject.
+ * 3.Check the IDeviceObject properties set expectedly.
+ */
+ //@Ignore
+ @Test
+ public void testGetDeviceByMac() {
+ try
+ {
+ IDevice mockDev = createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ String dummyMac = "33:33:33:33:33:33";
+
+ expect(mockDev.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ replay(mockDev);
+
+ //Mock IPortObject 1 with dpid "00:00:00:00:00:00:0a:01" and port "1"
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setNumber(portNum);
+ mockIPort.setType("port");
+ String iPortDesc = "port 1 at SEA Switch";
+ expect(mockIPort.getNumber()).andReturn(portNum).anyTimes();
+ expect(mockIPort.getDesc()).andReturn(iPortDesc).anyTimes();
+ replay(mockIPort);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList = new ArrayList<IPortObject>();
+ portList.add(mockIPort);
+
+ //Expectation for mockIDeviceObject
+ IDeviceObject mockIDev = createMock(IDeviceObject.class);
+ expect(mockIDev.getAttachedPorts()).andReturn(portList);
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ replay(mockIDev);
+
+ //Expectation for mockOpe
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ expect(mockOpe.newDevice()).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.searchDevice(dummyMac)).andReturn(null);
+ expect(mockOpe.searchDevice(macAddr)).andReturn(mockIDev);
+ replay(mockOpe);
+
+ deviceImpl.init(conf);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ IDeviceObject dummyDev = deviceImpl.getDeviceByMac(dummyMac);
+ assertNull(dummyDev);
+
+ IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
+ assertNotNull(dev);
+
+ verify(mockIDev);
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for getDeviceByIP method.
+ * Condition:
+ * 1. Unregistered ip address argument is set
+ * Expect:
+ * 1. Nothing happen when you put unregistered mac address
+ * 2. Get the proper IDeviceObject.
+ * 3. Check the IDeviceObject properties set expectedly.
+ */
+ //@Ignore
+ @Test
+ public void testGetDeviceByIP() {
+ try
+ {
+ IDevice mockDev = createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ String ip2 = "192.168.100.2";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer ipInt2 = IPv4.toIPv4Address(ip2);
+ Integer[] ipaddrs = {ipInt, ipInt2};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ String dummyIP = "222.222.222.222";
+
+ expect(mockDev.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ replay(mockDev);
+
+ //Mock IPortObject 1 with dpid "00:00:00:00:00:00:0a:01" and port "1"
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setNumber(portNum);
+ mockIPort.setType("port");
+ String iPortDesc = "port 1 at SEA Switch";
+ expect(mockIPort.getNumber()).andReturn(portNum).anyTimes();
+ expect(mockIPort.getDesc()).andReturn(iPortDesc).anyTimes();
+ replay(mockIPort);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList = new ArrayList<IPortObject>();
+ portList.add(mockIPort);
+
+ //Expectation for mockIDeviceObject
+ IDeviceObject mockIDev = createMock(IDeviceObject.class);
+ expect(mockIDev.getAttachedPorts()).andReturn(portList);
+ expect(mockIDev.getIPAddress()).andReturn(makeIPStringFromArray(ipaddrs)).times(2);
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ replay(mockIDev);
+
+
+ //Make mock Iterator for IDeviceObject
+ List<IDeviceObject> deviceList = new ArrayList<IDeviceObject>();
+ deviceList.add(mockIDev);
+
+ //Expectation for mockOpe
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ expect(mockOpe.newDevice()).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.getDevices()).andReturn(deviceList).times(2);
+ replay(mockOpe);
+
+ deviceImpl.init(conf);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ IDeviceObject dummyDev = deviceImpl.getDeviceByIP(dummyIP);
+ assertNull(dummyDev);
+
+ IDeviceObject dev = deviceImpl.getDeviceByIP(ip);
+ assertNotNull(dev);
+
+ verify(mockIDev);
+
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for testChangeDeviceAttachmentsIDevice
+ * Condition:
+ * 1. Unexisting attachment point argument is set
+ * Expect:
+ * 1. Nothing happen when you put unexisting attachment point.
+ * 2. Set the attachment point expectedly;
+ */
+ //@Ignore
+ @Test
+ public void testChangeDeviceAttachmentsIDevice() {
+ try
+ {
+ IDevice mockDev = createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ expect(mockDev.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ replay(mockDev);
+
+ //Dev2
+ IDevice mockDev2 = createMock(Device.class);
+ String switchMacAddr2 = "00:00:00:00:00:00:0a:02";
+ long lSwitchMacAddr2 = HexString.toLong(switchMacAddr2);
+ short portNum2 = 2;
+ SwitchPort sp2 = new SwitchPort(lSwitchMacAddr2, portNum2);
+ SwitchPort sps2[] = {sp2};
+
+ expect(mockDev2.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs);
+ expect(mockDev2.getAttachmentPoints()).andReturn(sps2);
+ replay(mockDev2);
+
+ //Dev3
+ IDevice mockDev3 = createMock(Device.class);
+ String switchMacAddr3 = "00:00:00:00:00:00:00:00";
+ long lSwitchMacAddr3 = HexString.toLong(switchMacAddr3);
+ short portNum3 = 1;
+ SwitchPort sp3 = new SwitchPort(lSwitchMacAddr3, portNum3);
+ SwitchPort sps3[] = {sp3};
+
+ expect(mockDev3.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev3.getIPv4Addresses()).andReturn(ipaddrs);
+ expect(mockDev3.getAttachmentPoints()).andReturn(sps3);
+ replay(mockDev3);
+
+ IDeviceObject mockIDev = createMock(IDeviceObject.class);
+
+ //Mock IPortObject 1 with dpid "00:00:00:00:00:00:0a:01" and port "1"
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setNumber(portNum);
+ mockIPort.setType("port");
+ String iPortDesc = "port 1 at SEA Switch";
+ expect(mockIPort.getNumber()).andReturn(portNum).anyTimes();
+ expect(mockIPort.getDesc()).andReturn(iPortDesc).anyTimes();
+ mockIPort.removeDevice(mockIDev);
+ mockIPort.removeDevice(mockIDev);
+ replay(mockIPort);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList = new ArrayList<IPortObject>();
+ portList.add(mockIPort);
+
+ //Expectation for mockIDeviceObject
+ expect(mockIDev.getAttachedPorts()).andReturn(portList).anyTimes();
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ replay(mockIDev);
+
+ //Mock IPortObject 2 with dpid "00:00:00:00:00:00:0a:02" and port "2"
+ IPortObject mockIPort2 = createMock(IPortObject.class);
+ mockIPort2.setNumber(portNum2);
+ mockIPort2.setType("port");
+ String iPortDesc2 = "port 2 at LAX Switch";
+ expect(mockIPort2.getNumber()).andReturn(portNum2).anyTimes();
+ expect(mockIPort2.getDesc()).andReturn(iPortDesc2).anyTimes();
+ mockIPort2.setDevice(mockIDev);
+ replay(mockIPort2);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList2 = new ArrayList<IPortObject>();
+ portList2.add(mockIPort2);
+
+ //Mock IPortObject 3 with dpid "00:00:00:00:00:00:00:00" and port "1"
+ IPortObject mockIPort3 = createMock(IPortObject.class);
+ mockIPort3.setNumber(portNum3);
+ mockIPort3.setType("port");
+ String iPortDesc3 = "n/a";
+ expect(mockIPort3.getNumber()).andReturn(portNum3).anyTimes();
+ expect(mockIPort3.getDesc()).andReturn(iPortDesc3).anyTimes();
+ mockIPort3.setDevice(mockIDev);
+ replay(mockIPort3);
+
+ //Expectation for mockOpe
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ expect(mockOpe.newDevice()).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.searchDevice(macAddr)).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr2, portNum2)).andReturn(mockIPort2);
+ mockOpe.commit();
+ expect(mockOpe.searchDevice(macAddr)).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr3, portNum3)).andReturn(null);
+ mockOpe.commit();
+ replay(mockOpe);
+
+ deviceImpl.init(conf);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ deviceImpl.changeDeviceAttachments(mockDev2);
+
+ deviceImpl.changeDeviceAttachments(mockDev3);
+
+ verify(mockIDev);
+
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Ignore
+ @Test
+ public void testChangeDeviceAttachmentsIDeviceIDeviceObject() {
+ //It is tested by the testChangeDeviceAttachmentsIDevice
+ }
+
+ /**
+ * Desc:
+ * Test method for testChangeDeviceIPv4Address
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Set the ipadress expectedly.
+ */
+ //@Ignore
+ @Test
+ public void testChangeDeviceIPv4Address() {
+ try
+ {
+ //Dev1
+ IDevice mockDev = createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ expect(mockDev.getMACAddressString()).andReturn(macAddr).anyTimes();
+ expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ replay(mockDev);
+
+ //Dev2
+ IDevice mockDev2 = createMock(Device.class);
+ String ip2 = "192.168.100.2";
+ Integer ipInt2 = IPv4.toIPv4Address(ip2);
+ Integer[] ipaddrs2 = {ipInt2};
+ expect(mockDev2.getMACAddressString()).andReturn(macAddr);
+ expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
+ replay(mockDev2);
+
+ //Mock IPortObject 1 with dpid "00:00:00:00:00:00:0a:01" and port "1"
+ IPortObject mockIPort = createMock(IPortObject.class);
+ mockIPort.setNumber(portNum);
+ mockIPort.setType("port");
+ String iPortDesc = "port 1 at SEA Switch";
+ expect(mockIPort.getNumber()).andReturn(portNum).anyTimes();
+ expect(mockIPort.getDesc()).andReturn(iPortDesc).anyTimes();
+ replay(mockIPort);
+
+ //Make Iterator for mockIport
+ List<IPortObject> portList = new ArrayList<IPortObject>();
+ portList.add(mockIPort);
+
+ //Expectation for mockIDeviceObject
+ IDeviceObject mockIDev = createMock(IDeviceObject.class);
+ expect(mockIDev.getAttachedPorts()).andReturn(portList);
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs));
+ mockIDev.setMACAddress(macAddr);
+ mockIDev.setType("device");
+ mockIDev.setState("ACTIVE");
+ mockIDev.setIPAddress(makeIPStringFromArray(ipaddrs2));
+ replay(mockIDev);
+
+ //Expectation for mockOpe
+ expect(mockOpe.searchDevice(macAddr)).andReturn(null);
+ expect(mockOpe.newDevice()).andReturn(mockIDev);
+ expect(mockOpe.searchPort(switchMacAddr, portNum)).andReturn(mockIPort);
+ mockOpe.commit();
+ expect(mockOpe.searchDevice(macAddr)).andReturn(mockIDev);
+ mockOpe.commit();
+ replay(mockOpe);
+
+ deviceImpl.init(conf);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ deviceImpl.changeDeviceIPv4Address(mockDev2);
+
+ verify(mockIDev);
+
+
+ }
+ catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
new file mode 100644
index 0000000..e4053f4
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
@@ -0,0 +1,626 @@
+package net.onrc.onos.ofcontroller.devicemanager.internal;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.floodlightcontroller.core.internal.TestDatabaseManager;
+import net.floodlightcontroller.devicemanager.IDevice;
+import net.floodlightcontroller.devicemanager.SwitchPort;
+import net.floodlightcontroller.devicemanager.internal.Device;
+import net.floodlightcontroller.packet.IPv4;
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.util.HexString;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class DeviceStorageImplTestBB {
+ protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ String conf;
+ private GraphDBConnection conn = null;
+ private GraphDBOperation ope = null;
+ private TitanGraph titanGraph = null;
+ IDeviceStorage deviceImpl = null;
+
+ @Before
+ public void setUp() throws Exception {
+
+ deviceImpl = new DeviceStorageImpl();
+ conf = "/dummy/path/to/db";
+
+ // Make mock cassandra DB
+ // Replace TitanFactory.open() to return mock DB
+ titanGraph = TestDatabaseManager.getTestDatabase();
+ TestDatabaseManager.populateTestData(titanGraph);
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
+
+ conn = GraphDBConnection.getInstance(conf);
+ ope = new GraphDBOperation(conn);
+
+ deviceImpl.init(conf);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
+
+ deviceImpl.close();
+ deviceImpl = null;
+ }
+
+ /**
+ * Desc:
+ * Test method for addDevice method.
+ * Codition:
+ * N/A
+ * Expect:
+ * Get proper IDeviceObject
+ * Check the IDeviceObject properties set
+ */
+ @Test
+ public void testAddDevice() {
+ try
+ {
+ //Make mockDevice
+ IDevice mockDev = EasyMock.createMock(Device.class);
+ // Mac addr for test device.
+ String macAddr = "99:99:99:99:99:99";
+ // IP addr for test device
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ // Mac addr for attached switch
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ // Port number for attached switch
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+
+ EasyMock.replay(mockDev);
+
+ //Add the device
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ //Test to take a Device from DB correctly
+ IDeviceObject devObj1 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, devObj1.getMACAddress());
+
+ //Test to take a attached sw from DB correctly
+ for(ISwitchObject sw1: devObj1.getSwitch())
+ {
+ String swMacFromDB = sw1.getDPID();
+ assertEquals(switchMacAddr, swMacFromDB);
+ }
+
+ //Test to take a IP addr from DB
+ //TodoForGettingIPaddr. There may be bug in the test class.
+ String ipFromDB = devObj1.getIPAddress();
+ String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
+ List<String> ipsList = Arrays.asList(ipsFromDB);
+ assertTrue(ipsList.contains(ip));
+
+ //Test to take a attached port from DB
+ for(IPortObject port : devObj1.getAttachedPorts())
+ {
+
+ //In this implementing, the object was not set the port. So it must be null.
+ if(port.getNumber() != null)
+ {
+ String portNumFromDB = port.getNumber().toString();
+ assertEquals(String.valueOf(portNum), portNumFromDB);
+ }
+ }
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for addDevice method.
+ * Condition:
+ * Already added device is existed.
+ * Expect:
+ * Get proper IDeviceObject still.
+ * Check the IDeviceObject properties set.
+ */
+ @Test
+ public void testAddDeviceExisting() {
+ try
+ {
+ IDevice mockDev = EasyMock.createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.replay(mockDev);
+
+ //Add the device
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ //Test to take a Device from DB correctly
+ IDeviceObject devObj1 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, devObj1.getMACAddress());
+
+ //Add the same device
+ IDeviceObject obj2 = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj2);
+
+ IDeviceObject devObj2 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, devObj2.getMACAddress());
+
+ //Test to take a attached port from DB
+ for(IPortObject port : devObj2.getAttachedPorts())
+ {
+ //In this implementing, the object was not set the port. So it must be null.
+ if(port.getNumber() != null)
+ {
+
+ String portNumFromDB = port.getNumber().toString();
+ assertEquals(String.valueOf(portNum), portNumFromDB);
+
+ ISwitchObject sw = port.getSwitch();
+ String str = sw.getDPID();
+ log.debug("");
+ }
+ }
+
+ String ipFromDB = devObj2.getIPAddress();
+ String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
+ List<String> ipsList = Arrays.asList(ipsFromDB);
+ assertTrue(ipsList.contains(ip));
+
+ //Test to take a attached port from DB
+ for(IPortObject port : devObj2.getAttachedPorts())
+ {
+
+ //In this implementing, the object was not set the port. So it must be null.
+ if(port.getNumber() != null)
+ {
+ String portNumFromDB = port.getNumber().toString();
+ assertEquals(String.valueOf(portNum), portNumFromDB);
+ }
+ }
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+ /**
+ * Desc:
+ * Test method for updateDevice method.
+ * Condition:
+ * The mac address and attachment point are the same.
+ * All of the other parameter are different.
+ * Expect:
+ * Changed parameters are set properly.
+ */
+ //@Ignore
+ @Test
+ public void testUpdateDevice() {
+ try
+ {
+ IDevice mockDev = EasyMock.createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.replay(mockDev);
+
+ //Dev2 (attached port is the same)
+ IDevice mockDev2 = EasyMock.createMock(Device.class);
+ String macAddr2 = "99:aa:aa:aa:aa:aa";
+ Integer ip2 = IPv4.toIPv4Address("192.168.100.2");
+ Integer[] ipaddrs2 = {ip2};
+
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
+ EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
+ EasyMock.expect(mockDev2.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
+ EasyMock.replay(mockDev2);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ IDeviceObject dev1 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, dev1.getMACAddress());
+
+ //update theDevice
+ deviceImpl.updateDevice(mockDev2);
+ IDeviceObject dev2 = ope.searchDevice(macAddr2);
+ assertEquals(macAddr2, dev2.getMACAddress());
+ IPortObject iport = ope.searchPort(switchMacAddr, portNum);
+
+ //Test to take a attached port from DB
+ for(IDeviceObject dev : iport.getDevices())
+ {
+ String macAddrFromDB = dev.getMACAddress();
+ if(macAddr2.equals(macAddrFromDB)){
+ //Nothing to do
+ }
+ else{
+ fail("notFoundTheDeviceOnThePort");
+ }
+ }
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for testRemoveDevice method.
+ * Condition:
+ * 1. Unregistered IDeviceObject argument is put.
+ * Expect:
+ * 1. Nothing happen when unregistered IDeviceObject is put
+ * 2. IDeviceObject will be removed.
+ */
+ //@Ignore
+ @Test
+ public void testRemoveDevice() {
+ try
+ {
+ IDevice mockDev = EasyMock.createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.replay(mockDev);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ IDeviceObject dev1 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, dev1.getMACAddress());
+
+ deviceImpl.removeDevice(mockDev);
+ IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
+ assertNull(dev);
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for getDeviceByMac
+ * Condition:
+ * 1. Unregistered mac address argument is set
+ * Expect:
+ * 1.Nothing happen when you put unregistered mac address
+ * 2.Get the proper IDeviceObject.
+ * 3.Check the IDeviceObject properties set.
+ */
+ //@Ignore
+ @Test
+ public void testGetDeviceByMac() {
+ try
+ {
+ IDevice mockDev = EasyMock.createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.replay(mockDev);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ IDeviceObject dev1 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, dev1.getMACAddress());
+
+ IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
+ assertNotNull(dev);
+ assertEquals(macAddr, dev.getMACAddress());
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for getDeviceByIP method.
+ * Condition:
+ * 1. Unregistered ip address argument is set
+ * Expect:
+ * 1. Nothing happen when you put unregistered mac address
+ * 2. Get the proper IDeviceObject.
+ * 3. Check the IDeviceObject properties set.
+ */
+ //@Ignore
+ @Test
+ public void testGetDeviceByIP() {
+ try
+ {
+ IDevice mockDev = EasyMock.createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.replay(mockDev);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ IDeviceObject dev1 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, dev1.getMACAddress());
+
+ IDeviceObject dev = deviceImpl.getDeviceByIP(ip);
+ assertNotNull(dev);
+ String ipFromDB = dev.getIPAddress();
+ String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
+ List<String> ipsList = Arrays.asList(ipsFromDB);
+ assertTrue(ipsList.contains(ip));
+
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Desc:
+ * Test method for testChangeDeviceAttachmentsIDevice
+ * Condition:
+ * 1. Unexisting attachment point argument is set
+ * Expect:
+ * 1. Unexisting attachment point is ignored, so nothing happen.
+ * 2. Change the attachment point.
+ */
+ //@Ignore
+ @Test
+ public void testChangeDeviceAttachmentsIDevice() {
+ try
+ {
+ IDevice mockDev = EasyMock.createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.replay(mockDev);
+
+ //Dev2
+ IDevice mockDev2 = EasyMock.createMock(Device.class);
+ String switchMacAddr2 = "00:00:00:00:00:00:0a:02";
+ long lSwitchMacAddr2 = HexString.toLong(switchMacAddr2);
+ short portNum2 = 2;
+ SwitchPort sp2 = new SwitchPort(lSwitchMacAddr2, portNum2);
+ SwitchPort sps2[] = {sp2};
+
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev2.getAttachmentPoints()).andReturn(sps2);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
+ EasyMock.replay(mockDev2);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ deviceImpl.changeDeviceAttachments(mockDev2);
+
+ IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
+ assertNotNull(dev);
+
+ for(ISwitchObject sw1: dev.getSwitch())
+ {
+ String swMacFromDB = sw1.getDPID();
+ assertEquals(switchMacAddr2, swMacFromDB);
+ }
+ } catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ //@Ignore
+ @Test
+ public void testChangeDeviceAttachmentsIDeviceIDeviceObject() {
+ //It is tested by the testChangeDeviceAttachmentsIDevice
+ }
+
+ /**
+ * Desc:
+ * Test method for testChangeDeviceIPv4Address
+ * Condition:
+ * N/A
+ * Expect:
+ * 1. Check correctly changed the ipadress
+ */
+ //@Ignore
+ @Test
+ public void testChangeDeviceIPv4Address() {
+ try
+ {
+ //Dev1
+ IDevice mockDev = EasyMock.createMock(Device.class);
+ String macAddr = "99:99:99:99:99:99";
+ String ip = "192.168.100.1";
+ Integer ipInt = IPv4.toIPv4Address(ip);
+ Integer[] ipaddrs = {ipInt};
+ String switchMacAddr = "00:00:00:00:00:00:0a:01";
+ long switchMacAddrL = HexString.toLong(switchMacAddr);
+ short portNum = 2;
+ SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
+ SwitchPort[] sps = {sp1};
+
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
+ EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
+ EasyMock.replay(mockDev);
+
+ IDeviceObject obj = deviceImpl.addDevice(mockDev);
+ assertNotNull(obj);
+
+ IDevice mockDev2 = EasyMock.createMock(Device.class);
+ String ip2 = "192.168.100.2";
+ Integer ipInt2 = IPv4.toIPv4Address(ip2);
+ Integer[] ipaddrs2 = {ipInt2};
+ EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
+ EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
+ EasyMock.replay(mockDev2);
+
+ IDeviceObject dev1 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, dev1.getMACAddress());
+ String ipFromDB = dev1.getIPAddress();
+ String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
+ List<String> ipsList = Arrays.asList(ipsFromDB);
+ assertTrue(ipsList.contains(ip));
+
+ deviceImpl.changeDeviceIPv4Address(mockDev2);
+
+ IDeviceObject dev2 = ope.searchDevice(macAddr);
+ assertEquals(macAddr, dev2.getMACAddress());
+ String ipFromDB2 = dev2.getIPAddress();
+ String[] ipsFromDB2 = ipFromDB2.replace("[", "").replace("]", "").split(",");
+ List<String> ipsList2 = Arrays.asList(ipsFromDB2);
+ assertTrue(ipsList2.contains(ip2));
+ }
+ catch(Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
new file mode 100644
index 0000000..7bc0aac
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
@@ -0,0 +1,1224 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.cmpEq;
+import static org.powermock.api.easymock.PowerMock.*;
+
+import java.util.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.ofcontroller.util.*;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.factory.BasicFactory;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * @author Toshio Koide
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({FlowManager.class, GraphDBOperation.class, System.class, Executors.class})
+public class FlowManagerTest {
+ private static FloodlightModuleContext context;
+ private static IFloodlightProviderService floodlightProvider;
+ private static TopoRouteService topoRouteService;
+ private static IRestApiService restApi;
+ private static GraphDBOperation op;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ private void expectInitWithContext() throws Exception {
+ // create mock objects
+ context = createMock(FloodlightModuleContext.class);
+ floodlightProvider = createMock(IFloodlightProviderService.class);
+ topoRouteService = createMock(TopoRouteService.class);
+ restApi = createMock(IRestApiService.class);
+ op = createMock(GraphDBOperation.class);
+
+ // setup expectations
+ expect(context.getServiceImpl(IFloodlightProviderService.class)).andReturn(floodlightProvider);
+ expect(context.getServiceImpl(IRestApiService.class)).andReturn(restApi);
+ expectNew(GraphDBOperation.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(op);
+ expectNew(TopoRouteService.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(topoRouteService);
+ }
+
+ private IFlowPath createIFlowPathMock(long flowId, String installerID,
+ long flowPathFlags,
+ long srcDpid, int srcPort, long dstDpid, int dstPort) {
+ IFlowPath iFlowPath = createNiceMock(IFlowPath.class);
+ expect(iFlowPath.getFlowId()).andReturn(new FlowId(flowId).toString()).anyTimes();
+ expect(iFlowPath.getInstallerId()).andReturn(installerID).anyTimes();
+ expect(iFlowPath.getFlowPathFlags()).andReturn(new Long(flowPathFlags)).anyTimes();
+ expect(iFlowPath.getSrcSwitch()).andReturn(new Dpid(srcDpid).toString()).anyTimes();
+ expect(iFlowPath.getSrcPort()).andReturn(new Short((short)srcPort)).anyTimes();
+ expect(iFlowPath.getDstSwitch()).andReturn(new Dpid(dstDpid).toString()).anyTimes();
+ expect(iFlowPath.getDstPort()).andReturn(new Short((short)dstPort)).anyTimes();
+ return iFlowPath;
+ }
+
+ private FlowPath createTestFlowPath(long flowId, String installerId,
+ final long flowPathFlags,
+ final long srcDpid, final int srcPort,
+ final long dstDpid, final int dstPort
+ ) {
+ FlowPath flowPath = new FlowPath();
+ flowPath.setFlowId(new FlowId(flowId));
+ flowPath.setInstallerId(new CallerId(installerId));
+ flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
+ flowPath.setDataPath(new DataPath() {{
+ setSrcPort(new SwitchPort(new Dpid(srcDpid), new Port((short)srcPort)));
+ setDstPort(new SwitchPort(new Dpid(dstDpid), new Port((short)dstPort)));
+ }});
+ flowPath.setFlowEntryMatch(new FlowEntryMatch());
+ return flowPath;
+ }
+
+ private ArrayList<FlowPath> createTestFlowPaths() {
+ FlowPath flowPath1 = createTestFlowPath(1, "foo caller id", 0, 1, 1, 2, 2);
+ FlowPath flowPath2 = createTestFlowPath(2, "caller id", 0, 1, 1, 2, 2);
+ FlowPath flowPath3 = createTestFlowPath(3, "caller id", 0, 1, 5, 2, 2);
+
+ ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+ flowPaths.add(flowPath1);
+ flowPaths.add(flowPath2);
+ flowPaths.add(flowPath3);
+
+ return flowPaths;
+ }
+
+
+ // IFlowService methods
+
+
+ /**
+ * Test method for {@link FlowManager#addFlow(FlowPath, FlowId, String)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testAddFlowFailGraphCreatesNoFlow() throws Exception {
+ // instantiate required objects
+ FlowId flowId = new FlowId(123);
+ FlowPath flowPath = new FlowPath();
+ flowPath.setFlowId(flowId);
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+ expect(op.searchFlowPath(flowId)).andReturn(null);
+ expect(op.newFlowPath()).andReturn(null);
+ op.rollback();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Boolean result = fm.addFlow(flowPath, flowId, "");
+
+ // verify the test
+ verifyAll();
+ assertFalse(result);
+ }
+
+ /**
+ * Test method for {@link FlowManager#addFlow(FlowPath, FlowId, String)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testAddFlowSuccessNormally() throws Exception {
+ final String addFlowEntry = "addFlowEntry";
+ // create mock objects
+ IFlowPath createdFlowPath = createNiceMock(IFlowPath.class);
+ IFlowEntry createdFlowEntry1 = createNiceMock(IFlowEntry.class);
+ IFlowEntry createdFlowEntry2 = createNiceMock(IFlowEntry.class);
+ FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlowEntry);
+
+ // instantiate required objects
+ final FlowEntry flowEntry1 = new FlowEntry();
+ final FlowEntry flowEntry2 = new FlowEntry();
+ ArrayList<FlowEntry> flowEntries = new ArrayList<FlowEntry>();
+ flowEntries.add(flowEntry1);
+ flowEntries.add(flowEntry2);
+
+ DataPath dataPath = new DataPath();
+ dataPath.setSrcPort(new SwitchPort(new Dpid(0x1234), new Port((short)1)));
+ dataPath.setDstPort(new SwitchPort(new Dpid(0x5678), new Port((short)2)));
+ dataPath.setFlowEntries(flowEntries);
+
+ FlowEntryMatch match = new FlowEntryMatch();
+
+ FlowPath flowPath = new FlowPath();
+ flowPath.setFlowId(new FlowId(0x100));
+ flowPath.setInstallerId(new CallerId("installer id"));
+ flowPath.setFlowPathFlags(new FlowPathFlags(0));
+ flowPath.setDataPath(dataPath);
+ flowPath.setFlowEntryMatch(match);
+
+ // setup expectations
+ expectInitWithContext();
+ expect(op.searchFlowPath(cmpEq(new FlowId(0x100)))).andReturn(null);
+ expect(op.newFlowPath()).andReturn(createdFlowPath);
+ createdFlowPath.setFlowId("0x100");
+ createdFlowPath.setType("flow");
+ createdFlowPath.setInstallerId("installer id");
+ createdFlowPath.setFlowPathFlags(new Long((long)0));
+ createdFlowPath.setSrcSwitch("00:00:00:00:00:00:12:34");
+ createdFlowPath.setSrcPort(new Short((short)1));
+ createdFlowPath.setDstSwitch("00:00:00:00:00:00:56:78");
+ createdFlowPath.setDstPort(new Short((short)2));
+ createdFlowPath.setDataPathSummary("data path summary");
+ createdFlowPath.setUserState("FE_USER_ADD");
+
+ expectPrivate(fm, addFlowEntry, createdFlowPath, flowEntry1)
+ .andReturn(createdFlowEntry1);
+ expectPrivate(fm, addFlowEntry, createdFlowPath, flowEntry2)
+ .andReturn(createdFlowEntry2);
+
+ op.commit();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Boolean result = fm.addFlow(flowPath, new FlowId(0x100), "data path summary");
+
+ // verify the test
+ verifyAll();
+ assertTrue(result);
+ }
+
+ /**
+ * Test method for {@link FlowManager#deleteAllFlows()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testDeleteAllFlowsSuccessNormally() throws Exception {
+ // create mock objects
+ IFlowPath flowPath1 = createNiceMock(IFlowPath.class);
+ IFlowPath flowPath2 = createNiceMock(IFlowPath.class);
+
+ // instantiate required objects
+ ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+ flowPaths.add(flowPath1);
+ flowPaths.add(flowPath2);
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+ expect(op.getAllFlowPaths()).andReturn(flowPaths);
+
+ expect(flowPath1.getFlowId()).andReturn("1").anyTimes();
+ expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(flowPath1);
+ expect(flowPath1.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>());
+ op.removeFlowPath(flowPath1);
+
+ expect(flowPath2.getFlowId()).andReturn("2").anyTimes();
+ expect(op.searchFlowPath(cmpEq(new FlowId(2)))).andReturn(flowPath2);
+ expect(flowPath2.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>());
+ op.removeFlowPath(flowPath2);
+
+ op.commit();
+ expectLastCall().anyTimes();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Boolean result = fm.deleteAllFlows();
+
+ // verify the test
+ verifyAll();
+ assertTrue(result);
+ }
+
+ /**
+ * Test method for {@link FlowManager#deleteFlow(FlowId)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testDeleteFlowSuccessEmptyFlowPath() throws Exception {
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ // create mock objects
+ IFlowPath flowObj = createNiceMock(IFlowPath.class);
+
+ // setup expectations
+ expectInitWithContext();
+ expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(flowObj);
+ expect(flowObj.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>());
+ op.removeFlowPath(flowObj);
+ op.commit();
+ expectLastCall().anyTimes();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Boolean result = fm.deleteFlow(new FlowId(1));
+
+ // verify the test
+ verifyAll();
+ assertTrue(result);
+ }
+
+ /**
+ * Test method for {@link FlowManager#clearAllFlows()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testClearAllFlowsSuccessNormally() throws Exception {
+ // create mock objects
+ IFlowPath flowPath1 = createNiceMock(IFlowPath.class);
+ IFlowPath flowPath2 = createNiceMock(IFlowPath.class);
+ IFlowPath flowPath3 = createNiceMock(IFlowPath.class);
+ FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, "clearFlow");
+
+ // instantiate required objects
+ ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+ flowPaths.add(flowPath1);
+ flowPaths.add(flowPath2);
+ flowPaths.add(null);
+ flowPaths.add(flowPath3);
+
+ // setup expectations
+ expectInitWithContext();
+ expect(op.getAllFlowPaths()).andReturn(flowPaths);
+ expect(flowPath1.getFlowId()).andReturn(new FlowId(1).toString());
+ expect(flowPath2.getFlowId()).andReturn(null);
+ expect(flowPath3.getFlowId()).andReturn(new FlowId(3).toString());
+ expect(fm.clearFlow(cmpEq(new FlowId(1)))).andReturn(true);
+ expect(fm.clearFlow(cmpEq(new FlowId(3)))).andReturn(true);
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Boolean result = fm.clearAllFlows();
+
+ //verify the test
+ verifyAll();
+ assertTrue(result);
+ }
+
+ /**
+ * Test method for {@link FlowManager#getFlow()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetFlowSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+ IFlowPath iFlowPath = createIFlowPathMock(1, "caller id", 0, 1, 1, 2, 2);
+
+ // setup expectations
+ expectInitWithContext();
+ expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(iFlowPath);
+ expect(iFlowPath.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
+ op.commit();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ FlowPath flowPath = fm.getFlow(new FlowId(1));
+ String installerId = flowPath.installerId().toString();
+ long flowPathFlags = flowPath.flowPathFlags().flags();
+
+ //verify the test
+ verifyAll();
+ assertEquals("caller id", installerId);
+ assertEquals(0L, flowPathFlags);
+ }
+
+ /**
+ * Test method for {@link FlowManager#getAllFlows(CallerId, DataPathEndpoints)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetAllFlowsWithCallerIdAndDataPathEndpointsSuccessNormally() throws Exception {
+ final String getAllFlows = "getAllFlows";
+ // create mock objects
+ FlowManager fm = createPartialMock(FlowManager.class, getAllFlows,
+ new Class<?>[]{}, new Object[]{});
+
+ // instantiate required objects
+ DataPathEndpoints dataPathEndpoints = new DataPathEndpoints(
+ new SwitchPort(new Dpid(1), new Port((short)1)),
+ new SwitchPort(new Dpid(2), new Port((short)2)));
+
+ ArrayList<FlowPath> obtainedAllFlows = createTestFlowPaths();
+
+ //setup expectations
+ expectInitWithContext();
+ expectPrivate(fm, getAllFlows).andReturn(obtainedAllFlows);
+
+ //start the test
+ replayAll();
+
+ fm.init(context);
+ ArrayList<FlowPath> flows = fm.getAllFlows(new CallerId("caller id"), dataPathEndpoints);
+
+ // verify the test
+ verifyAll();
+ assertEquals(1, flows.size());
+ assertEquals(obtainedAllFlows.get(1), flows.get(0));
+ }
+
+ /**
+ * Test method for {@link FlowManager#getAllFlows(DataPathEndpoints)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetAllFlowsWithDataPathEndpointsSuccessNormally() throws Exception {
+ final String getAllFlows = "getAllFlows";
+ // create mock objects
+ FlowManager fm = createPartialMock(FlowManager.class, getAllFlows,
+ new Class<?>[]{}, new Object[]{});
+
+ // instantiate required objects
+ DataPathEndpoints dataPathEndpoints = new DataPathEndpoints(
+ new SwitchPort(new Dpid(1), new Port((short)1)),
+ new SwitchPort(new Dpid(2), new Port((short)2)));
+
+ ArrayList<FlowPath> obtainedAllFlows = createTestFlowPaths();
+
+ //setup expectations
+ expectInitWithContext();
+ expectPrivate(fm, getAllFlows).andReturn(obtainedAllFlows);
+
+ //start the test
+ replayAll();
+
+ fm.init(context);
+ ArrayList<FlowPath> flows = fm.getAllFlows(dataPathEndpoints);
+
+ // verify the test
+ verifyAll();
+ assertEquals(2, flows.size());
+ assertEquals(obtainedAllFlows.get(0), flows.get(0));
+ assertEquals(obtainedAllFlows.get(1), flows.get(1));
+ // TODO: ignore the order of flows in the list
+ }
+
+ /**
+ * Test method for {@link FlowManager#getAllFlowsSummary(FlowId, int)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetAllFlowsSummarySuccessNormally() throws Exception {
+ final String getAllFlowsWithoutFlowEntries = "getAllFlowsWithoutFlowEntries";
+ // create mock objects
+ FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, getAllFlowsWithoutFlowEntries);
+ IFlowPath flowPath1 = createIFlowPathMock(1, "", 0, 1, 2, 3, 4);
+ IFlowPath flowPath2 = createIFlowPathMock(5, "", 0, 2, 3, 4, 5);
+ IFlowPath flowPath3 = createIFlowPathMock(10, "", 0, 3, 4, 5, 6);
+
+ // instantiate required objects
+ ArrayList<IFlowPath> flows = new ArrayList<IFlowPath>();
+ flows.add(flowPath3);
+ flows.add(flowPath1);
+ flows.add(flowPath2);
+
+ // setup expectations
+ expectInitWithContext();
+ expectPrivate(fm, getAllFlowsWithoutFlowEntries).andReturn(flows);
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ ArrayList<IFlowPath> returnedFlows = fm.getAllFlowsSummary(null, 0);
+
+ // verify the test
+ verifyAll();
+ assertEquals(3, returnedFlows.size());
+ assertEquals(1, new FlowId(returnedFlows.get(0).getFlowId()).value());
+ assertEquals(5, new FlowId(returnedFlows.get(1).getFlowId()).value());
+ assertEquals(10, new FlowId(returnedFlows.get(2).getFlowId()).value());
+ }
+
+ /**
+ * Test method for {@link FlowManager#getAllFlows()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetAllFlowsSuccessNormally() throws Exception {
+ // create mock objects
+ IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 0, 1, 1, 2, 2);
+ IFlowPath iFlowPath2 = createIFlowPathMock(2, "caller id", 0, 2, 5, 3, 5);
+
+ // instantiate required objects
+ ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+ flowPaths.add(iFlowPath1);
+ flowPaths.add(iFlowPath2);
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+ expect(op.getAllFlowPaths()).andReturn(flowPaths);
+ expect(iFlowPath1.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
+ expect(iFlowPath2.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
+ op.commit();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ ArrayList<FlowPath> flows = fm.getAllFlows();
+
+ // verify the test
+ verifyAll();
+ assertEquals(2, flows.size());
+ assertEquals(new SwitchPort(new Dpid(1), new Port((short)1)).toString(),
+ flows.get(0).dataPath().srcPort().toString());
+ assertEquals(new SwitchPort(new Dpid(2), new Port((short)5)).toString(),
+ flows.get(1).dataPath().srcPort().toString());
+ // TODO: more asserts
+ // TODO: ignore seq. of the list
+ }
+
+ /**
+ * Test method for {@link FlowManager#addAndMaintainShortestPathFlow(FlowPath)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testAddAndMaintainShortestPathFlowSuccessNormally() throws Exception {
+ final String addFlow = "addFlow";
+
+ // create mock objects
+ FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlow);
+
+ // instantiate required objects
+ DataPath dataPath = new DataPath();
+ dataPath.setSrcPort(new SwitchPort(new Dpid(1), new Port((short)3)));
+ dataPath.setDstPort(new SwitchPort(new Dpid(2), new Port((short)4)));
+ FlowEntryMatch match = new FlowEntryMatch();
+ FlowPath paramFlow = new FlowPath();
+ paramFlow.setFlowId(new FlowId(100));
+ paramFlow.setInstallerId(new CallerId("installer id"));
+ paramFlow.setFlowPathFlags(new FlowPathFlags(0));
+ paramFlow.setDataPath(dataPath);
+ paramFlow.setFlowEntryMatch(match);
+
+ // setup expectations
+ expectInitWithContext();
+ expectPrivate(fm, addFlow,
+ EasyMock.anyObject(FlowPath.class),
+ EasyMock.anyObject(FlowId.class),
+ EasyMock.anyObject(String.class)
+ ).andAnswer(new IAnswer<Object>() {
+ public Object answer() throws Exception {
+ FlowPath flowPath = (FlowPath)EasyMock.getCurrentArguments()[0];
+ assertEquals(flowPath.flowId().value(), 100);
+ assertEquals(flowPath.installerId().toString(), "installer id");
+ assertEquals(flowPath.flowPathFlags().flags(), 0);
+ assertEquals(flowPath.dataPath().srcPort().toString(),
+ new SwitchPort(new Dpid(1), new Port((short)3)).toString());
+
+ String dataPathSummary = (String)EasyMock.getCurrentArguments()[2];
+ assertEquals(dataPathSummary, "X");
+
+ return true;
+ }
+ });
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ FlowPath resultFlow = fm.addAndMaintainShortestPathFlow(paramFlow);
+
+ // verify the test
+ verifyAll();
+ assertEquals(paramFlow.flowId().value(), resultFlow.flowId().value());
+ assertEquals(paramFlow.installerId().toString(), resultFlow.installerId().toString());
+ assertEquals(paramFlow.flowPathFlags().flags(), resultFlow.flowPathFlags().flags());
+ assertEquals(paramFlow.dataPath().toString(), resultFlow.dataPath().toString());
+ assertEquals(paramFlow.flowEntryMatch().toString(), resultFlow.flowEntryMatch().toString());
+ }
+
+ /**
+ * Test method for {@link FlowManager#measurementStorePathFlow(FlowPath)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testMeasurementStorePathFlowSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowPath paramFlow = createTestFlowPath(100, "installer id", 0, 1, 3, 2, 4);
+ Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+ expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+ ).andReturn(shortestPathMap);
+ expect(topoRouteService.getTopoShortestPath(
+ shortestPathMap,
+ paramFlow.dataPath().srcPort(),
+ paramFlow.dataPath().dstPort())).andReturn(null);
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ FlowPath resultFlowPath = fm.measurementStorePathFlow(paramFlow);
+
+ // verify the test
+ verifyAll();
+ assertEquals(paramFlow.flowId().value(), resultFlowPath.flowId().value());
+ assertEquals(paramFlow.installerId().toString(), resultFlowPath.installerId().toString());
+ assertEquals(paramFlow.flowPathFlags().flags(), resultFlowPath.flowPathFlags().flags());
+ assertEquals(paramFlow.dataPath().toString(), resultFlowPath.dataPath().toString());
+ assertEquals(paramFlow.flowEntryMatch().toString(), resultFlowPath.flowEntryMatch().toString());
+ }
+
+ /**
+ * Test method for {@link FlowManager#measurementInstallPaths(Integer)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testMeasurementInstallPathsSuccessNormally() throws Exception {
+ final String addFlow = "addFlow";
+
+ // create mock objects
+ FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlow);
+
+ // instantiate required objects
+ FlowPath flow1 = createTestFlowPath(1, "installer id", 0, 1, 2, 3, 4);
+ FlowPath flow2 = createTestFlowPath(2, "installer id", 0, 2, 3, 4, 5);
+ FlowPath flow3 = createTestFlowPath(3, "installer id", 0, 3, 4, 5, 6);
+ Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+
+ // setup expectations
+ expectInitWithContext();
+ expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+ ).andReturn(shortestPathMap);
+
+ expect(topoRouteService.getTopoShortestPath(
+ shortestPathMap,
+ flow1.dataPath().srcPort(),
+ flow1.dataPath().dstPort())).andReturn(null);
+
+ expect(topoRouteService.getTopoShortestPath(
+ shortestPathMap,
+ flow2.dataPath().srcPort(),
+ flow2.dataPath().dstPort())).andReturn(null);
+
+ expect(topoRouteService.getTopoShortestPath(
+ shortestPathMap,
+ flow3.dataPath().srcPort(),
+ flow3.dataPath().dstPort())).andReturn(null);
+
+ expectPrivate(fm, addFlow,
+ EasyMock.cmpEq(flow1),
+ EasyMock.anyObject(FlowId.class),
+ EasyMock.anyObject(String.class)).andReturn(true);
+
+ expectPrivate(fm, addFlow,
+ EasyMock.cmpEq(flow2),
+ EasyMock.anyObject(FlowId.class),
+ EasyMock.anyObject(String.class)).andReturn(true);
+
+ expectPrivate(fm, addFlow,
+ EasyMock.cmpEq(flow3),
+ EasyMock.anyObject(FlowId.class),
+ EasyMock.anyObject(String.class)).andReturn(true);
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ fm.measurementStorePathFlow(flow1);
+ fm.measurementStorePathFlow(flow2);
+ fm.measurementStorePathFlow(flow3);
+ Boolean result = fm.measurementInstallPaths(3);
+
+ // verify the test
+ verifyAll();
+ assertTrue(result);
+ }
+
+ /**
+ * Test method for {@link FlowManager#measurementGetInstallPathsTimeNsec()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testMeasurementGetInstallPathsTimeNsecSuccessNormally() throws Exception {
+ final String addFlow = "addFlow";
+
+ // create mock objects
+ FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlow);
+ mockStaticPartial(System.class, "nanoTime");
+
+ // instantiate required objects
+ FlowPath flow1 = createTestFlowPath(1, "installer id", 0, 1, 2, 3, 4);
+ Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+
+ // setup expectations
+ expectInitWithContext();
+ expect(System.nanoTime()).andReturn(new Long(100000));
+ expect(System.nanoTime()).andReturn(new Long(110000));
+ expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+ ).andReturn(shortestPathMap);
+ expect(topoRouteService.getTopoShortestPath(
+ shortestPathMap,
+ flow1.dataPath().srcPort(),
+ flow1.dataPath().dstPort())).andReturn(null);
+ expectPrivate(fm, addFlow,
+ EasyMock.cmpEq(flow1),
+ EasyMock.anyObject(FlowId.class),
+ EasyMock.anyObject(String.class)).andReturn(true);
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ fm.measurementStorePathFlow(flow1).toString();
+ fm.measurementInstallPaths(1);
+ Long result = fm.measurementGetInstallPathsTimeNsec();
+
+ // verify the test
+ verifyAll();
+ assertEquals(new Long(10000), result);
+ }
+
+ /**
+ * Test method for {@link FlowManager#measurementGetPerFlowInstallTime()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testMeasurementGetPerFlowInstallTimeSuccessNormally() throws Exception {
+ final String addFlow = "addFlow";
+
+ // create mock objects
+ FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlow);
+
+ // instantiate required objects
+ FlowPath flow1 = createTestFlowPath(1, "installer id", 0, 1, 2, 3, 4);
+ Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+
+ // setup expectations
+ expectInitWithContext();
+ expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+ ).andReturn(shortestPathMap);
+
+ expect(topoRouteService.getTopoShortestPath(
+ shortestPathMap,
+ flow1.dataPath().srcPort(),
+ flow1.dataPath().dstPort())).andReturn(null);
+
+ expectPrivate(fm, addFlow,
+ EasyMock.cmpEq(flow1),
+ EasyMock.anyObject(FlowId.class),
+ EasyMock.anyObject(String.class)).andReturn(true);
+
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ fm.measurementStorePathFlow(flow1);
+ fm.measurementInstallPaths(10);
+ String result = fm.measurementGetPerFlowInstallTime();
+
+ // verify the test
+ verifyAll();
+ assertTrue(result.startsWith("ThreadAndTimePerFlow"));
+ }
+
+ /**
+ * Test method for {@link FlowManager#measurementClearAllPaths()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testMeasurementClearAllPathsSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowPath paramFlow = createTestFlowPath(100, "installer id", 0, 1, 3, 2, 4);
+ Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+ expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+ ).andReturn(shortestPathMap);
+ expect(topoRouteService.getTopoShortestPath(
+ shortestPathMap,
+ paramFlow.dataPath().srcPort(),
+ paramFlow.dataPath().dstPort())).andReturn(null);
+ topoRouteService.dropShortestPathTopo(shortestPathMap);
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ fm.measurementStorePathFlow(paramFlow);
+ Boolean result = fm.measurementClearAllPaths();
+
+ // verify the test
+ verifyAll();
+ assertTrue(result);
+ assertEquals(new Long(0), fm.measurementGetInstallPathsTimeNsec());
+ assertEquals("", fm.measurementGetPerFlowInstallTime());
+ }
+
+
+ // INetMapStorage methods
+
+
+ /**
+ * Test method for {@link FlowManager#init(String)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testInitSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ // create mock objects
+ op = createMock(GraphDBOperation.class);
+
+ // setup expectations
+ expectNew(GraphDBOperation.class, "/dummy/path").andReturn(op);
+
+ // start the test
+ replayAll();
+
+ fm.init("/dummy/path");
+
+ // verify the test
+ verifyAll();
+ }
+
+ /**
+ * Test method for {@link FlowManager#close()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testCloseSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+ op.close();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ fm.close();
+
+ // verify the test
+ verifyAll();
+ }
+
+
+ // IFloodlightModule methods
+
+
+ /**
+ * Test method for {@link FlowManager#getModuleServices()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetModuleServicesSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Collection<Class<? extends IFloodlightService>> l = fm.getModuleServices();
+
+ // verify the test
+ verifyAll();
+ assertEquals(1, l.size());
+ assertEquals(IFlowService.class, l.iterator().next());
+ }
+
+ /**
+ * Test method for {@link FlowManager#getServiceImpls()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetServiceImplsSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Map<Class<? extends IFloodlightService>, IFloodlightService> si = fm.getServiceImpls();
+
+ // verify the test
+ verifyAll();
+ assertEquals(1, si.size());
+ assertTrue(si.containsKey(IFlowService.class));
+ assertEquals(fm, si.get(IFlowService.class));
+ }
+
+ /**
+ * Test method for {@link FlowManager#getModuleDependencies()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetModuleDependenciesSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Collection<Class<? extends IFloodlightService>> md = fm.getModuleDependencies();
+
+ // verify the test
+ verifyAll();
+ assertEquals(2, md.size());
+ assertTrue(md.contains(IFloodlightProviderService.class));
+ assertTrue(md.contains(IRestApiService.class));
+ }
+
+ /**
+ * Test method for {@link FlowManager#init(FloodlightModuleContext)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testInitWithFloodlightModuleContextSuccessNormally() throws Exception {
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+
+ // verify the test
+ verifyAll();
+ }
+
+ /**
+ * Test method for {@link FlowManager#startUp(FloodlightModuleContext)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testStartupSuccessNormally() throws Exception {
+ // create mock objects
+ mockStaticPartial(Executors.class, "newScheduledThreadPool");
+ ScheduledExecutorService scheduler = createMock(ScheduledExecutorService.class);
+
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+ expect(Executors.newScheduledThreadPool(1)).andReturn(scheduler);
+ expect(Executors.newScheduledThreadPool(1)).andReturn(scheduler);
+ expect(scheduler.scheduleAtFixedRate(
+ EasyMock.anyObject(Runnable.class),
+ EasyMock.anyLong(),
+ EasyMock.anyLong(),
+ EasyMock.anyObject(TimeUnit.class))).andReturn(null).times(2);
+ restApi.addRestletRoutable(EasyMock.anyObject(FlowWebRoutable.class));
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ fm.startUp(context);
+
+ // verify the test
+ verifyAll();
+ }
+
+
+ // other methods
+
+
+ /**
+ * Test method for {@link FlowManager#clearFlow(FlowId)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testClearFlowSuccessNormally() throws Exception {
+ // create mock objects
+ IFlowPath flowPath = createIFlowPathMock(123, "id", 0, 1, 2, 3, 4);
+ IFlowEntry flowEntry1 = createMock(IFlowEntry.class);
+ IFlowEntry flowEntry2 = createMock(IFlowEntry.class);
+ IFlowEntry flowEntry3 = createMock(IFlowEntry.class);
+
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+ FlowId flowId = new FlowId(123);
+ ArrayList<IFlowEntry> flowEntries = new ArrayList<IFlowEntry>();
+ flowEntries.add(flowEntry1);
+ flowEntries.add(flowEntry2);
+ flowEntries.add(flowEntry3);
+
+ // setup expectations
+ expectInitWithContext();
+ expect(op.searchFlowPath(cmpEq(flowId))).andReturn(flowPath);
+ expect(flowPath.getFlowEntries()).andReturn(flowEntries);
+ flowPath.removeFlowEntry(flowEntry1);
+ flowPath.removeFlowEntry(flowEntry2);
+ flowPath.removeFlowEntry(flowEntry3);
+ op.removeFlowEntry(flowEntry1);
+ op.removeFlowEntry(flowEntry2);
+ op.removeFlowEntry(flowEntry3);
+ op.removeFlowPath(flowPath);
+ op.commit();
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ fm.clearFlow(flowId);
+
+ // verify the test
+ verifyAll();
+ }
+
+ /**
+ * Test method for {@link FlowManager#getAllFlowsWithoutFlowEntries()}.
+ * @throws Exception
+ */
+ @Test
+ public final void testGetAllFlowsWithoutFlowEntriesSuccessNormally() throws Exception {
+ // create mock objects
+ IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 0, 1, 1, 2, 2);
+ IFlowPath iFlowPath2 = createIFlowPathMock(2, "caller id", 0, 2, 5, 3, 5);
+
+ // instantiate required objects
+ ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+ flowPaths.add(iFlowPath1);
+ flowPaths.add(iFlowPath2);
+ FlowManager fm = new FlowManager();
+
+ // setup expectations
+ expectInitWithContext();
+ op.commit();
+ expect(op.getAllFlowPaths()).andReturn(flowPaths);
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ ArrayList<IFlowPath> result = fm.getAllFlowsWithoutFlowEntries();
+
+ // verify the test
+ verifyAll();
+ assertEquals(iFlowPath1, result.get(0));
+ assertEquals(iFlowPath2, result.get(1));
+
+ // TODO: does this method just return the replica of the flow paths?
+ }
+
+ /**
+ * Test method for {@link FlowManager#reconcileFlow(IFlowPath, DataPath)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testReconcileFlowWithFlowPathAndDataPathSuccessNormally() throws Exception {
+ final String addFlowEntry = "addFlowEntry";
+
+ // create mock objects
+ IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 0, 1, 1, 2, 2);
+ IFlowEntry iFlowEntry1 = createMock(IFlowEntry.class);
+ IFlowEntry iFlowEntry2 = createMock(IFlowEntry.class);
+ FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlowEntry);
+
+ // instantiate required objects
+ FlowEntry flowEntry1 = new FlowEntry();
+ flowEntry1.setDpid(new Dpid(1));
+ flowEntry1.setFlowId(new FlowId(1));
+ flowEntry1.setInPort(new Port((short) 1));
+ flowEntry1.setOutPort(new Port((short) 11));
+ flowEntry1.setFlowEntryId(new FlowEntryId(1));
+ flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
+ flowEntry1.setFlowEntryActions(new FlowEntryActions());
+ flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
+
+ FlowEntry flowEntry2 = new FlowEntry();
+ flowEntry2.setDpid(new Dpid(2));
+ flowEntry2.setFlowId(new FlowId(2));
+ flowEntry2.setInPort(new Port((short) 22));
+ flowEntry2.setOutPort(new Port((short) 2));
+ flowEntry2.setFlowEntryId(new FlowEntryId(2));
+ flowEntry2.setFlowEntryMatch(new FlowEntryMatch());
+ flowEntry2.setFlowEntryActions(new FlowEntryActions());
+ flowEntry2.setFlowEntryErrorState(new FlowEntryErrorState());
+
+ DataPath dataPath = new DataPath();
+ ArrayList<FlowEntry> flowEntries = new ArrayList<FlowEntry>();
+ flowEntries.add(flowEntry1);
+ flowEntries.add(flowEntry2);
+ dataPath.setFlowEntries(flowEntries);
+
+ ArrayList<IFlowEntry> oldFlowEntries = new ArrayList<IFlowEntry>();
+ oldFlowEntries.add(iFlowEntry1);
+ oldFlowEntries.add(iFlowEntry2);
+
+ // setup expectations
+ expectInitWithContext();
+ expect(floodlightProvider.getSwitches()).andReturn(null); // TODO: why is this needed?
+ expect(iFlowPath1.getFlowEntries()).andReturn(oldFlowEntries);
+ iFlowEntry1.setUserState("FE_USER_DELETE");
+ iFlowEntry1.setSwitchState("FE_SWITCH_NOT_UPDATED");
+ iFlowEntry2.setUserState("FE_USER_DELETE");
+ iFlowEntry2.setSwitchState("FE_SWITCH_NOT_UPDATED");
+ expectPrivate(fm, addFlowEntry, iFlowPath1, flowEntry1).andReturn(null);
+ expectPrivate(fm, addFlowEntry, iFlowPath1, flowEntry2).andReturn(null);
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Boolean result = fm.reconcileFlow(iFlowPath1, dataPath);
+
+ // verify the test
+ verifyAll();
+ assertTrue(result);
+ // TODO: write more asserts
+ }
+
+ /**
+ * Test method for {@link FlowManager#installFlowEntry(net.floodlightcontroller.core.IOFSwitch, IFlowPath, IFlowEntry)}.
+ * @throws Exception
+ */
+ @Test
+ public final void testInstallFlowEntryWithIFlowPathSuccessNormally() throws Exception {
+ // create mock object
+ IOFSwitch iofSwitch = createNiceMock(IOFSwitch.class);
+ IFlowPath iFlowPath = createIFlowPathMock(1, "id", 0, 1, 2, 3, 4);
+ IFlowEntry iFlowEntry = createMock(IFlowEntry.class);
+ BasicFactory basicFactory = createMock(BasicFactory.class);
+
+ // instantiate required objects
+ FlowManager fm = new FlowManager();
+
+ FlowEntryAction action = new FlowEntryAction();
+ action.setActionOutput(new Port((short)2));
+ FlowEntryActions actions = new FlowEntryActions();
+ actions.addAction(action);
+
+ // setup expectations
+ expectInitWithContext();
+ expect(iFlowEntry.getFlowEntryId()).andReturn(new FlowEntryId(123).toString());
+ expect(iFlowEntry.getUserState()).andReturn("FE_USER_ADD");
+ iFlowEntry.setSwitchState("FE_SWITCH_UPDATED");
+ expect(iFlowEntry.getMatchInPort()).andReturn(new Short((short) 1));
+ expect(iFlowEntry.getMatchSrcMac()).andReturn("01:23:45:67:89:01");
+ expect(iFlowEntry.getMatchDstMac()).andReturn("01:23:45:67:89:02");
+ expect(iFlowEntry.getMatchEthernetFrameType()).andReturn(new Short((short)0x0800));
+ expect(iFlowEntry.getMatchVlanId()).andReturn(new Short((short)0x1234));
+ expect(iFlowEntry.getMatchVlanPriority()).andReturn(new Byte((byte)0x10));
+ expect(iFlowEntry.getMatchSrcIPv4Net()).andReturn("192.168.0.1");
+ expect(iFlowEntry.getMatchDstIPv4Net()).andReturn("192.168.0.2");
+ expect(iFlowEntry.getMatchIpProto()).andReturn(new Byte((byte)0x20));
+ expect(iFlowEntry.getMatchIpToS()).andReturn(new Byte((byte)0x3));
+ expect(iFlowEntry.getMatchSrcTcpUdpPort()).andReturn(new Short((short)40000));
+ expect(iFlowEntry.getMatchDstTcpUdpPort()).andReturn(new Short((short)80));
+ expect(iFlowEntry.getActions()).andReturn(actions.toString());
+ expect(floodlightProvider.getOFMessageFactory()).andReturn(basicFactory);
+ expect(basicFactory.getMessage(OFType.FLOW_MOD)).andReturn(new OFFlowMod());
+ expect(iofSwitch.getStringId()).andReturn(new Dpid(100).toString());
+
+ // start the test
+ replayAll();
+
+ fm.init(context);
+ Boolean result = fm.installFlowEntry(iofSwitch, iFlowPath, iFlowEntry);
+
+ // verify the test
+ verifyAll();
+ assertTrue(result);
+ // TODO: write more asserts
+ }
+
+ /**
+ * Test method for {@link FlowManager#installFlowEntry(net.floodlightcontroller.core.IOFSwitch, FlowPath, FlowEntry)}.
+ * The method seems to be not used for now.
+ */
+ @Ignore @Test
+ public final void testInstallFlowEntryWithFlowPathSuccessNormally() {
+ fail("not yet implemented");
+ }
+
+ /**
+ * Test method for {@link FlowManager#removeFlowEntry(net.floodlightcontroller.core.IOFSwitch, FlowPath, FlowEntry)}.
+ * The method seems to be not implemented and not used for now.
+ */
+ @Ignore @Test
+ public final void testRemoveFlowEntrySuccessNormally() {
+ fail("not yet implemented");
+ }
+
+ /**
+ * Test method for {@link FlowManager#installRemoteFlowEntry(FlowPath, FlowEntry)}.
+ * The method seems to be not implemented and not used for now.
+ */
+ @Ignore @Test
+ public final void testInstallRemoteFlowEntrySuccessNormally() {
+ fail("not yet implemented");
+ }
+
+ /**
+ * Test method for {@link FlowManager#removeRemoteFlowEntry(FlowPath, FlowEntry)}.
+ * The method seems to be not implemented and not used for now.
+ */
+ @Ignore @Test
+ public final void testRemoveRemoteFlowEntrySuccessNormally() {
+ fail("not yet implemented");
+ }
+}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
similarity index 97%
rename from src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
rename to src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
index 6e99acd..87b48b2 100644
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -15,7 +15,7 @@
* under the License.
**/
-package net.floodlightcontroller.linkdiscovery.internal;
+package net.onrc.onos.ofcontroller.linkdiscovery.internal;
import static org.easymock.EasyMock.*;
@@ -35,10 +35,6 @@
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
-import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.floodlightcontroller.linkdiscovery.LinkInfo;
-import net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.restserver.RestApiServer;
import net.floodlightcontroller.routing.IRoutingService;
@@ -50,6 +46,10 @@
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.topology.TopologyManager;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+import net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager;
/**
*
diff --git a/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java b/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java
new file mode 100644
index 0000000..a33df98
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java
@@ -0,0 +1,262 @@
+package net.onrc.onos.ofcontroller.routing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.easymock.EasyMock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+import com.tinkerpop.pipes.PipeFunction;
+import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowPathFlags;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
+
+/**
+ * A class for testing the TopoRouteService class.
+ * @see net.onrc.onos.ofcontroller.routing.TopoRouteService
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, TopoRouteService.class})
+public class TopoRouteServiceTest {
+ String conf;
+ private GraphDBConnection conn = null;
+ private GraphDBOperation oper = null;
+ private TitanGraph titanGraph = null;
+ private TopoRouteService topoRouteService = null;
+
+ /**
+ * Setup the tests.
+ */
+ @Before
+ public void setUp() throws Exception {
+ conf = "/dummy/path/to/db";
+
+ //
+ // Make mock database.
+ // Replace TitanFactory.open() to return the mock database.
+ //
+ titanGraph = TestDatabaseManager.getTestDatabase();
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
+
+ // Create the connection to the database
+ conn = GraphDBConnection.getInstance(conf);
+ oper = new GraphDBOperation(conn);
+
+ // Populate the database
+ TestDatabaseManager.populateTestData(titanGraph);
+
+ // Prepare the TopoRouteService instance
+ topoRouteService = new TopoRouteService();
+ topoRouteService.setDbOperationHandler(oper);
+ }
+
+ /**
+ * Cleanup after the tests.
+ */
+ @After
+ public void tearDown() throws Exception {
+ titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
+ }
+
+ /**
+ * Test method TopoRouteService.getTopoShortestPath()
+ *
+ * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#getTopoShortestPath
+ */
+ @Test
+ public void test_getTopoShortestPath() {
+ DataPath dataPath = null;
+ String srcDpidStr = "00:00:00:00:00:00:0a:01";
+ String dstDpidStr = "00:00:00:00:00:00:0a:06";
+ short srcPortShort = 1;
+ short dstPortShort = 1;
+
+ //
+ // Initialize the source and destination points
+ //
+ Dpid srcDpid = new Dpid(srcDpidStr);
+ Port srcPort = new Port(srcPortShort);
+ Dpid dstDpid = new Dpid(dstDpidStr);
+ Port dstPort = new Port(dstPortShort);
+ SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+ SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+ //
+ // Test a valid Shortest-Path computation
+ //
+ Map<Long, ?> shortestPathTopo =
+ topoRouteService.prepareShortestPathTopo();
+ dataPath = topoRouteService.getTopoShortestPath(shortestPathTopo,
+ srcSwitchPort,
+ dstSwitchPort);
+ assertTrue(dataPath != null);
+ String dataPathSummaryStr = dataPath.dataPathSummary();
+ // System.out.println(dataPathSummaryStr);
+ String expectedResult = "1/00:00:00:00:00:00:0a:01/2;1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
+ assertEquals(dataPathSummaryStr, expectedResult);
+
+ // Test if we apply various Flow Path Flags
+ String expectedResult2 = "1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
+ String expectedResult3 = "1/00:00:00:00:00:00:0a:03/2;";
+ FlowPathFlags flowPathFlags2 = new FlowPathFlags("DISCARD_FIRST_HOP_ENTRY");
+ FlowPathFlags flowPathFlags3 = new FlowPathFlags("KEEP_ONLY_FIRST_HOP_ENTRY");
+ //
+ dataPath.applyFlowPathFlags(flowPathFlags2);
+ dataPathSummaryStr = dataPath.dataPathSummary();
+ assertEquals(dataPathSummaryStr, expectedResult2);
+ //
+ dataPath.applyFlowPathFlags(flowPathFlags3);
+ dataPathSummaryStr = dataPath.dataPathSummary();
+ assertEquals(dataPathSummaryStr, expectedResult3);
+
+ //
+ // Test Shortest-Path computation to non-existing destination
+ //
+ String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+ Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+ SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+ dataPath = topoRouteService.getTopoShortestPath(shortestPathTopo,
+ srcSwitchPort,
+ noSuchDstSwitchPort);
+ assertTrue(dataPath == null);
+
+ topoRouteService.dropShortestPathTopo(shortestPathTopo);
+ }
+
+ /**
+ * Test method TopoRouteService.getShortestPath()
+ *
+ * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#getShortestPath
+ */
+ @Test
+ public void test_getShortestPath() {
+ DataPath dataPath = null;
+ String srcDpidStr = "00:00:00:00:00:00:0a:01";
+ String dstDpidStr = "00:00:00:00:00:00:0a:06";
+ short srcPortShort = 1;
+ short dstPortShort = 1;
+
+ //
+ // Initialize the source and destination points
+ //
+ Dpid srcDpid = new Dpid(srcDpidStr);
+ Port srcPort = new Port(srcPortShort);
+ Dpid dstDpid = new Dpid(dstDpidStr);
+ Port dstPort = new Port(dstPortShort);
+ SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+ SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+ //
+ // Test a valid Shortest-Path computation
+ //
+ dataPath = topoRouteService.getShortestPath(srcSwitchPort,
+ dstSwitchPort);
+ assertTrue(dataPath != null);
+ String dataPathSummaryStr = dataPath.dataPathSummary();
+ // System.out.println(dataPathSummaryStr);
+ String expectedResult = "1/00:00:00:00:00:00:0a:01/2;1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
+ assertEquals(dataPathSummaryStr, expectedResult);
+
+ // Test if we apply various Flow Path Flags
+ String expectedResult2 = "1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
+ String expectedResult3 = "1/00:00:00:00:00:00:0a:03/2;";
+ FlowPathFlags flowPathFlags2 = new FlowPathFlags("DISCARD_FIRST_HOP_ENTRY");
+ FlowPathFlags flowPathFlags3 = new FlowPathFlags("KEEP_ONLY_FIRST_HOP_ENTRY");
+ //
+ dataPath.applyFlowPathFlags(flowPathFlags2);
+ dataPathSummaryStr = dataPath.dataPathSummary();
+ assertEquals(dataPathSummaryStr, expectedResult2);
+ //
+ dataPath.applyFlowPathFlags(flowPathFlags3);
+ dataPathSummaryStr = dataPath.dataPathSummary();
+ assertEquals(dataPathSummaryStr, expectedResult3);
+
+ //
+ // Test Shortest-Path computation to non-existing destination
+ //
+ String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+ Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+ SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+
+ dataPath = topoRouteService.getShortestPath(srcSwitchPort,
+ noSuchDstSwitchPort);
+ assertTrue(dataPath == null);
+ }
+
+ /**
+ * Test method TopoRouteService.routeExists()
+ *
+ * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#routeExists
+ */
+ @Test
+ public void test_routeExists() {
+ Boolean result;
+ String srcDpidStr = "00:00:00:00:00:00:0a:01";
+ String dstDpidStr = "00:00:00:00:00:00:0a:06";
+ short srcPortShort = 1;
+ short dstPortShort = 1;
+
+ //
+ // Initialize the source and destination points
+ //
+ Dpid srcDpid = new Dpid(srcDpidStr);
+ Port srcPort = new Port(srcPortShort);
+ Dpid dstDpid = new Dpid(dstDpidStr);
+ Port dstPort = new Port(dstPortShort);
+ SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+ SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+ //
+ // Test a valid route
+ //
+ result = topoRouteService.routeExists(srcSwitchPort, dstSwitchPort);
+ assertTrue(result == true);
+
+ //
+ // Test a non-existing route
+ //
+ String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+ Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+ SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+ result = topoRouteService.routeExists(srcSwitchPort,
+ noSuchDstSwitchPort);
+ assertTrue(result != true);
+ }
+}
diff --git a/src/test/java/net/onrc/onos/registry/controller/StandaloneRegistryTest.java b/src/test/java/net/onrc/onos/registry/controller/StandaloneRegistryTest.java
new file mode 100644
index 0000000..7c4a1a0
--- /dev/null
+++ b/src/test/java/net/onrc/onos/registry/controller/StandaloneRegistryTest.java
@@ -0,0 +1,461 @@
+package net.onrc.onos.registry.controller;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openflow.util.HexString;
+
+/**
+ * Unit test for {@link StandaloneRegistry}.
+ * @author Naoki Shiota
+ *
+ */
+public class StandaloneRegistryTest {
+ protected static final long TIMEOUT_MSEC = 1000;
+
+ protected StandaloneRegistry registry;
+
+ /**
+ * Implementation of {@link ControlChangeCallback} which defines callback interfaces called by Registry.
+ * This class remembers past callback parameters and provides methods to access them.
+ * This class also provides CountDownLatch so one can wait until the callback be called
+ * specific times (specified by constructor parameter). Particularly, the first time callback
+ * called is supposed for registration, this class has an independent latch to wait for
+ * the first callback.
+ * @author Naoki Shiota
+ */
+ public static class LoggingCallback implements ControlChangeCallback {
+ private LinkedList<Long> dpidsCalledback = new LinkedList<Long>();
+ private LinkedList<Boolean> controlsCalledback = new LinkedList<Boolean>();
+ private CountDownLatch lock = null, registerLock = null;;
+
+ /**
+ * Constructor with number of times callback to be called.
+ * @param numberToCall Number of times expected callback to be called
+ */
+ public LoggingCallback(int numberToCall) {
+ lock = new CountDownLatch(numberToCall);
+ registerLock = new CountDownLatch(1);
+ }
+
+ /**
+ * Wait until registration is finished (callback is called for the first time).
+ * @throws InterruptedException
+ */
+ public void waitForRegistration() throws InterruptedException {
+ registerLock.await();
+ }
+
+ /**
+ * Wait for registration specifying timeout.
+ * @param msec Milliseconds to timeout
+ * @throws InterruptedException
+ */
+ public void waitForRegistration(long msec) throws InterruptedException {
+ registerLock.await(msec, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Wait until callback is called specific times.
+ * @throws InterruptedException
+ */
+ public void waitUntilCalled() throws InterruptedException {
+ lock.await();
+ }
+
+ /**
+ * Wait until callback is called specific times, specifying timeout.
+ * @param msec Milliseconds to timeout
+ * @throws InterruptedException
+ */
+ public void waitUntilCalled(long msec) throws InterruptedException {
+ lock.await(msec, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Get DPID parameter given by specific callback time.
+ * @param index Specify which time to get parameter
+ * @return DPID value by number.
+ */
+ public Long getDpid(int index) { return dpidsCalledback.get(index); }
+
+ /**
+ * Get hasControl parameter given by specific callback time.
+ * @param index Specify which time to get parameter
+ * @return hasControl value
+ */
+ public Boolean getControl(int index) { return controlsCalledback.get(index); }
+
+ /**
+ * Get DPID parameter given by latest call.
+ * @return DPID value by number
+ */
+ public Long getLatestDpid() { return dpidsCalledback.peekLast(); }
+
+ /**
+ * Get hasControl parameter given by latest call
+ * @return hasControl value
+ */
+ public Boolean getLatestControl() { return controlsCalledback.peekLast(); }
+
+ @Override
+ public void controlChanged(long dpid, boolean hasControl) {
+ dpidsCalledback.addLast(dpid);
+ controlsCalledback.addLast(hasControl);
+
+ lock.countDown();
+ registerLock.countDown();
+ }
+ };
+
+ @Before
+ public void setUp() throws Exception {
+ FloodlightModuleContext fmc = new FloodlightModuleContext();
+ registry = new StandaloneRegistry();
+ registry.init(fmc);
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#registerController(String)} can run without error.
+ */
+ @Test
+ public void testRegisterController() {
+ String controllerIdToRegister = "test";
+ try {
+ registry.registerController(controllerIdToRegister);
+ } catch (RegistryException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ // Register Controller ID doubly
+ try {
+ registry.registerController(controllerIdToRegister);
+ fail("Double registration goes through without exception");
+ } catch (RegistryException e) {
+ // expected behavior
+ }
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#getControllerId()} can return correct ID.
+ * @throws RegistryException
+ */
+ @Test
+ public void testGetControllerId() throws RegistryException {
+ String controllerIdToRegister = "test";
+
+ // try before controller is registered
+ String controllerId = registry.getControllerId();
+ assertNull(controllerId);
+
+ // register
+ registry.registerController(controllerIdToRegister);
+
+ // call getControllerId and verify
+ controllerId = registry.getControllerId();
+ assertNotNull(controllerId);
+ assertEquals(controllerIdToRegister, controllerId);
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#getAllControllers()} can return correct list of controllers.
+ * @throws RegistryException
+ */
+ @Test
+ public void testGetAllControllers() throws RegistryException {
+ String controllerIdToRegister = "test";
+
+ // Test before register controller
+ try {
+ Collection<String> ctrls = registry.getAllControllers();
+ assertFalse(ctrls.contains(controllerIdToRegister));
+ } catch (RegistryException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ // register
+ registry.registerController(controllerIdToRegister);
+
+ // Test after register controller
+ try {
+ Collection<String> ctrls = registry.getAllControllers();
+ assertTrue(ctrls.contains(controllerIdToRegister));
+ } catch (RegistryException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#requestControl(long, ControlChangeCallback)} can correctly take control for switch so that callback is called.
+ * @throws RegistryException
+ * @throws InterruptedException
+ */
+ @Test
+ public void testRequestControl() throws InterruptedException, RegistryException {
+ String controllerId = "test";
+ registry.registerController(controllerId);
+
+ LoggingCallback callback = new LoggingCallback(1);
+ long dpidToRequest = 1000L;
+
+ try {
+ registry.requestControl(dpidToRequest, callback);
+ } catch (RegistryException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ callback.waitForRegistration();
+
+ long dpidCallback = callback.getLatestDpid();
+ boolean controlCallback = callback.getLatestControl();
+
+ assertEquals(dpidToRequest, dpidCallback);
+ assertTrue(controlCallback);
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#releaseControl(long)} can correctly release the control so that callback is called.
+ * @throws InterruptedException
+ * @throws RegistryException
+ */
+ @Test
+ public void testReleaseControl() throws InterruptedException, RegistryException {
+ String controllerId = "test";
+ registry.registerController(controllerId);
+
+ long dpidToRequest = 1000L;
+ LoggingCallback callback = new LoggingCallback(2);
+
+ // to request and wait to take control
+ registry.requestControl(dpidToRequest, callback);
+ callback.waitForRegistration();
+
+ registry.releaseControl(dpidToRequest);
+
+ // verify
+ callback.waitUntilCalled();
+ assertEquals(dpidToRequest, (long)callback.getLatestDpid());
+ assertFalse(callback.getLatestControl());
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#hasControl(long)} returns correct status.
+ * @throws InterruptedException
+ * @throws RegistryException
+ */
+ @Test
+ public void testHasControl() throws InterruptedException, RegistryException {
+ String controllerId = "test";
+ registry.registerController(controllerId);
+
+ long dpidToRequest = 1000L;
+ LoggingCallback callback = new LoggingCallback(2);
+
+ // Test before request control
+ assertFalse(registry.hasControl(dpidToRequest));
+
+ registry.requestControl(dpidToRequest, callback);
+ callback.waitForRegistration();
+
+ // Test after take control
+ assertTrue(registry.hasControl(dpidToRequest));
+
+ registry.releaseControl(dpidToRequest);
+
+ callback.waitUntilCalled();
+
+ // Test after release control
+ assertFalse(registry.hasControl(dpidToRequest));
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#getControllerForSwitch(long)} returns correct controller ID.
+ * @throws InterruptedException
+ * @throws RegistryException
+ */
+ @Test
+ public void testGetControllerForSwitch() throws InterruptedException, RegistryException {
+ String controllerId = "test";
+ registry.registerController(controllerId);
+
+ long dpidToRequest = 1000L;
+ LoggingCallback callback = new LoggingCallback(2);
+
+ // Test before request control
+ try {
+ String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+ assertNotEquals(controllerId,controllerForSw);
+ } catch (RegistryException e) {
+ fail("Failed before request control : " + e.getMessage());
+ e.printStackTrace();
+ }
+
+ registry.requestControl(dpidToRequest, callback);
+ callback.waitForRegistration();
+
+ // Test after take control
+ try {
+ String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+ assertEquals(controllerId,controllerForSw);
+ } catch (RegistryException e) {
+ fail("Failed after take control : " + e.getMessage());
+ e.printStackTrace();
+ }
+
+ registry.releaseControl(dpidToRequest);
+ callback.waitUntilCalled();
+
+ // Test after release control
+ try {
+ String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+ assertNotEquals(controllerId,controllerForSw);
+ } catch (RegistryException e) {
+ fail("Failed after release control : " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#getAllSwitches()} returns correct list of switches.
+ * @throws InterruptedException
+ * @throws RegistryException
+ */
+ @Test
+ public void testGetAllSwitches() throws InterruptedException, RegistryException {
+ String controllerId = "test";
+ registry.registerController(controllerId);
+
+ long dpidToRequest = 1000L;
+ String dpidToRequestStr = HexString.toHexString(dpidToRequest);
+ LoggingCallback callback = new LoggingCallback(2);
+
+ // Test before request control
+ Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
+ assertNotNull(switches);
+ assertFalse(switches.keySet().contains(dpidToRequestStr));
+
+ registry.requestControl(dpidToRequest, callback);
+ callback.waitForRegistration();
+
+ // Test after take control
+ switches = registry.getAllSwitches();
+ assertNotNull(switches);
+ assertTrue(switches.keySet().contains(dpidToRequestStr));
+ int count = 0;
+ for(ControllerRegistryEntry ctrl : switches.get(dpidToRequestStr)) {
+ if(ctrl.getControllerId().equals(controllerId)) {
+ ++count;
+ }
+ }
+ assertEquals(1,count);
+
+ registry.releaseControl(dpidToRequest);
+ callback.waitUntilCalled();
+
+ // Test after release control
+ switches = registry.getAllSwitches();
+ assertNotNull(switches);
+ assertFalse(switches.keySet().contains(dpidToRequestStr));
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#getSwitchesControlledByController(String)} returns correct list of switches.
+ * @throws InterruptedException
+ * @throws RegistryException
+ */
+ // TODO: remove @Ignore after implement StandaloneRegistry#getSwitchesControlledByController
+ @Ignore @Test
+ public void testGetSwitchesControlledByController() throws InterruptedException, RegistryException {
+ String controllerId = "test";
+ registry.registerController(controllerId);
+
+ long dpidToRequest = 1000L;
+ String dpidToRequestStr = HexString.toHexString(dpidToRequest);
+ LoggingCallback callback = new LoggingCallback(2);
+
+ // Test before request control
+ Collection<Long> switches = registry.getSwitchesControlledByController(controllerId);
+ assertNotNull(switches);
+ assertFalse(switches.contains(dpidToRequestStr));
+
+ registry.requestControl(dpidToRequest, callback);
+ callback.waitForRegistration();
+
+ // Test after take control
+ switches = registry.getSwitchesControlledByController(controllerId);
+ assertNotNull(switches);
+ assertTrue(switches.contains(dpidToRequestStr));
+ int count = 0;
+ for(Long dpid : switches) {
+ if((long)dpid == dpidToRequest) {
+ ++count;
+ }
+ }
+ assertEquals(1, count);
+
+ registry.releaseControl(dpidToRequest);
+ callback.waitUntilCalled();
+
+ // Test after release control
+ switches = registry.getSwitchesControlledByController(controllerId);
+ assertNotNull(switches);
+ assertFalse(switches.contains(dpidToRequestStr));
+ }
+
+ /**
+ * Test if {@link StandaloneRegistry#allocateUniqueIdBlock()} returns appropriate object.
+ * Get bulk of IdBlocks and check if they do have unique range of IDs.
+ */
+ @Test
+ public void testAllocateUniqueIdBlock() {
+ // Number of blocks to be verified that any of them has unique block
+ final int NUM_BLOCKS = 100;
+ ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(NUM_BLOCKS);
+
+ for(int i = 0; i < NUM_BLOCKS; ++i) {
+ blocks.add(registry.allocateUniqueIdBlock());
+ }
+
+ for(int i = 0; i < NUM_BLOCKS; ++i) {
+ IdBlock block1 = blocks.get(i);
+ for(int j = i + 1; j < NUM_BLOCKS; ++j) {
+ IdBlock block2 = blocks.get(j);
+ IdBlock lower,higher;
+
+ if(block1.getStart() < block2.getStart()) {
+ lower = block1;
+ higher = block2;
+ } else {
+ lower = block2;
+ higher = block1;
+ }
+
+ assertTrue(lower.getSize() > 0L);
+ assertTrue(higher.getSize() > 0L);
+ assertTrue(lower.getEnd() < higher.getStart());
+ }
+ }
+ }
+}
diff --git a/src/test/java/net/onrc/onos/registry/controller/ZookeeperRegistryTest.java b/src/test/java/net/onrc/onos/registry/controller/ZookeeperRegistryTest.java
new file mode 100644
index 0000000..3314ad2
--- /dev/null
+++ b/src/test/java/net/onrc/onos/registry/controller/ZookeeperRegistryTest.java
@@ -0,0 +1,597 @@
+package net.onrc.onos.registry.controller;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.test.FloodlightTestCase;
+import net.onrc.onos.registry.controller.StandaloneRegistryTest.LoggingCallback;
+import net.onrc.onos.registry.controller.ZookeeperRegistry.SwitchLeaderListener;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.util.HexString;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.netflix.curator.RetryPolicy;
+import com.netflix.curator.framework.CuratorFramework;
+import com.netflix.curator.framework.CuratorFrameworkFactory;
+import com.netflix.curator.framework.listen.ListenerContainer;
+import com.netflix.curator.framework.recipes.atomic.AtomicValue;
+import com.netflix.curator.framework.recipes.atomic.DistributedAtomicLong;
+import com.netflix.curator.framework.recipes.cache.ChildData;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCache;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCacheEvent;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCacheListener;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCache.StartMode;
+import com.netflix.curator.framework.recipes.leader.LeaderLatch;
+import com.netflix.curator.x.discovery.ServiceCache;
+import com.netflix.curator.x.discovery.ServiceCacheBuilder;
+import com.netflix.curator.x.discovery.ServiceDiscovery;
+import com.netflix.curator.x.discovery.ServiceDiscoveryBuilder;
+import com.netflix.curator.x.discovery.ServiceInstance;
+
+/**
+ * Unit test for {@link ZookeeperRegistry}.
+ * NOTE: {@link FloodlightTestCase} conflicts with PowerMock. If FloodLight-related methods need to be tested,
+ * implement another test class to test them.
+ * @author Naoki Shiota
+ *
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ZookeeperRegistry.class, CuratorFramework.class, CuratorFrameworkFactory.class,
+ ServiceDiscoveryBuilder.class, ServiceDiscovery.class, ServiceCache.class, PathChildrenCache.class,
+ ZookeeperRegistry.SwitchPathCacheListener.class})
+public class ZookeeperRegistryTest extends FloodlightTestCase {
+ private final static Long ID_BLOCK_SIZE = 0x100000000L;
+
+ protected ZookeeperRegistry registry;
+ protected CuratorFramework client;
+
+ protected PathChildrenCacheListener pathChildrenCacheListener;
+ protected final String CONTROLLER_ID = "controller2013";
+
+ /**
+ * Initialize {@link ZookeeperRegistry} Object and inject initial value with {@link ZookeeperRegistry#init(FloodlightModuleContext)} method.
+ * This setup code also tests {@link ZookeeperRegistry#init(FloodlightModuleContext)} method itself.
+ */
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+
+ pathChildrenCacheListener = null;
+
+ // Mock of CuratorFramework
+ client = createCuratorFrameworkMock();
+
+ // Mock of CuratorFrameworkFactory
+ PowerMock.mockStatic(CuratorFrameworkFactory.class);
+ EasyMock.expect(CuratorFrameworkFactory.newClient((String)EasyMock.anyObject(),
+ EasyMock.anyInt(), EasyMock.anyInt(), (RetryPolicy)EasyMock.anyObject())).andReturn(client);
+ PowerMock.replay(CuratorFrameworkFactory.class);
+
+ FloodlightModuleContext fmc = new FloodlightModuleContext();
+ registry = new ZookeeperRegistry();
+ fmc.addService(ZookeeperRegistry.class, registry);
+
+ registry.init(fmc);
+
+ PowerMock.verify(client, CuratorFrameworkFactory.class);
+ }
+
+ /**
+ * Clean up member variables (empty for now).
+ */
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#registerController(String)} method can go through without exception.
+ * (Exceptions are usually out of test target, but {@link ZookeeperRegistry#registerController(String)} throws an exception in case of invalid registration.)
+ */
+ @Test
+ public void testRegisterController() {
+ String controllerIdToRegister = "controller2013";
+
+ try {
+ registry.registerController(controllerIdToRegister);
+ } catch (RegistryException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#getControllerId()} correctly returns registered ID.
+ * @throws Exception
+ */
+ @Test
+ public void testGetControllerId() throws Exception {
+ String controllerIdToRegister = "controller1";
+
+ // try before controller is registered
+ String controllerId = registry.getControllerId();
+ assertNull(controllerId);
+
+ // register
+ registry.registerController(controllerIdToRegister);
+
+ // call getControllerId and verify
+ controllerId = registry.getControllerId();
+ assertNotNull(controllerId);
+ assertEquals(controllerIdToRegister, controllerId);
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#getAllControllers()} returns all controllers.
+ * Controllers to be returned are injected while setup. See {@link ZookeeperRegistryTest#createCuratorFrameworkMock()}
+ * to what controllers are injected using mock {@link ServiceCache}.
+ * @throws Exception
+ */
+ @Test
+ public void testGetAllControllers() throws Exception {
+ String controllerIdRegistered = "controller1";
+ String controllerIdNotRegistered = "controller2013";
+
+ try {
+ Collection<String> ctrls = registry.getAllControllers();
+ assertTrue(ctrls.contains(controllerIdRegistered));
+ assertFalse(ctrls.contains(controllerIdNotRegistered));
+ } catch (RegistryException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#requestControl(long, net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback)}
+ * correctly take control of specific switch. Because {@link ZookeeperRegistry#requestControl(long, net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback)}
+ * doesn't return values, inject mock {@link LeaderLatch} object and verify latch is correctly set up.
+ * @throws Exception
+ */
+ @Test
+ public void testRequestControl() throws Exception {
+ // Mock LeaderLatch
+ LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+ latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+ EasyMock.expectLastCall().once();
+ latch.start();
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(latch);
+
+ PowerMock.expectNew(LeaderLatch.class,
+ EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
+ .andReturn(latch).once();
+ PowerMock.replay(LeaderLatch.class);
+
+ String controllerId = "controller2013";
+ registry.registerController(controllerId);
+
+ LoggingCallback callback = new LoggingCallback(1);
+ long dpidToRequest = 2000L;
+
+ try {
+ registry.requestControl(dpidToRequest, callback);
+ } catch (RegistryException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ EasyMock.verify(latch);
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#releaseControl(long)} correctly release control of specific switch.
+ * Because {@link ZookeeperRegistry#releaseControl(long)} doesn't return values, inject mock
+ * {@link LeaderLatch} object and verify latch is correctly set up.
+ * @throws Exception
+ */
+ @Test
+ public void testReleaseControl() throws Exception {
+ // Mock of LeaderLatch
+ LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+ latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+ EasyMock.expectLastCall().once();
+ latch.start();
+ EasyMock.expectLastCall().once();
+ latch.removeAllListeners();
+ EasyMock.expectLastCall().once();
+ latch.close();
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(latch);
+
+ PowerMock.expectNew(LeaderLatch.class,
+ EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
+ .andReturn(latch).once();
+ PowerMock.replay(LeaderLatch.class);
+
+ String controllerId = "controller2013";
+ registry.registerController(controllerId);
+
+ long dpidToRequest = 2000L;
+ LoggingCallback callback = new LoggingCallback(1);
+
+ registry.requestControl(dpidToRequest, callback);
+ registry.releaseControl(dpidToRequest);
+
+ EasyMock.verify(latch);
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#hasControl(long)} returns correct status whether controller has control of specific switch.
+ * @throws Exception
+ */
+ @Test
+ public void testHasControl() throws Exception {
+ // Mock of LeaderLatch
+ LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+ latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+ EasyMock.expectLastCall().once();
+ latch.start();
+ EasyMock.expectLastCall().once();
+ EasyMock.expect(latch.hasLeadership()).andReturn(true).anyTimes();
+ latch.removeAllListeners();
+ EasyMock.expectLastCall().once();
+ latch.close();
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(latch);
+
+ PowerMock.expectNew(LeaderLatch.class,
+ EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
+ .andReturn(latch);
+ PowerMock.replay(LeaderLatch.class);
+
+ String controllerId = "controller2013";
+ registry.registerController(controllerId);
+
+ long dpidToRequest = 2000L;
+ LoggingCallback callback = new LoggingCallback(2);
+
+ // Test before request control
+ assertFalse(registry.hasControl(dpidToRequest));
+
+ registry.requestControl(dpidToRequest, callback);
+
+ // Test after request control
+ assertTrue(registry.hasControl(dpidToRequest));
+
+ registry.releaseControl(dpidToRequest);
+
+ // Test after release control
+ assertFalse(registry.hasControl(dpidToRequest));
+
+ EasyMock.verify(latch);
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#getControllerForSwitch(long)} correctly returns controller ID of specific switch.
+ * Relation between controllers and switches are defined by {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
+ * @throws Throwable
+ */
+ @Test
+ public void testGetControllerForSwitch() throws Throwable {
+ long dpidRegistered = 1000L;
+ long dpidNotRegistered = 2000L;
+
+ setPathChildrenCache();
+
+ String controllerForSw = registry.getControllerForSwitch(dpidRegistered);
+ assertEquals("controller1",controllerForSw);
+
+ controllerForSw = registry.getControllerForSwitch(dpidNotRegistered);
+ assertEquals(null, controllerForSw);
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#getSwitchesControlledByController(String)} returns correct list of
+ * switches controlled by a controller.
+ * @throws Exception
+ */
+ // TODO: Test after getSwitchesControlledByController() is implemented.
+ @Ignore @Test
+ public void testGetSwitchesControlledByController() throws Exception {
+ String controllerIdRegistered = "controller1";
+ String dpidRegistered = HexString.toHexString(1000L);
+ String controllerIdNotRegistered = CONTROLLER_ID;
+
+ Collection<Long> switches = registry.getSwitchesControlledByController(controllerIdRegistered);
+ assertNotNull(switches);
+ assertTrue(switches.contains(dpidRegistered));
+
+ switches = registry.getSwitchesControlledByController(controllerIdNotRegistered);
+ assertNotNull(switches);
+ assertEquals(0, switches.size());
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#getAllSwitches()} returns correct list of all switches.
+ * Switches are injected in {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
+ * @throws Exception
+ */
+ @Test
+ public void testGetAllSwitches() throws Exception {
+ String [] dpids = {
+ HexString.toHexString(1000L),
+ HexString.toHexString(1001L),
+ HexString.toHexString(1002L),
+ };
+
+ setPathChildrenCache();
+
+ Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
+ assertNotNull(switches);
+ assertEquals(dpids.length, switches.size());
+ for(String dpid : dpids) {
+ assertTrue(switches.keySet().contains(dpid));
+ }
+ }
+
+ /**
+ * Test if {@link ZookeeperRegistry#allocateUniqueIdBlock()} can assign IdBlock without duplication.
+ */
+ @Test
+ public void testAllocateUniqueIdBlock() {
+ // Number of blocks to be verified that any of them has unique block
+ final int NUM_BLOCKS = 100;
+ ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(NUM_BLOCKS);
+
+ for(int i = 0; i < NUM_BLOCKS; ++i) {
+ IdBlock block = registry.allocateUniqueIdBlock();
+ assertNotNull(block);
+ blocks.add(block);
+ }
+
+ for(int i = 0; i < NUM_BLOCKS; ++i) {
+ IdBlock block1 = blocks.get(i);
+ for(int j = i + 1; j < NUM_BLOCKS; ++j) {
+ IdBlock block2 = blocks.get(j);
+ IdBlock lower,higher;
+
+ if(block1.getStart() < block2.getStart()) {
+ lower = block1;
+ higher = block2;
+ } else {
+ lower = block2;
+ higher = block1;
+ }
+
+ assertTrue(lower.getSize() > 0L);
+ assertTrue(higher.getSize() > 0L);
+ assertTrue(lower.getEnd() <= higher.getStart());
+ }
+ }
+ }
+
+
+ //-------------------------- Creation of mock objects --------------------------
+ /**
+ * Create mock {@link CuratorFramework} object with initial value below.<br>
+ * [Ctrl ID] : [DPID]<br>
+ * controller1 : 1000<br>
+ * controller2 : 1001<br>
+ * controller2 : 1002<br>
+ * controller2013 : nothing
+ * @return Created mock object
+ * @throws Exception
+ */
+ @SuppressWarnings({ "serial", "unchecked" })
+ private CuratorFramework createCuratorFrameworkMock() throws Exception {
+ // Mock of AtomicValue
+ AtomicValue<Long> atomicValue = EasyMock.createMock(AtomicValue.class);
+ EasyMock.expect(atomicValue.succeeded()).andReturn(true).anyTimes();
+ EasyMock.expect(atomicValue.preValue()).andAnswer(new IAnswer<Long>() {
+ private long value = 0;
+ @Override
+ public Long answer() throws Throwable {
+ value += ID_BLOCK_SIZE;
+ return value;
+ }
+ }).anyTimes();
+ EasyMock.expect(atomicValue.postValue()).andAnswer(new IAnswer<Long>() {
+ private long value = ID_BLOCK_SIZE;
+ @Override
+ public Long answer() throws Throwable {
+ value += ID_BLOCK_SIZE;
+ return value;
+ }
+ }).anyTimes();
+ EasyMock.replay(atomicValue);
+
+ // Mock DistributedAtomicLong
+ DistributedAtomicLong daLong = EasyMock.createMock(DistributedAtomicLong.class);
+ EasyMock.expect(daLong.add(EasyMock.anyLong())).andReturn(atomicValue).anyTimes();
+ EasyMock.replay(daLong);
+ PowerMock.expectNew(DistributedAtomicLong.class,
+ new Class<?> [] {CuratorFramework.class, String.class, RetryPolicy.class},
+ EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(RetryPolicy.class)).
+ andReturn(daLong).anyTimes();
+ PowerMock.replay(DistributedAtomicLong.class);
+
+ // Mock ListenerContainer
+ ListenerContainer<PathChildrenCacheListener> listenerContainer = EasyMock.createMock(ListenerContainer.class);
+ listenerContainer.addListener(EasyMock.anyObject(PathChildrenCacheListener.class));
+ EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+ @Override
+ public Object answer() throws Throwable {
+ pathChildrenCacheListener = (PathChildrenCacheListener)EasyMock.getCurrentArguments()[0];
+ return null;
+ }
+ }).once();
+ EasyMock.replay(listenerContainer);
+
+ // Mock PathChildrenCache
+ PathChildrenCache pathChildrenCacheMain = createPathChildrenCacheMock(CONTROLLER_ID, new String[] {"/switches"}, listenerContainer);
+ PathChildrenCache pathChildrenCache1 = createPathChildrenCacheMock("controller1", new String[] {HexString.toHexString(1000L)}, listenerContainer);
+ PathChildrenCache pathChildrenCache2 = createPathChildrenCacheMock("controller2", new String[] {
+ HexString.toHexString(1001L), HexString.toHexString(1002L) },listenerContainer);
+
+ // Mock PathChildrenCache constructor
+ PowerMock.expectNew(PathChildrenCache.class,
+ EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+ andReturn(pathChildrenCacheMain).once();
+ PowerMock.expectNew(PathChildrenCache.class,
+ EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+ andReturn(pathChildrenCache1).once();
+ PowerMock.expectNew(PathChildrenCache.class,
+ EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+ andReturn(pathChildrenCache2).anyTimes();
+ PowerMock.replay(PathChildrenCache.class);
+
+ // Mock ServiceCache
+ ServiceCache<ControllerService> serviceCache = EasyMock.createMock(ServiceCache.class);
+ serviceCache.start();
+ EasyMock.expectLastCall().once();
+ EasyMock.expect(serviceCache.getInstances()).andReturn(new ArrayList<ServiceInstance<ControllerService> > () {{
+ add(createServiceInstanceMock("controller1"));
+ add(createServiceInstanceMock("controller2"));
+ }}).anyTimes();
+ EasyMock.replay(serviceCache);
+
+ // Mock ServiceCacheBuilder
+ ServiceCacheBuilder<ControllerService> serviceCacheBuilder = EasyMock.createMock(ServiceCacheBuilder.class);
+ EasyMock.expect(serviceCacheBuilder.name(EasyMock.anyObject(String.class))).andReturn(serviceCacheBuilder).once();
+ EasyMock.expect(serviceCacheBuilder.build()).andReturn(serviceCache).once();
+ EasyMock.replay(serviceCacheBuilder);
+
+ // Mock ServiceDiscovery
+ ServiceDiscovery<ControllerService> serviceDiscovery = EasyMock.createMock(ServiceDiscovery.class);
+ serviceDiscovery.start();
+ EasyMock.expectLastCall().once();
+ EasyMock.expect(serviceDiscovery.serviceCacheBuilder()).andReturn(serviceCacheBuilder).once();
+ serviceDiscovery.registerService(EasyMock.anyObject(ServiceInstance.class));
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(serviceDiscovery);
+
+ // Mock CuratorFramework
+ CuratorFramework client = EasyMock.createMock(CuratorFramework.class);
+ client.start();
+ EasyMock.expectLastCall().once();
+ EasyMock.expect(client.usingNamespace(EasyMock.anyObject(String.class))).andReturn(client);
+ EasyMock.replay(client);
+
+ // Mock ServiceDiscoveryBuilder
+ ServiceDiscoveryBuilder<ControllerService> builder = EasyMock.createMock(ServiceDiscoveryBuilder.class);
+ EasyMock.expect(builder.client(client)).andReturn(builder).once();
+ EasyMock.expect(builder.basePath(EasyMock.anyObject(String.class))).andReturn(builder);
+ EasyMock.expect(builder.build()).andReturn(serviceDiscovery);
+ EasyMock.replay(builder);
+
+ PowerMock.mockStatic(ServiceDiscoveryBuilder.class);
+ EasyMock.expect(ServiceDiscoveryBuilder.builder(ControllerService.class)).andReturn(builder).once();
+ PowerMock.replay(ServiceDiscoveryBuilder.class);
+
+ return client;
+ }
+
+ /**
+ * Create mock {@link ServiceInstance} object using given controller ID.
+ * @param controllerId Controller ID to represent instance's payload (ControllerService).
+ * @return Mock ServiceInstance object
+ */
+ private ServiceInstance<ControllerService> createServiceInstanceMock(String controllerId) {
+ ControllerService controllerService = EasyMock.createMock(ControllerService.class);
+ EasyMock.expect(controllerService.getControllerId()).andReturn(controllerId).anyTimes();
+ EasyMock.replay(controllerService);
+
+ @SuppressWarnings("unchecked")
+ ServiceInstance<ControllerService> serviceInstance = EasyMock.createMock(ServiceInstance.class);
+ EasyMock.expect(serviceInstance.getPayload()).andReturn(controllerService).anyTimes();
+ EasyMock.replay(serviceInstance);
+
+ return serviceInstance;
+ }
+
+ /**
+ * Create mock {@link PathChildrenCache} using given controller ID and DPIDs.
+ * @param controllerId Controller ID to represent current data.
+ * @param paths List of HexString indicating switch's DPID.
+ * @param listener Callback object to be set as Listenable.
+ * @return Mock PathChildrenCache object
+ * @throws Exception
+ */
+ private PathChildrenCache createPathChildrenCacheMock(final String controllerId, final String [] paths,
+ ListenerContainer<PathChildrenCacheListener> listener) throws Exception {
+ PathChildrenCache pathChildrenCache = EasyMock.createMock(PathChildrenCache.class);
+
+ EasyMock.expect(pathChildrenCache.getListenable()).andReturn(listener).anyTimes();
+
+ pathChildrenCache.start(EasyMock.anyObject(StartMode.class));
+ EasyMock.expectLastCall().anyTimes();
+
+ List<ChildData> childs = new ArrayList<ChildData>();
+ for(String path : paths) {
+ childs.add(createChildDataMockForCurrentData(controllerId,path));
+ }
+ EasyMock.expect(pathChildrenCache.getCurrentData()).andReturn(childs).anyTimes();
+
+ pathChildrenCache.rebuild();
+ EasyMock.expectLastCall().anyTimes();
+
+ EasyMock.replay(pathChildrenCache);
+
+ return pathChildrenCache;
+ }
+
+ /**
+ * Create mock {@link ChildData} for {@link PathChildrenCache#getCurrentData()} return value.
+ * This object need to include 'sequence number' in tail of path string. ("-0" means 0th sequence)
+ * @param controllerId Controller ID
+ * @param path HexString indicating switch's DPID
+ * @return Mock ChildData object
+ */
+ private ChildData createChildDataMockForCurrentData(String controllerId, String path) {
+ ChildData data = EasyMock.createMock(ChildData.class);
+ EasyMock.expect(data.getPath()).andReturn(path + "-0").anyTimes();
+ EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
+ EasyMock.replay(data);
+
+ return data;
+ }
+
+ /**
+ * Inject relations between controllers and switches using callback object.
+ * @throws Exception
+ */
+ private void setPathChildrenCache() throws Exception {
+ pathChildrenCacheListener.childEvent(client,
+ createChildrenCacheEventMock("controller1", HexString.toHexString(1000L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+ pathChildrenCacheListener.childEvent(client,
+ createChildrenCacheEventMock("controller2", HexString.toHexString(1001L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+ pathChildrenCacheListener.childEvent(client,
+ createChildrenCacheEventMock("controller2", HexString.toHexString(1002L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+ }
+
+ /**
+ * Create mock {@link PathChildrenCacheEvent} object using given controller ID and DPID.
+ * @param controllerId Controller ID.
+ * @param path HexString of DPID.
+ * @param type Event type to be set to mock object.
+ * @return Mock PathChildrenCacheEvent object
+ */
+ private PathChildrenCacheEvent createChildrenCacheEventMock(String controllerId, String path,
+ PathChildrenCacheEvent.Type type) {
+ PathChildrenCacheEvent event = EasyMock.createMock(PathChildrenCacheEvent.class);
+ ChildData data = EasyMock.createMock(ChildData.class);
+
+ EasyMock.expect(data.getPath()).andReturn(path).anyTimes();
+ EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
+ EasyMock.replay(data);
+
+ EasyMock.expect(event.getType()).andReturn(type).anyTimes();
+ EasyMock.expect(event.getData()).andReturn(data).anyTimes();
+ EasyMock.replay(event);
+
+ return event;
+ }
+}
diff --git a/start-cassandra.sh b/start-cassandra.sh
index c06fb14..426fa60 100755
--- a/start-cassandra.sh
+++ b/start-cassandra.sh
@@ -1,10 +1,10 @@
#!/bin/bash
# Set paths
-FL_HOME=`dirname $0`
-CASSANDRA_DIR=${HOME}/apache-cassandra-1.1.4
-LOGDIR=${HOME}/ONOS/onos-logs
-CASSANDRA_LOG=$LOGDIR/cassandara.`hostname`.log
+ONOS_HOME=`dirname $0`
+CASSANDRA_DIR=${HOME}/apache-cassandra-1.2.4
+LOGDIR=${ONOS_HOME}/ONOS/onos-logs
+CASSANDRA_LOG=${LOGDIR}/cassandara.`hostname`.log
function lotate {
logfile=$1
@@ -30,6 +30,11 @@
# Run cassandra
echo "Starting cassandra"
+# echo "[31;48m[WARNING] This script copies conf/cassandra.yaml to $CASSANDRA_DIR/conf/cassandra.yaml (overwrites)[0m"
+# echo "[31;48moriginal cassandra.yaml was backed up as cassandra.yaml.backup[0m"
+# id=`hostid`
+# cp ${CASSANDRA_DIR}/conf/cassandra.yaml $CASSANDRA_DIR/conf/cassandra.yaml.backup
+# cp ${ONOS_HOME}/conf/cassandra.yaml.${id} $CASSANDRA_DIR/conf
$CASSANDRA_DIR/bin/cassandra > $CASSANDRA_LOG 2>&1
}
@@ -56,7 +61,7 @@
case "$1" in
start)
deldb
- cp $FL_HOME/cassandra.titan /tmp
+ cp $ONOS_HOME/conf/cassandra.titan /tmp
stop
start
;;
diff --git a/start-onos-embedded.sh b/start-onos-embedded.sh
new file mode 100755
index 0000000..dac0331
--- /dev/null
+++ b/start-onos-embedded.sh
@@ -0,0 +1,162 @@
+#!/bin/bash
+
+# Set paths
+if [ -z "${ONOS_HOME}" ]; then
+ ONOS_HOME=`dirname $0`
+fi
+ONOS_LOGBACK="${ONOS_HOME}/logback.xml"
+LOGDIR=${ONOS_HOME}/onos-logs
+ONOS_LOG="${LOGDIR}/onos.`hostname`.log"
+PCAP_LOG="${LOGDIR}/onos.`hostname`.pcap"
+LOGS="$ONOS_LOG $PCAP_LOG"
+
+# 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:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
+JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8 \
+ -XX:+UseThreadPriorities \
+ -XX:ThreadPriorityPolicy=42 \
+ -XX:+UseCompressedOops \
+ -Dcassandra.compaction.priority=1 \
+ -Dcom.sun.management.jmxremote.port=7199 \
+ -Dcom.sun.management.jmxremote.ssl=false \
+ -Dcom.sun.management.jmxremote.authenticate=false"
+
+#JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
+
+# Set Main class to start ONOS core
+MAIN_CLASS="net.onrc.onos.ofcontroller.core.Main"
+
+if [ -z "${MVN}" ]; then
+ MVN="mvn"
+fi
+#<logger name="net.floodlightcontroller.linkdiscovery.internal" level="TRACE"/>
+#<appender-ref ref="STDOUT" />
+
+function lotate {
+ logfile=$1
+ nr_max=${2:-10}
+ if [ -f $logfile ]; then
+ for i in `seq $(expr $nr_max - 1) -1 1`; do
+ if [ -f ${logfile}.${i} ]; then
+ mv -f ${logfile}.${i} ${logfile}.`expr $i + 1`
+ fi
+ done
+ mv $logfile $logfile.1
+ fi
+}
+
+function start {
+ if [ ! -d ${LOGDIR} ]; then
+ mkdir -p ${LOGDIR}
+ fi
+ # Backup log files
+ for log in ${LOGS}; do
+ echo "rotate log: $log"
+ if [ -f ${log} ]; then
+ lotate ${log}
+ fi
+ done
+
+# Create a logback file if required
+ cat <<EOF_LOGBACK >${ONOS_LOGBACK}
+<configuration scan="true" debug="true">
+<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+<encoder>
+<pattern>%level [%logger:%thread] %msg%n</pattern>
+</encoder>
+</appender>
+
+<appender name="FILE" class="ch.qos.logback.core.FileAppender">
+<file>${ONOS_LOG}</file>
+<encoder>
+<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
+</encoder>
+</appender>
+
+<logger name="org" level="WARN"/>
+<logger name="LogService" level="WARN"/> <!-- Restlet access logging -->
+<logger name="net.floodlightcontroller.logging" level="WARN"/>
+
+<root level="DEBUG">
+<appender-ref ref="FILE" />
+</root>
+</configuration>
+EOF_LOGBACK
+
+ # Run floodlight
+ echo "Starting ONOS controller ..."
+ echo
+
+ # XXX MVN has to run at the project top dir..
+ cd ${ONOS_HOME}
+ ${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_HOME}/conf/onos-embedded.properties" > ${LOGDIR}/onos.stdout 2>${LOGDIR}/onos.stderr &
+
+ echo "Waiting for ONOS to start..."
+ COUNT=0
+ ESTATE=0
+ while [ "$COUNT" != "10" ]; do
+ COUNT=$((COUNT + 1))
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
+ if [ "$n" -ge "1" ]; then
+ exit 0
+ fi
+ sleep $COUNT
+ done
+ echo "Timed out"
+ exit 1
+
+ sudo -b /usr/sbin/tcpdump -n -i eth0 -s0 -w ${PCAP_LOG} 'tcp port 6633' > /dev/null 2>&1
+}
+
+function stop {
+ # Kill the existing processes
+ flpid=`jps -l |grep ${MAIN_CLASS} | awk '{print $1}'`
+ tdpid=`ps -edalf |grep tcpdump |grep ${PCAP_LOG} | awk '{print $4}'`
+ pids="$flpid $tdpid"
+ for p in ${pids}; do
+ if [ x$p != "x" ]; then
+ kill -KILL $p
+ echo "Killed existing process (pid: $p)"
+ fi
+ done
+}
+
+function deldb {
+ # Delete the cassandra data
+ if [ -d "/tmp/cassandra" ]; then
+ rm -rf /tmp/cassandra/*
+ fi
+}
+
+case "$1" in
+ start)
+ stop
+ start
+ ;;
+ startifdown)
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
+ if [ $n == 0 ]; then
+ start
+ else
+ echo "$n instance of onos running"
+ fi
+ ;;
+ stop)
+ stop
+ ;;
+ deldb)
+ deldb
+ ;;
+ status)
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
+ echo "$n instance of onos running"
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart|status|startifdown}"
+ exit 1
+esac
diff --git a/start-onos.sh b/start-onos.sh
index 77accd0..a35d181 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -1,28 +1,46 @@
#!/bin/bash
# Set paths
-FL_HOME=`dirname $0`
-FL_JAR="${FL_HOME}/target/floodlight.jar"
-FL_ONLY_JAR="${FL_HOME}/target/floodlight-only.jar"
-FL_LOGBACK="${FL_HOME}/logback.xml"
-LOGDIR=${FL_HOME}/onos-logs
-FL_LOG="${LOGDIR}/onos.`hostname`.log"
+if [ -z "${ONOS_HOME}" ]; then
+ ONOS_HOME=`dirname $0`
+fi
+
+## Because the script change dir to $ONOS_HOME, we can set ONOS_LOGBACK and LOGDIR relative to $ONOS_HOME
+#ONOS_LOGBACK="${ONOS_HOME}/logback.`hostname`.xml"
+#LOGDIR=${ONOS_HOME}/onos-logs
+ONOS_LOGBACK="./logback.`hostname`.xml"
+LOGDIR=./onos-logs
+ONOS_LOG="${LOGDIR}/onos.`hostname`.log"
PCAP_LOG="${LOGDIR}/onos.`hostname`.pcap"
-LOGS="$FL_LOG $PCAP_LOG"
+LOGS="$ONOS_LOG $PCAP_LOG"
# Set JVM options
JVM_OPTS=""
+## If you want JaCoCo Code Coverage reports... uncomment line below
+JVM_OPTS="$JVM_OPTS -javaagent:${ONOS_HOME}/lib/jacocoagent.jar=dumponexit=true,output=file,destfile=${LOGDIR}/jacoco.exec"
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 -Xmx2g -Xms2g -Xmn800m"
+JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
+#JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -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 -XX:OnError=crash-logger" ;# For dumping core
#JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
+JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8 \
+ -XX:+UseThreadPriorities \
+ -XX:ThreadPriorityPolicy=42 \
+ -XX:+UseCompressedOops \
+ -Dcom.sun.management.jmxremote.port=7189 \
+ -Dcom.sun.management.jmxremote.ssl=false \
+ -Dcom.sun.management.jmxremote.authenticate=false"
-# Set classpath to include titan libs
-#CLASSPATH=`echo ${FL_HOME}/lib/*.jar ${FL_HOME}/lib/titan/*.jar | sed 's/ /:/g'`
-CLASSPATH="${FL_ONLY_JAR}:${FL_HOME}/lib/*:${FL_HOME}/lib/titan/*"
-MAIN_CLASS="net.floodlightcontroller.core.Main"
+# Set ONOS core main class
+MAIN_CLASS="net.onrc.onos.ofcontroller.core.Main"
+
+if [ -z "${MVN}" ]; then
+ MVN="mvn -o"
+fi
#<logger name="net.floodlightcontroller.linkdiscovery.internal" level="TRACE"/>
#<appender-ref ref="STDOUT" />
@@ -53,7 +71,7 @@
done
# Create a logback file if required
- cat <<EOF_LOGBACK >${FL_LOGBACK}
+ cat <<EOF_LOGBACK >${ONOS_LOGBACK}
<configuration scan="true" debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
@@ -62,7 +80,7 @@
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
-<file>${FL_LOG}</file>
+<file>${ONOS_LOG}</file>
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
@@ -81,11 +99,33 @@
# Run floodlight
echo "Starting ONOS controller ..."
echo
- #java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf ${FL_HOME}/onos.properties > /dev/null 2>&1 &
- java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -cp ${CLASSPATH} ${MAIN_CLASS} -cf ${FL_HOME}/onos.properties > /dev/null 2>&1 &
+ # XXX : MVN has to run at the project top dir
+ echo $ONOS_HOME
+ cd ${ONOS_HOME}
+ pwd
+ echo "${MVN} exec:exec -Dexec.executable=\"java\" -Dexec.args=\"${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ./conf/onos.properties\""
-# echo "java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf ./onos.properties > /dev/null 2>&1 &"
+ ${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ./conf/onos.properties" > ${LOGDIR}/onos.`hostname`.stdout 2>${LOGDIR}/onos.`hostname`.stderr &
+
+ echo "Waiting for ONOS to start..."
+ COUNT=0
+ ESTATE=0
+ while [ "$COUNT" != "10" ]; do
+ echo -n "."
+ sleep 1
+# COUNT=$((COUNT + 1))
+# sleep $COUNT
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
+ if [ "$n" -ge "1" ]; then
+ echo ""
+ exit 0
+ fi
+ done
+ echo "Timed out"
+ exit 1
+
+# echo "java ${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -jar ${ONOS_JAR} -cf ./onos.properties > /dev/null 2>&1 &"
# sudo -b /usr/sbin/tcpdump -n -i eth0 -s0 -w ${PCAP_LOG} 'tcp port 6633' > /dev/null 2>&1
}
@@ -96,19 +136,12 @@
pids="$flpid $tdpid"
for p in ${pids}; do
if [ x$p != "x" ]; then
- kill -KILL $p
- echo "Killed existing prosess (pid: $p)"
+ kill -TERM $p
+ echo "Killed existing process (pid: $p)"
fi
done
}
-function deldb {
- # Delete the berkeley db database
- if [ -d "/tmp/cassandra.titan" ]; then
- rm -rf /tmp/cassandra.titan
- mkdir /tmp/cassandra.titan
- fi
-}
function check_db {
if [ -d "/tmp/cassandra.titan" ]; then
echo "Cassandra is running on local berkely db. Exitting"
@@ -128,7 +161,7 @@
start
;;
startifdown)
- n=`jps -l |grep "net.floodlightcontroller.core.Main" | wc -l`
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
if [ $n == 0 ]; then
start
else
@@ -138,11 +171,8 @@
stop)
stop
;;
- deldb)
- deldb
- ;;
status)
- n=`jps -l |grep "net.floodlightcontroller.core.Main" | wc -l`
+ n=`jps -l |grep "${MAIN_CLASS}" | wc -l`
echo "$n instance of onos running"
;;
*)
diff --git a/start-zk.sh b/start-zk.sh
new file mode 100755
index 0000000..0853a96
--- /dev/null
+++ b/start-zk.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# Set paths
+
+ONOS_HOME=`dirname $0`
+ZK_DIR=${HOME}/zookeeper-3.4.5
+#ZK_CONF=${ONOS_HOME}/conf/zoo.cfg
+
+function start {
+ # Run Zookeeper with our configuration
+ echo "Starting Zookeeper"
+# echo "[31;48m[WARNING] This script copies conf/zoo.cfg to $ZK_DIR/conf/zoo.cfg (overwrites)[0m"
+# echo "[31;48moriginal zoo.cfg was backed up as zoo.cfg.backup[0m"
+# if [ $ZK_DIR/conf/zoo.cfg ]; then
+# cp $ZK_DIR/conf/zoo.cfg $ZK_DIR/conf/zoo.cfg.backup
+# fi
+# hostid > /var/lib/zookeeper/myid
+# cp $ZK_CONF $ZK_DIR/conf
+# echo "cp $ZK_CONF $ZK_DIR/conf"
+ $ZK_DIR/bin/zkServer.sh start
+}
+
+function stop {
+ # Kill the existing processes
+ pids=`jps -l | grep org.apache.zookeeper.server | awk '{print $1}'`
+ for p in ${pids}; do
+ if [ x$p != "x" ]; then
+ kill -KILL $p
+ echo "Killed existing prosess (pid: $p)"
+ fi
+ done
+}
+function status {
+ $ZK_DIR/bin/zkServer.sh status
+}
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ status
+ ;;
+ restart)
+ stop
+ start
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart|status}"
+ exit 1
+esac
diff --git a/titan/gremlin.sh b/titan/gremlin.sh
index c7155ac..e4895b0 100755
--- a/titan/gremlin.sh
+++ b/titan/gremlin.sh
@@ -1,6 +1,12 @@
#!/bin/bash
-CP=$( echo `dirname $0`/../lib/*.jar `dirname $0`/../lib/titan/*.jar . | sed 's/ /:/g')
+if [ -z "${MVN}" ]; then
+ MVN="mvn"
+fi
+
+ONOS_DIR="`dirname $0`/.."
+#CP=$( echo `dirname $0`/../lib/*.jar `dirname $0`/../lib/titan/*.jar . | sed 's/ /:/g')
+CP=`${MVN} -f ${ONOS_DIR}/pom.xml dependency:build-classpath -Dmdep.outputFile=/dev/stdout -l /dev/stderr`
# Find Java
if [ "$JAVA_HOME" = "" ] ; then
diff --git a/titan/schema/dbapi-testdata.graphml b/titan/schema/dbapi-testdata.graphml
index fbf7e2b..952a62a 100644
--- a/titan/schema/dbapi-testdata.graphml
+++ b/titan/schema/dbapi-testdata.graphml
@@ -1 +1 @@
-<?xml version=\"1.0\" ?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"> <key id=\"id\" for=\"node\" attr.name=\"id\" attr.type=\"string\"></key> <key id=\"type\" for=\"node\" attr.name=\"type\" attr.type=\"string\"></key> <key id=\"dpid\" for=\"node\" attr.name=\"dpid\" attr.type=\"string\"></key> <key id=\"desc\" for=\"node\" attr.name=\"desc\" attr.type=\"string\"></key> <key id=\"number\" for=\"node\" attr.name=\"number\" attr.type=\"int\"></key> <key id=\"dl_addr\" for=\"node\" attr.name=\"dl_addr\" attr.type=\"string\"></key> <key id=\"nw_addr\" for=\"node\" attr.name=\"nw_addr\" attr.type=\"string\"></key> <key id=\"id\" for=\"edge\" attr.name=\"id\" attr.type=\"string\"></key> <key id=\"source\" for=\"edge\" attr.name=\"source\" attr.type=\"string\"></key> <key id=\"target\" for=\"edge\" attr.name=\"target\" attr.type=\"string\"></key> <key id=\"label\" for=\"edge\" attr.name=\"label\" attr.type=\"string\"></key> <graph id=\"G\" edgedefault=\"directed\"> <node id=\"1\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:01</data> <data key=\"desc\">OpenFlow Switch at SEA</data> </node> <node id=\"2\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:02</data> <data key=\"desc\">OpenFlow Switch at LAX</data> </node> <node id=\"3\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:03</data> <data key=\"desc\">OpenFlow Switch at CHI</data> </node> <node id=\"4\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:04</data> <data key=\"desc\">OpenFlow Switch at IAH</data> </node> <node id=\"5\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:05</data> <data key=\"desc\">OpenFlow Switch at NYC</data> </node> <node id=\"6\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:06</data> <data key=\"desc\">OpenFlow Switch at ATL</data> </node> <node id=\"100\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at SEA Switch</data> </node> <node id=\"101\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at SEA Switch</data> </node> <node id=\"102\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at SEA Switch</data> </node> <node id=\"103\"> <data key=\"type\">port</data> <data key=\"number\">4</data> <data key=\"desc\">port 4 at SEA Switch</data> </node> <node id=\"104\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at LAX Switch</data> </node> <node id=\"105\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at LAX Switch</data> </node> <node id=\"106\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at LAX Switch</data> </node> <node id=\"107\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at CHI Switch</data> </node> <node id=\"108\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at CHI Switch</data> </node> <node id=\"109\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at CHI Switch</data> </node> <node id=\"110\"> <data key=\"type\">port</data> <data key=\"number\">4</data> <data key=\"desc\">port 4 at CHI Switch</data> </node> <node id=\"111\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at IAH Switch</data> </node> <node id=\"112\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at IAH Switch</data> </node> <node id=\"113\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at IAH Switch</data> </node> <node id=\"114\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at NYC Switch</data> </node> <node id=\"115\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at NYC Switch</data> </node> <node id=\"116\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at NYC Switch</data> </node> <node id=\"117\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at ATL Switch</data> </node> <node id=\"118\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at ATL Switch</data> </node> <node id=\"119\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at ATL Switch</data> </node> <node id=\"1000\"> <data key=\"type\">device</data> <data key=\"dl_addr\">20:c9:d0:4a:e1:73</data> <data key=\"nw_addr\">192.168.10.101</data> </node> <node id=\"1001\"> <data key=\"type\">device</data> <data key=\"dl_addr\">20:c9:d0:4a:e1:62</data> <data key=\"nw_addr\">192.168.20.101</data> </node> <node id=\"1002\"> <data key=\"type\">device</data> <data key=\"dl_addr\">10:40:f3:e6:8d:55</data> <data key=\"nw_addr\">192.168.10.1</data> </node> <node id=\"1003\"> <data key=\"type\">device</data> <data key=\"dl_addr\">a0:b3:cc:9c:c6:88</data> <data key=\"nw_addr\">192.168.20.1</data> </node> <node id=\"1004\"> <data key=\"type\">device</data> <data key=\"dl_addr\">00:04:20:e2:50:a2</data> <data key=\"nw_addr\">192.168.30.1</data> </node> <node id=\"1005\"> <data key=\"type\">device</data> <data key=\"dl_addr\">58:55:ca:c4:1b:a0</data> <data key=\"nw_addr\">192.168.40.1</data> </node> <edge id=\"10000\" source=\"1\" target=\"101\" label=\"on\"></edge> <edge id=\"10001\" source=\"1\" target=\"102\" label=\"on\"></edge> <edge id=\"10002\" source=\"1\" target=\"103\" label=\"on\"></edge> <edge id=\"10003\" source=\"2\" target=\"104\" label=\"on\"></edge> <edge id=\"10004\" source=\"2\" target=\"105\" label=\"on\"></edge> <edge id=\"10005\" source=\"2\" target=\"106\" label=\"on\"></edge> <edge id=\"10006\" source=\"3\" target=\"107\" label=\"on\"></edge> <edge id=\"10007\" source=\"3\" target=\"108\" label=\"on\"></edge> <edge id=\"10008\" source=\"3\" target=\"109\" label=\"on\"></edge> <edge id=\"10009\" source=\"3\" target=\"110\" label=\"on\"></edge> <edge id=\"10010\" source=\"4\" target=\"111\" label=\"on\"></edge> <edge id=\"10011\" source=\"4\" target=\"112\" label=\"on\"></edge> <edge id=\"10012\" source=\"4\" target=\"113\" label=\"on\"></edge> <edge id=\"10013\" source=\"5\" target=\"114\" label=\"on\"></edge> <edge id=\"10014\" source=\"5\" target=\"115\" label=\"on\"></edge> <edge id=\"10015\" source=\"5\" target=\"116\" label=\"on\"></edge> <edge id=\"10016\" source=\"6\" target=\"117\" label=\"on\"></edge> <edge id=\"10017\" source=\"6\" target=\"118\" label=\"on\"></edge> <edge id=\"10018\" source=\"6\" target=\"119\" label=\"on\"></edge> <edge id=\"11000\" source=\"101\" target=\"107\" label=\"link\"></edge> <edge id=\"11003\" source=\"105\" target=\"111\" label=\"link\"></edge> <edge id=\"11004\" source=\"107\" target=\"101\" label=\"link\"></edge> <edge id=\"11005\" source=\"108\" target=\"112\" label=\"link\"></edge> <edge id=\"11006\" source=\"109\" target=\"114\" label=\"link\"></edge> <edge id=\"11007\" source=\"111\" target=\"105\" label=\"link\"></edge> <edge id=\"11008\" source=\"112\" target=\"108\" label=\"link\"></edge> <edge id=\"11009\" source=\"113\" target=\"117\" label=\"link\"></edge> <edge id=\"11010\" source=\"114\" target=\"109\" label=\"link\"></edge> <edge id=\"11011\" source=\"115\" target=\"118\" label=\"link\"></edge> <edge id=\"11012\" source=\"117\" target=\"113\" label=\"link\"></edge> <edge id=\"11013\" source=\"118\" target=\"115\" label=\"link\"></edge> <edge id=\"12000\" source=\"103\" target=\"1000\" label=\"host\"></edge> <edge id=\"12001\" source=\"103\" target=\"1001\" label=\"host\"></edge> <edge id=\"12002\" source=\"110\" target=\"1002\" label=\"host\"></edge> <edge id=\"12003\" source=\"116\" target=\"1003\" label=\"host\"></edge> <edge id=\"12004\" source=\"106\" target=\"1004\" label=\"host\"></edge> <edge id=\"12005\" source=\"119\" target=\"1005\" label=\"host\"></edge> </graph> </graphml>
\ No newline at end of file
+<?xml version=\"1.0\" ?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"> <key id=\"id\" for=\"node\" attr.name=\"id\" attr.type=\"string\"></key> <key id=\"type\" for=\"node\" attr.name=\"type\" attr.type=\"string\"></key> <key id=\"dpid\" for=\"node\" attr.name=\"dpid\" attr.type=\"string\"></key> <key id=\"desc\" for=\"node\" attr.name=\"desc\" attr.type=\"string\"></key> <key id=\"number\" for=\"node\" attr.name=\"number\" attr.type=\"int\"></key> <key id=\"dl_add\" for=\"node\" attr.name=\"dl_addr\" attr.type=\"string\"></key> <key id=\"nw_addr\" for=\"node\" attr.name=\"nw_addr\" attr.type=\"string\"></key> <key id=\"id\" for=\"edge\" attr.name=\"id\" attr.type=\"string\"></key> <key id=\"source\" for=\"edge\" attr.name=\"source\" attr.type=\"string\"></key> <key id=\"target\" for=\"edge\" attr.name=\"target\" attr.type=\"string\"></key> <key id=\"label\" for=\"edge\" attr.name=\"label\" attr.type=\"string\"></key> <graph id=\"G\" edgedefault=\"directed\"> <node id=\"1\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:01</data> <data key=\"desc\">OpenFlow Switch at SEA</data> </node> <node id=\"2\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:02</data> <data key=\"desc\">OpenFlow Switch at LAX</data> </node> <node id=\"3\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:03</data> <data key=\"desc\">OpenFlow Switch at CHI</data> </node> <node id=\"4\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:04</data> <data key=\"desc\">OpenFlow Switch at IAH</data> </node> <node id=\"5\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:05</data> <data key=\"desc\">OpenFlow Switch at NYC</data> </node> <node id=\"6\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:06</data> <data key=\"desc\">OpenFlow Switch at ATL</data> </node> <node id=\"100\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at SEA Switch</data> </node> <node id=\"101\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at SEA Switch</data> </node> <node id=\"102\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at SEA Switch</data> </node> <node id=\"103\"> <data key=\"type\">port</data> <data key=\"number\">4</data> <data key=\"desc\">port 4 at SEA Switch</data> </node> <node id=\"104\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at LAX Switch</data> </node> <node id=\"105\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at LAX Switch</data> </node> <node id=\"106\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at LAX Switch</data> </node> <node id=\"107\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at CHI Switch</data> </node> <node id=\"108\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at CHI Switch</data> </node> <node id=\"109\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at CHI Switch</data> </node> <node id=\"110\"> <data key=\"type\">port</data> <data key=\"number\">4</data> <data key=\"desc\">port 4 at CHI Switch</data> </node> <node id=\"111\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at IAH Switch</data> </node> <node id=\"112\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at IAH Switch</data> </node> <node id=\"113\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at IAH Switch</data> </node> <node id=\"114\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at NYC Switch</data> </node> <node id=\"115\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at NYC Switch</data> </node> <node id=\"116\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at NYC Switch</data> </node> <node id=\"117\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at ATL Switch</data> </node> <node id=\"118\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at ATL Switch</data> </node> <node id=\"119\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at ATL Switch</data> </node> <node id=\"1000\"> <data key=\"type\">device</data> <data key=\"dl_addr\">20:c9:d0:4a:e1:73</data> <data key=\"nw_addr\">192.168.10.101</data> </node> <node id=\"1001\"> <data key=\"type\">device</data> <data key=\"dl_addr\">20:c9:d0:4a:e1:62</data> <data key=\"nw_addr\">192.168.20.101</data> </node> <node id=\"1002\"> <data key=\"type\">device</data> <data key=\"dl_addr\">10:40:f3:e6:8d:55</data> <data key=\"nw_addr\">192.168.10.1</data> </node> <node id=\"1003\"> <data key=\"type\">device</data> <data key=\"dl_addr\">a0:b3:cc:9c:c6:88</data> <data key=\"nw_addr\">192.168.20.1</data> </node> <node id=\"1004\"> <data key=\"type\">device</data> <data key=\"dl_addr\">00:04:20:e2:50:a2</data> <data key=\"nw_addr\">192.168.30.1</data> </node> <node id=\"1005\"> <data key=\"type\">device</data> <data key=\"dl_addr\">58:55:ca:c4:1b:a0</data> <data key=\"nw_addr\">192.168.40.1</data> </node> <edge id=\"10000\" source=\"1\" target=\"101\" label=\"on\"></edge> <edge id=\"10001\" source=\"1\" target=\"102\" label=\"on\"></edge> <edge id=\"10002\" source=\"1\" target=\"103\" label=\"on\"></edge> <edge id=\"10003\" source=\"2\" target=\"104\" label=\"on\"></edge> <edge id=\"10004\" source=\"2\" target=\"105\" label=\"on\"></edge> <edge id=\"10005\" source=\"2\" target=\"106\" label=\"on\"></edge> <edge id=\"10006\" source=\"3\" target=\"107\" label=\"on\"></edge> <edge id=\"10007\" source=\"3\" target=\"108\" label=\"on\"></edge> <edge id=\"10008\" source=\"3\" target=\"109\" label=\"on\"></edge> <edge id=\"10009\" source=\"3\" target=\"110\" label=\"on\"></edge> <edge id=\"10010\" source=\"4\" target=\"111\" label=\"on\"></edge> <edge id=\"10011\" source=\"4\" target=\"112\" label=\"on\"></edge> <edge id=\"10012\" source=\"4\" target=\"113\" label=\"on\"></edge> <edge id=\"10013\" source=\"5\" target=\"114\" label=\"on\"></edge> <edge id=\"10014\" source=\"5\" target=\"115\" label=\"on\"></edge> <edge id=\"10015\" source=\"5\" target=\"116\" label=\"on\"></edge> <edge id=\"10016\" source=\"6\" target=\"117\" label=\"on\"></edge> <edge id=\"10017\" source=\"6\" target=\"118\" label=\"on\"></edge> <edge id=\"10018\" source=\"6\" target=\"119\" label=\"on\"></edge> <edge id=\"11000\" source=\"101\" target=\"107\" label=\"link\"></edge> <edge id=\"11003\" source=\"105\" target=\"111\" label=\"link\"></edge> <edge id=\"11004\" source=\"107\" target=\"101\" label=\"link\"></edge> <edge id=\"11005\" source=\"108\" target=\"112\" label=\"link\"></edge> <edge id=\"11006\" source=\"109\" target=\"114\" label=\"link\"></edge> <edge id=\"11007\" source=\"111\" target=\"105\" label=\"link\"></edge> <edge id=\"11008\" source=\"112\" target=\"108\" label=\"link\"></edge> <edge id=\"11009\" source=\"113\" target=\"117\" label=\"link\"></edge> <edge id=\"11010\" source=\"114\" target=\"109\" label=\"link\"></edge> <edge id=\"11011\" source=\"115\" target=\"118\" label=\"link\"></edge> <edge id=\"11012\" source=\"117\" target=\"113\" label=\"link\"></edge> <edge id=\"11013\" source=\"118\" target=\"115\" label=\"link\"></edge> <edge id=\"12000\" source=\"103\" target=\"1000\" label=\"host\"></edge> <edge id=\"12001\" source=\"103\" target=\"1001\" label=\"host\"></edge> <edge id=\"12002\" source=\"110\" target=\"1002\" label=\"host\"></edge> <edge id=\"12003\" source=\"116\" target=\"1003\" label=\"host\"></edge> <edge id=\"12004\" source=\"106\" target=\"1004\" label=\"host\"></edge> <edge id=\"12005\" source=\"119\" target=\"1005\" label=\"host\"></edge> </graph> </graphml>
diff --git a/titan/schema/test-network.xml b/titan/schema/test-network.xml
index a03a99c..630c5da 100644
--- a/titan/schema/test-network.xml
+++ b/titan/schema/test-network.xml
@@ -3,6 +3,7 @@
<key id="id" for="node" attr.name="id" attr.type="string"></key>
<key id="type" for="node" attr.name="type" attr.type="string"></key>
+ <key id="state" for="node" attr.name="state" attr.type="string"></key>
<key id="dpid" for="node" attr.name="dpid" attr.type="string"></key>
<key id="desc" for="node" attr.name="desc" attr.type="string"></key>
<key id="number" for="node" attr.name="number" attr.type="int"></key>
@@ -17,31 +18,37 @@
<node id="1">
<data key="type">switch</data>
<data key="dpid">00:00:00:00:00:00:0a:01</data>
+ <data key="state">ACTIVE</data>
<data key="desc">OpenFlow Switch at SEA</data>
</node>
<node id="2">
<data key="type">switch</data>
<data key="dpid">00:00:00:00:00:00:0a:02</data>
+ <data key="state">ACTIVE</data>
<data key="desc">OpenFlow Switch at LAX</data>
</node>
<node id="3">
<data key="type">switch</data>
<data key="dpid">00:00:00:00:00:00:0a:03</data>
+ <data key="state">ACTIVE</data>
<data key="desc">OpenFlow Switch at CHI</data>
</node>
<node id="4">
<data key="type">switch</data>
<data key="dpid">00:00:00:00:00:00:0a:04</data>
+ <data key="state">ACTIVE</data>
<data key="desc">OpenFlow Switch at IAH</data>
</node>
<node id="5">
<data key="type">switch</data>
<data key="dpid">00:00:00:00:00:00:0a:05</data>
+ <data key="state">ACTIVE</data>
<data key="desc">OpenFlow Switch at NYC</data>
</node>
<node id="6">
<data key="type">switch</data>
<data key="dpid">00:00:00:00:00:00:0a:06</data>
+ <data key="state">ACTIVE</data>
<data key="desc">OpenFlow Switch at ATL</data>
</node>
@@ -234,4 +241,4 @@
<edge id="12004" source="106" target="1004" label="host"></edge>
<edge id="12005" source="119" target="1005" label="host"></edge>
</graph>
-</graphml>
\ No newline at end of file
+</graphml>
diff --git a/web/add_flow.py b/web/add_flow.py
index 4f502f6..8100f22 100755
--- a/web/add_flow.py
+++ b/web/add_flow.py
@@ -129,8 +129,9 @@
my_dst_port = my_args[5]
#
- # Extract the "match" and "action" arguments
+ # Extract the "flowPathFlags", "match" and "action" arguments
#
+ flowPathFlags = 0L
match = {}
matchInPortEnabled = True # NOTE: Enabled by default
actions = []
@@ -149,7 +150,12 @@
arg2 = my_args[idx]
idx = idx + 1
- if arg1 == "matchInPort":
+ if arg1 == "flowPathFlags":
+ if "DISCARD_FIRST_HOP_ENTRY" in arg2:
+ flowPathFlags = flowPathFlags + 0x1
+ if "KEEP_ONLY_FIRST_HOP_ENTRY" in arg2:
+ flowPathFlags = flowPathFlags + 0x2
+ elif arg1 == "matchInPort":
# Just mark whether inPort matching is enabled
matchInPortEnabled = arg2 in ['True', 'true']
# inPort = {}
@@ -166,21 +172,15 @@
dstMac['value'] = arg2
match['dstMac'] = dstMac
# match['matchDstMac'] = True
+ elif arg1 == "matchEthernetFrameType":
+ match['ethernetFrameType'] = int(arg2, 0)
+ # match['matchEthernetFrameType'] = True
elif arg1 == "matchVlanId":
match['vlanId'] = int(arg2, 0)
# match['matchVlanId'] = True
elif arg1 == "matchVlanPriority":
match['vlanPriority'] = int(arg2, 0)
# match['matchVlanPriority'] = True
- elif arg1 == "matchEthernetFrameType":
- match['ethernetFrameType'] = int(arg2, 0)
- # match['matchEthernetFrameType'] = True
- elif arg1 == "matchIpToS":
- match['ipToS'] = int(arg2, 0)
- # match['matchIpToS'] = True
- elif arg1 == "matchIpProto":
- match['ipProto'] = int(arg2, 0)
- # match['matchIpProto'] = True
elif arg1 == "matchSrcIPv4Net":
srcIPv4Net = {}
srcIPv4Net['value'] = arg2
@@ -191,6 +191,12 @@
dstIPv4Net['value'] = arg2
match['dstIPv4Net'] = dstIPv4Net
# match['matchDstIPv4Net'] = True
+ elif arg1 == "matchIpProto":
+ match['ipProto'] = int(arg2, 0)
+ # match['matchIpProto'] = True
+ elif arg1 == "matchIpToS":
+ match['ipToS'] = int(arg2, 0)
+ # match['matchIpToS'] = True
elif arg1 == "matchSrcTcpUdpPort":
match['srcTcpUdpPort'] = int(arg2, 0)
# match['matchSrcTcpUdpPort'] = True
@@ -198,18 +204,19 @@
match['dstTcpUdpPort'] = int(arg2, 0)
# match['matchDstTcpUdpPort'] = True
elif arg1 == "actionOutput":
- # Just mark whether ACTION_OUTPUT action is enabled
+ # Mark whether ACTION_OUTPUT action is enabled
actionOutputEnabled = arg2 in ['True', 'true']
- #
- # TODO: Complete the implementation for ACTION_OUTPUT
- # actionOutput = {}
- # outPort = {}
- # outPort['value'] = int(arg2, 0)
- # actionOutput['port'] = outPort
- # actionOutput['maxLen'] = int(arg3, 0)
- # action['actionOutput'] = actionOutput
- # # action['actionType'] = 'ACTION_OUTPUT'
- # actions.append(action)
+ # If ACTION_OUTPUT is explicitly enabled, add an entry with a fake
+ # port number. We need this entry to preserve the action ordering.
+ if actionOutputEnabled == True:
+ actionOutput = {}
+ outPort = {}
+ outPort['value'] = 0xffff
+ actionOutput['port'] = outPort
+ actionOutput['maxLen'] = 0
+ action['actionOutput'] = actionOutput
+ # action['actionType'] = 'ACTION_OUTPUT'
+ actions.append(action)
#
elif arg1 == "actionSetVlanId":
vlanId = {}
@@ -223,24 +230,6 @@
action['actionSetVlanPriority'] = vlanPriority
# action['actionType'] = 'ACTION_SET_VLAN_PCP'
actions.append(copy.deepcopy(action))
- elif arg1 == "actionSetIpToS":
- ipToS = {}
- ipToS['ipToS'] = int(arg2, 0)
- action['actionSetIpToS'] = ipToS
- # action['actionType'] = 'ACTION_SET_NW_TOS'
- actions.append(copy.deepcopy(action))
- elif arg1 == "actionSetTcpUdpSrcPort":
- tcpUdpSrcPort = {}
- tcpUdpSrcPort['port'] = int(arg2, 0)
- action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
- # action['actionType'] = 'ACTION_SET_TP_SRC'
- actions.append(copy.deepcopy(action))
- elif arg1 == "actionSetTcpUdpDstPort":
- tcpUdpDstPort = {}
- tcpUdpDstPort['port'] = int(arg2, 0)
- action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
- # action['actionType'] = 'ACTION_SET_TP_DST'
- actions.append(copy.deepcopy(action))
elif arg1 == "actionStripVlan":
stripVlan = {}
stripVlan['stripVlan'] = arg2 in ['True', 'true']
@@ -279,6 +268,24 @@
action['actionSetIPv4DstAddr'] = setIPv4DstAddr
# action['actionType'] = 'ACTION_SET_NW_DST'
actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetIpToS":
+ ipToS = {}
+ ipToS['ipToS'] = int(arg2, 0)
+ action['actionSetIpToS'] = ipToS
+ # action['actionType'] = 'ACTION_SET_NW_TOS'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetTcpUdpSrcPort":
+ tcpUdpSrcPort = {}
+ tcpUdpSrcPort['port'] = int(arg2, 0)
+ action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
+ # action['actionType'] = 'ACTION_SET_TP_SRC'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetTcpUdpDstPort":
+ tcpUdpDstPort = {}
+ tcpUdpDstPort['port'] = int(arg2, 0)
+ action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
+ # action['actionType'] = 'ACTION_SET_TP_DST'
+ actions.append(copy.deepcopy(action))
elif arg1 == "actionEnqueue":
# TODO: Implement ACTION_ENQUEUE
actionEnqueue = {}
@@ -302,6 +309,7 @@
'my_src_port' : my_src_port,
'my_dst_dpid' : my_dst_dpid,
'my_dst_port' : my_dst_port,
+ 'flowPathFlags' : flowPathFlags,
'match' : match,
'matchInPortEnabled' : matchInPortEnabled,
'actions' : actions,
@@ -325,6 +333,7 @@
my_flow_id = parsed_args['my_flow_id']
my_installer_id = parsed_args['my_installer_id']
+ myFlowPathFlags = parsed_args['flowPathFlags']
match = parsed_args['match']
matchInPortEnabled = parsed_args['matchInPortEnabled']
actions = parsed_args['actions']
@@ -335,10 +344,15 @@
flow_id['value'] = my_flow_id
installer_id = {}
installer_id['value'] = my_installer_id
+ flowPathFlags = {}
+ flowPathFlags['flags'] = myFlowPathFlags
+
+ flowEntryActions = {}
flow_path = {}
flow_path['flowId'] = flow_id
flow_path['installerId'] = installer_id
+ flow_path['flowPathFlags'] = flowPathFlags
if (len(match) > 0):
flow_path['flowEntryMatch'] = copy.deepcopy(match)
@@ -356,6 +370,11 @@
my_data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
idx = idx + 1
+
+ if (len(actions) > 0):
+ flowEntryActions['actions'] = copy.deepcopy(actions)
+ flow_path['flowEntryActions'] = flowEntryActions
+
#
# Set the actions for each flow entry
# NOTE: The actions from the command line are aplied
@@ -377,11 +396,12 @@
action['actionOutput'] = copy.deepcopy(actionOutput)
# action['actionType'] = 'ACTION_OUTPUT'
actions.append(copy.deepcopy(action))
+ flowEntryActions = {}
+ flowEntryActions['actions'] = copy.deepcopy(actions)
- my_data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
+ my_data_path['flowEntries'][idx]['flowEntryActions'] = flowEntryActions
idx = idx + 1
-
flow_path['dataPath'] = my_data_path
debug("Flow Path: %s" % flow_path)
return flow_path
@@ -461,7 +481,7 @@
if __name__ == "__main__":
- usage_msg = "Usage: %s [Flags] <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Match Conditions] [Actions]\n" % (sys.argv[0])
+ usage_msg = "Usage: %s [Flags] <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Flow Path Flags] [Match Conditions] [Actions]\n" % (sys.argv[0])
usage_msg = usage_msg + "\n"
usage_msg = usage_msg + " Flags:\n"
usage_msg = usage_msg + " -m [monitorname] Monitor and maintain the installed shortest path(s)\n"
@@ -472,36 +492,40 @@
usage_msg = usage_msg + " -f <filename> Read the flow(s) to install from a file\n"
usage_msg = usage_msg + " File format: one line per flow starting with <flow-id>\n"
usage_msg = usage_msg + "\n"
+ usage_msg = usage_msg + " Flow Path Flags:\n"
+ usage_msg = usage_msg + " flowPathFlags <Flags> (flag names separated by ',')\n"
+ usage_msg = usage_msg + "\n"
+ usage_msg = usage_msg + " Known flags:\n"
+ usage_msg = usage_msg + " DISCARD_FIRST_HOP_ENTRY : Discard the first-hop flow entry\n"
+ usage_msg = usage_msg + " KEEP_ONLY_FIRST_HOP_ENTRY : Keep only the first-hop flow entry\n"
+ usage_msg = usage_msg + "\n"
usage_msg = usage_msg + " Match Conditions:\n"
usage_msg = usage_msg + " matchInPort <True|False> (default to True)\n"
usage_msg = usage_msg + " matchSrcMac <source MAC address>\n"
usage_msg = usage_msg + " matchDstMac <destination MAC address>\n"
- usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
- usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
usage_msg = usage_msg + " matchEthernetFrameType <Ethernet frame type>\n"
- usage_msg = usage_msg + "\n"
- usage_msg = usage_msg + " Match Conditions (not implemented yet):\n"
usage_msg = usage_msg + " matchVlanId <VLAN ID>\n"
usage_msg = usage_msg + " matchVlanPriority <VLAN priority>\n"
- usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
+ usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
+ usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
usage_msg = usage_msg + " matchIpProto <IP protocol>\n"
+ usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
usage_msg = usage_msg + " matchSrcTcpUdpPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " matchDstTcpUdpPort <destination TCP/UDP port>\n"
usage_msg = usage_msg + "\n"
usage_msg = usage_msg + " Actions:\n"
usage_msg = usage_msg + " actionOutput <True|False> (default to True)\n"
+ usage_msg = usage_msg + " actionSetVlanId <VLAN ID>\n"
+ usage_msg = usage_msg + " actionSetVlanPriority <VLAN priority>\n"
+ usage_msg = usage_msg + " actionStripVlan <True|False>\n"
usage_msg = usage_msg + " actionSetEthernetSrcAddr <source MAC address>\n"
usage_msg = usage_msg + " actionSetEthernetDstAddr <destination MAC address>\n"
usage_msg = usage_msg + " actionSetIPv4SrcAddr <source IPv4 address>\n"
usage_msg = usage_msg + " actionSetIPv4DstAddr <destination IPv4 address>\n"
- usage_msg = usage_msg + "\n"
- usage_msg = usage_msg + " Actions (not implemented yet):\n"
- usage_msg = usage_msg + " actionSetVlanId <VLAN ID>\n"
- usage_msg = usage_msg + " actionSetVlanPriority <VLAN priority>\n"
usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
- usage_msg = usage_msg + " actionStripVlan <True|False>\n"
+ usage_msg = usage_msg + " Actions (not implemented yet):\n"
usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
# app.debug = False;
diff --git a/web/config.json.dev.1node b/web/config.json.dev.1node
new file mode 100644
index 0000000..580a136
--- /dev/null
+++ b/web/config.json.dev.1node
@@ -0,0 +1,26 @@
+{
+ "LB": false,
+ "TESTBED": "sw",
+ "ONOS_DEFAULT_HOST": "localhost",
+ "ONOS_GUI3_CONTROL_HOST": "http://localhost:9000",
+ "ONOS_GUI3_HOST": "http://localhost:9000",
+ "cluster_basename": "onosdev",
+ "controllers": [
+ "onosdev1",
+ "onosdev1",
+ "onosdev1",
+ "onosdev1",
+ "onosdev1",
+ "onosdev1",
+ "onosdev1",
+ "onosdev1"
+ ],
+ "core_switches": [
+ "00:00:00:00:00:00:01:01",
+ "00:00:00:00:00:00:01:02",
+ "00:00:00:00:00:00:01:03",
+ "00:00:00:00:00:00:01:04",
+ "00:00:00:00:00:00:01:05",
+ "00:00:00:00:00:00:01:06"
+ ]
+}
diff --git a/web/config.json.devA b/web/config.json.devA
new file mode 100644
index 0000000..b20639e
--- /dev/null
+++ b/web/config.json.devA
@@ -0,0 +1,22 @@
+{
+ "LB": false,
+ "TESTBED": "sw",
+ "ONOS_DEFAULT_HOST": "localhost",
+ "ONOS_GUI3_CONTROL_HOST": "http://10.128.4.51:9000",
+ "ONOS_GUI3_HOST": "http://10.128.4.51:9000",
+ "cluster_basename": "ONOS",
+ "controllers": [
+ "DevA-ONOS1",
+ "DevA-ONOS2",
+ "DevA-ONOS3",
+ "DevA-ONOS4"
+ ],
+ "core_switches": [
+ "00:00:00:00:ba:5e:ba:11",
+ "00:00:00:00:00:00:ba:12",
+ "00:00:20:4e:7f:51:8a:35",
+ "00:00:00:00:ba:5e:ba:13",
+ "00:00:00:08:a2:08:f9:01",
+ "00:00:00:16:97:08:9a:46"
+ ]
+}
diff --git a/web/get_flow.py b/web/get_flow.py
index 033176d..9ab55da 100755
--- a/web/get_flow.py
+++ b/web/get_flow.py
@@ -33,78 +33,182 @@
# Sample output:
# {"flowId":{"value":"0x5"},"installerId":{"value":"FOOBAR"},"dataPath":{"srcPort":{"dpid":{"value":"00:00:00:00:00:00:00:01"},"port":{"value":0}},"dstPort":{"dpid":{"value":"00:00:00:00:00:00:00:02"},"port":{"value":0}},"flowEntries":[{"flowEntryId":"0x1389","flowEntryMatch":null,"flowEntryActions":null,"dpid":{"value":"00:00:00:00:00:00:00:01"},"inPort":{"value":0},"outPort":{"value":1},"flowEntryUserState":"FE_USER_DELETE","flowEntrySwitchState":"FE_SWITCH_NOT_UPDATED","flowEntryErrorState":null},{"flowEntryId":"0x138a","flowEntryMatch":null,"flowEntryActions":null,"dpid":{"value":"00:00:00:00:00:00:00:02"},"inPort":{"value":9},"outPort":{"value":0},"flowEntryUserState":"FE_USER_DELETE","flowEntrySwitchState":"FE_SWITCH_NOT_UPDATED","flowEntryErrorState":null}]}}
+def parse_match(match):
+ result = []
+
+ inPort = match['inPort']
+ matchInPort = match['matchInPort']
+ srcMac = match['srcMac']
+ matchSrcMac = match['matchSrcMac']
+ dstMac = match['dstMac']
+ matchDstMac = match['matchDstMac']
+ ethernetFrameType = match['ethernetFrameType']
+ matchEthernetFrameType = match['matchEthernetFrameType']
+ vlanId = match['vlanId']
+ matchVlanId = match['matchVlanId']
+ vlanPriority = match['vlanPriority']
+ matchVlanPriority = match['matchVlanPriority']
+ srcIPv4Net = match['srcIPv4Net']
+ matchSrcIPv4Net = match['matchSrcIPv4Net']
+ dstIPv4Net = match['dstIPv4Net']
+ matchDstIPv4Net = match['matchDstIPv4Net']
+ ipProto = match['ipProto']
+ matchIpProto = match['matchIpProto']
+ ipToS = match['ipToS']
+ matchIpToS = match['matchIpToS']
+ srcTcpUdpPort = match['srcTcpUdpPort']
+ matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
+ dstTcpUdpPort = match['dstTcpUdpPort']
+ matchDstTcpUdpPort = match['matchDstTcpUdpPort']
+ if matchInPort == True:
+ r = "inPort: %s" % inPort['value']
+ result.append(r)
+ if matchSrcMac == True:
+ r = "srcMac: %s" % srcMac['value']
+ result.append(r)
+ if matchDstMac == True:
+ r = "dstMac: %s" % dstMac['value']
+ result.append(r)
+ if matchEthernetFrameType == True:
+ r = "ethernetFrameType: %s" % hex(ethernetFrameType)
+ result.append(r)
+ if matchVlanId == True:
+ r = "vlanId: %s" % vlanId
+ result.append(r)
+ if matchVlanPriority == True:
+ r = "vlanPriority: %s" % vlanPriority
+ result.append(r)
+ if matchSrcIPv4Net == True:
+ r = "srcIPv4Net: %s" % srcIPv4Net['value']
+ result.append(r)
+ if matchDstIPv4Net == True:
+ r = "dstIPv4Net: %s" % dstIPv4Net['value']
+ result.append(r)
+ if matchIpProto == True:
+ r = "ipProto: %s" % ipProto
+ result.append(r)
+ if matchIpToS == True:
+ r = "ipToS: %s" % ipToS
+ result.append(r)
+ if matchSrcTcpUdpPort == True:
+ r = "srcTcpUdpPort: %s" % srcTcpUdpPort
+ result.append(r)
+ if matchDstTcpUdpPort == True:
+ r = "dstTcpUdpPort: %s" % dstTcpUdpPort
+ result.append(r)
+
+ return result
+
+
+def parse_actions(actions):
+ result = []
+ for a in actions:
+ actionType = a['actionType']
+ if actionType == "ACTION_OUTPUT":
+ port = a['actionOutput']['port']['value']
+ maxLen = a['actionOutput']['maxLen']
+ r = "actionType: %s port: %s maxLen: %s" % (actionType, port, maxLen)
+ result.append(r)
+ if actionType == "ACTION_SET_VLAN_VID":
+ vlanId = a['actionSetVlanId']['vlanId']
+ r = "actionType: %s vlanId: %s" % (actionType, vlanId)
+ result.append(r)
+ if actionType == "ACTION_SET_VLAN_PCP":
+ vlanPriority = a['actionSetVlanPriority']['vlanPriority']
+ r = "actionType: %s vlanPriority: %s" % (actionType, vlanPriority)
+ result.append(r)
+ if actionType == "ACTION_STRIP_VLAN":
+ stripVlan = a['actionStripVlan']['stripVlan']
+ r = "actionType: %s stripVlan: %s" % (actionType, stripVlan)
+ result.append(r)
+ if actionType == "ACTION_SET_DL_SRC":
+ setEthernetSrcAddr = a['actionSetEthernetSrcAddr']['addr']['value']
+ r = "actionType: %s setEthernetSrcAddr: %s" % (actionType, setEthernetSrcAddr)
+ result.append(r)
+ if actionType == "ACTION_SET_DL_DST":
+ setEthernetDstAddr = a['actionSetEthernetDstAddr']['addr']['value']
+ r = "actionType: %s setEthernetDstAddr: %s" % (actionType, setEthernetDstAddr)
+ result.append(r)
+ if actionType == "ACTION_SET_NW_SRC":
+ setIPv4SrcAddr = a['actionSetIPv4SrcAddr']['addr']['value']
+ r = "actionType: %s setIPv4SrcAddr: %s" % (actionType, setIPv4SrcAddr)
+ result.append(r)
+ if actionType == "ACTION_SET_NW_DST":
+ setIPv4DstAddr = a['actionSetIPv4DstAddr']['addr']['value']
+ r = "actionType: %s setIPv4DstAddr: %s" % (actionType, setIPv4DstAddr)
+ result.append(r)
+ if actionType == "ACTION_SET_NW_TOS":
+ setIpToS = a['actionSetIpToS']['ipToS']
+ r = "actionType: %s setIpToS: %s" % (actionType, setIpToS)
+ result.append(r)
+ if actionType == "ACTION_SET_TP_SRC":
+ setTcpUdpSrcPort = a['actionSetTcpUdpSrcPort']['port']
+ r = "actionType: %s setTcpUdpSrcPort: %s" % (actionType, setTcpUdpSrcPort)
+ result.append(r)
+ if actionType == "ACTION_SET_TP_DST":
+ setTcpUdpDstPort = a['actionSetTcpUdpDstPort']['port']
+ r = "actionType: %s setTcpUdpDstPort: %s" % (actionType, setTcpUdpDstPort)
+ result.append(r)
+ if actionType == "ACTION_ENQUEUE":
+ port = a['actionEnqueue']['port']['value']
+ queueId = a['actionEnqueue']['queueId']
+ r = "actionType: %s port: %s queueId: %s" % (actionType, port, queueId)
+ result.append(r)
+
+ return result
+
+
def print_flow_path(parsedResult):
flowId = parsedResult['flowId']['value']
installerId = parsedResult['installerId']['value']
+ flowPathFlags = parsedResult['flowPathFlags']['flags']
srcSwitch = parsedResult['dataPath']['srcPort']['dpid']['value']
srcPort = parsedResult['dataPath']['srcPort']['port']['value']
dstSwitch = parsedResult['dataPath']['dstPort']['dpid']['value']
dstPort = parsedResult['dataPath']['dstPort']['port']['value']
-
- print "FlowPath: (flowId = %s installerId = %s src = %s/%s dst = %s/%s)" % (flowId, installerId, srcSwitch, srcPort, dstSwitch, dstPort)
match = parsedResult['flowEntryMatch'];
+ actions = parsedResult['flowEntryActions']['actions']
+
+ flowPathFlagsStr = ""
+ if (flowPathFlags & 0x1):
+ if flowPathFlagsStr:
+ flowPathFlagsStr += ","
+ flowPathFlagsStr += "DISCARD_FIRST_HOP_ENTRY"
+ if (flowPathFlags & 0x2):
+ if flowPathFlagsStr:
+ flowPathFlagsStr += ","
+ flowPathFlagsStr += "KEEP_ONLY_FIRST_HOP_ENTRY"
+
+ print "FlowPath: (flowId = %s installerId = %s flowPathFlags = 0x%x(%s) src = %s/%s dst = %s/%s)" % (flowId, installerId, flowPathFlags, flowPathFlagsStr, srcSwitch, srcPort, dstSwitch, dstPort)
+
#
- # Print the common conditions
+ # Print the common match conditions
#
if match == None:
print " Match: %s" % (match)
else:
- # inPort = match['inPort']
- # matchInPort = match['matchInPort']
- srcMac = match['srcMac']
- matchSrcMac = match['matchSrcMac']
- dstMac = match['dstMac']
- matchDstMac = match['matchDstMac']
- vlanId = match['vlanId']
- matchVlanId = match['matchVlanId']
- vlanPriority = match['vlanPriority']
- matchVlanPriority = match['matchVlanPriority']
- ethernetFrameType = match['ethernetFrameType']
- matchEthernetFrameType = match['matchEthernetFrameType']
- ipToS = match['ipToS']
- matchIpToS = match['matchIpToS']
- ipProto = match['ipProto']
- matchIpProto = match['matchIpProto']
- srcIPv4Net = match['srcIPv4Net']
- matchSrcIPv4Net = match['matchSrcIPv4Net']
- dstIPv4Net = match['dstIPv4Net']
- matchDstIPv4Net = match['matchDstIPv4Net']
- srcTcpUdpPort = match['srcTcpUdpPort']
- matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
- dstTcpUdpPort = match['dstTcpUdpPort']
- matchDstTcpUdpPort = match['matchDstTcpUdpPort']
- # if matchInPort == True:
- # print " inPort: %s" % inPort['value']
- if matchSrcMac == True:
- print " srcMac: %s" % srcMac['value']
- if matchDstMac == True:
- print " dstMac: %s" % dstMac['value']
- if matchVlanId == True:
- print " vlanId: %s" % vlanId
- if matchVlanPriority == True:
- print " vlanPriority: %s" % vlanPriority
- if matchEthernetFrameType == True:
- print " ethernetFrameType: %s" % hex(ethernetFrameType)
- if matchIpToS == True:
- print " ipToS: %s" % ipToS
- if matchIpProto == True:
- print " ipProto: %s" % ipProto
- if matchSrcIPv4Net == True:
- print " srcIPv4Net: %s" % srcIPv4Net['value']
- if matchDstIPv4Net == True:
- print " dstIPv4Net: %s" % dstIPv4Net['value']
- if matchSrcTcpUdpPort == True:
- print " srcTcpUdpPort: %s" % srcTcpUdpPort
- if matchDstTcpUdpPort == True:
- print " dstTcpUdpPort: %s" % dstTcpUdpPort
+ parsedMatch = parse_match(match)
+ for l in parsedMatch:
+ print " %s" % l
+ #
+ # Print the actions
+ #
+ parsedActions = parse_actions(actions)
+ for l in parsedActions:
+ print " %s" % l
+
+ #
+ # Print each Flow Entry
+ #
for f in parsedResult['dataPath']['flowEntries']:
flowEntryId = f['flowEntryId']
dpid = f['dpid']['value']
userState = f['flowEntryUserState']
switchState = f['flowEntrySwitchState']
match = f['flowEntryMatch'];
- actions = f['flowEntryActions']
+ actions = f['flowEntryActions']['actions']
+
print " FlowEntry: (%s, %s, %s, %s)" % (flowEntryId, dpid, userState, switchState)
#
@@ -113,101 +217,16 @@
if match == None:
print " Match: %s" % (match)
else:
- inPort = match['inPort']
- matchInPort = match['matchInPort']
- srcMac = match['srcMac']
- matchSrcMac = match['matchSrcMac']
- dstMac = match['dstMac']
- matchDstMac = match['matchDstMac']
- vlanId = match['vlanId']
- matchVlanId = match['matchVlanId']
- vlanPriority = match['vlanPriority']
- matchVlanPriority = match['matchVlanPriority']
- ethernetFrameType = match['ethernetFrameType']
- matchEthernetFrameType = match['matchEthernetFrameType']
- ipToS = match['ipToS']
- matchIpToS = match['matchIpToS']
- ipProto = match['ipProto']
- matchIpProto = match['matchIpProto']
- srcIPv4Net = match['srcIPv4Net']
- matchSrcIPv4Net = match['matchSrcIPv4Net']
- dstIPv4Net = match['dstIPv4Net']
- matchDstIPv4Net = match['matchDstIPv4Net']
- srcTcpUdpPort = match['srcTcpUdpPort']
- matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
- dstTcpUdpPort = match['dstTcpUdpPort']
- matchDstTcpUdpPort = match['matchDstTcpUdpPort']
- if matchInPort == True:
- print " inPort: %s" % inPort['value']
- if matchSrcMac == True:
- print " srcMac: %s" % srcMac['value']
- if matchDstMac == True:
- print " dstMac: %s" % dstMac['value']
- if matchVlanId == True:
- print " vlanId: %s" % vlanId
- if matchVlanPriority == True:
- print " vlanPriority: %s" % vlanPriority
- if matchEthernetFrameType == True:
- print " ethernetFrameType: %s" % hex(ethernetFrameType)
- if matchIpToS == True:
- print " ipToS: %s" % ipToS
- if matchIpProto == True:
- print " ipProto: %s" % ipProto
- if matchSrcIPv4Net == True:
- print " srcIPv4Net: %s" % srcIPv4Net['value']
- if matchDstIPv4Net == True:
- print " dstIPv4Net: %s" % dstIPv4Net['value']
- if matchSrcTcpUdpPort == True:
- print " srcTcpUdpPort: %s" % srcTcpUdpPort
- if matchDstTcpUdpPort == True:
- print " dstTcpUdpPort: %s" % dstTcpUdpPort
-
+ parsedMatch = parse_match(match)
+ for l in parsedMatch:
+ print " %s" % l
#
# Print the actions
#
- if actions == None:
- print " Actions: %s" % (actions)
- else:
- for a in actions:
- actionType = a['actionType']
- if actionType == "ACTION_OUTPUT":
- port = a['actionOutput']['port']['value']
- maxLen = a['actionOutput']['maxLen']
- print " actionType: %s port: %s maxLen: %s" % (actionType, port, maxLen)
- if actionType == "ACTION_SET_VLAN_VID":
- vlanId = a['actionSetVlanId']['vlanId']
- print " actionType: %s vlanId: %s" % (actionType, vlanId)
- if actionType == "ACTION_SET_VLAN_PCP":
- vlanPriority = a['actionSetVlanPriority']['vlanPriority']
- print " actionType: %s vlanPriority: %s" % (actionType, vlanPriority)
- if actionType == "ACTION_STRIP_VLAN":
- stripVlan = a['actionStripVlan']['stripVlan']
- print " actionType: %s stripVlan: %s" % (actionType, stripVlan)
- if actionType == "ACTION_SET_DL_SRC":
- setEthernetSrcAddr = a['actionSetEthernetSrcAddr']['addr']['value']
- print " actionType: %s setEthernetSrcAddr: %s" % (actionType, setEthernetSrcAddr)
- if actionType == "ACTION_SET_DL_DST":
- setEthernetDstAddr = a['actionSetEthernetDstAddr']['addr']['value']
- print " actionType: %s setEthernetDstAddr: %s" % (actionType, setEthernetDstAddr)
- if actionType == "ACTION_SET_NW_SRC":
- setIPv4SrcAddr = a['actionSetIPv4SrcAddr']['addr']['value']
- print " actionType: %s setIPv4SrcAddr: %s" % (actionType, setIPv4SrcAddr)
- if actionType == "ACTION_SET_NW_DST":
- setIPv4DstAddr = a['actionSetIPv4DstAddr']['addr']['value']
- print " actionType: %s setIPv4DstAddr: %s" % (actionType, setIPv4DstAddr)
- if actionType == "ACTION_SET_NW_TOS":
- setIpToS = a['actionSetIpToS']['ipToS']
- print " actionType: %s setIpToS: %s" % (actionType, setIpToS)
- if actionType == "ACTION_SET_TP_SRC":
- setTcpUdpSrcPort = a['actionSetTcpUdpSrcPort']['port']
- print " actionType: %s setTcpUdpSrcPort: %s" % (actionType, setTcpUdpSrcPort)
- if actionType == "ACTION_SET_TP_DST":
- setTcpUdpDstPort = a['actionSetTcpUdpDstPort']['port']
- print " actionType: %s setTcpUdpDstPort: %s" % (actionType, setTcpUdpDstPort)
- if actionType == "ACTION_ENQUEUE":
- port = a['actionEnqueue']['port']['value']
- queueId = a['actionEnqueue']['queueId']
- print " actionType: %s port: %s queueId: %s" % (actionType, port, queueId)
+ parsedActions = parse_actions(actions)
+ for l in parsedActions:
+ print " %s" % l
+
def get_flow_path(flow_id):
try:
diff --git a/web/log b/web/log
deleted file mode 100644
index e69de29..0000000
--- a/web/log
+++ /dev/null
diff --git a/web/measurement_get_per_flow_install_time.py b/web/measurement_get_per_flow_install_time.py
new file mode 100755
index 0000000..bf2bcc7
--- /dev/null
+++ b/web/measurement_get_per_flow_install_time.py
@@ -0,0 +1,61 @@
+#! /usr/bin/env python
+# -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
+
+import pprint
+import os
+import sys
+import subprocess
+import json
+import argparse
+import io
+import time
+
+from flask import Flask, json, Response, render_template, make_response, request
+
+#
+# TODO: remove this! We don't use JSON argument here!
+# curl http://127.0.0.1:8080/wm/flow/delete/{"value":"0xf"}/json'
+#
+
+## Global Var ##
+ControllerIP="127.0.0.1"
+ControllerPort=8080
+
+DEBUG=0
+pp = pprint.PrettyPrinter(indent=4)
+
+app = Flask(__name__)
+
+## Worker Functions ##
+def log_error(txt):
+ print '%s' % (txt)
+
+def debug(txt):
+ if DEBUG:
+ print '%s' % (txt)
+
+# @app.route("/wm/flow/measurement-get-per-flow-install-time/json")
+def measurement_get_per_flow_install_time():
+ command = "curl -s \"http://%s:%s/wm/flow/measurement-get-per-flow-install-time/json\"" % (ControllerIP, ControllerPort)
+ debug("measurement_get_per_flow_install_time %s" % command)
+ result = os.popen(command).read()
+ print '%s' % (result)
+ # parsedResult = json.loads(result)
+ # debug("parsed %s" % parsedResult)
+
+if __name__ == "__main__":
+ usage_msg = "Get the measured time per flow to install each stored flow path\n"
+ usage_msg = usage_msg + "Usage: %s\n" % (sys.argv[0])
+ usage_msg = usage_msg + "\n"
+
+ # app.debug = False;
+
+ # Usage info
+ if len(sys.argv) > 1 and (sys.argv[1] == "-h" or sys.argv[1] == "--help"):
+ print(usage_msg)
+ exit(0)
+
+ # Check arguments
+
+ # Do the work
+ measurement_get_per_flow_install_time()
diff --git a/web/measurement_process.py b/web/measurement_process.py
new file mode 100755
index 0000000..3187299
--- /dev/null
+++ b/web/measurement_process.py
@@ -0,0 +1,59 @@
+#! /usr/bin/env python
+# -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
+
+import functools
+import math
+import sys
+
+## {{{ http://code.activestate.com/recipes/511478/ (r1)
+
+def percentile(N, percent, key=lambda x:x):
+ """
+ Find the percentile of a list of values.
+
+ @parameter N - is a list of values. Note N MUST BE already sorted.
+ @parameter percent - a float value from 0.0 to 1.0.
+ @parameter key - optional key function to compute value from each element of N.
+
+ @return - the percentile of the values
+ """
+ if not N:
+ return None
+ k = (len(N)-1) * percent
+ f = math.floor(k)
+ c = math.ceil(k)
+ if f == c:
+ return key(N[int(k)])
+ d0 = key(N[int(f)]) * (c-k)
+ d1 = key(N[int(c)]) * (k-f)
+ return d0+d1
+
+# median is 50th percentile.
+# median = functools.partial(percentile, percent=0.5)
+## end of http://code.activestate.com/recipes/511478/ }}}
+
+if __name__ == "__main__":
+
+ dict = {}
+
+ #
+ # Read the data from the stdin, and store it in a dictionary.
+ # The dictionary uses lists as values.
+ #
+ data = sys.stdin.readlines()
+ for line in data:
+ words = line.split()
+ thread_n = int(words[0])
+ msec = float(words[1])
+ dict.setdefault(thread_n, []).append(msec)
+
+ #
+ # Compute and print the values: median (50-th), 10-th, and 90-th
+ # percentile:
+ # <key> <median> <10-percentile> <90-percentile>
+ #
+ for key, val_list in sorted(dict.items()):
+ val_10 = percentile(sorted(val_list), 0.1)
+ val_50 = percentile(sorted(val_list), 0.5)
+ val_90 = percentile(sorted(val_list), 0.9)
+ print "%s %s %s %s" % (str(key), str(val_50), str(val_10), str(val_90))
diff --git a/web/measurement_run.py b/web/measurement_run.py
new file mode 100755
index 0000000..80d0517
--- /dev/null
+++ b/web/measurement_run.py
@@ -0,0 +1,104 @@
+#! /usr/bin/env python
+# -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
+
+import os
+import string
+import subprocess
+import time
+
+# flow_n = 252
+# threads_n = [1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 100]
+# iterations_n = 10
+
+flow_n = 1
+threads_n = [1]
+iterations_n = 10
+# iterations_n = 100
+
+# flow_n = 42
+# flow_n = 420
+# flow_n = 1008
+
+def run_command(cmd):
+ """
+ - Run an external command, and return a tuple: stdout as the
+ first argument, and stderr as the second argument.
+ - Returns None if error.
+ """
+ try:
+ pr = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
+ ret_tuple = pr.communicate();
+ if pr.returncode:
+ print "%s failed with error code: %s" % (cmd, str(pr.returncode))
+ return ret_tuple
+ except OSError:
+ print "OS Error running %s" % cmd
+
+def run_install_paths(flowdef_filename):
+ # Prepare the flows to measure
+ cmd = "web/measurement_store_flow.py -f " + flowdef_filename
+ os.system(cmd)
+
+def run_measurement(thread_n):
+ # Install the Flow Paths
+ cmd = ["web/measurement_install_paths.py", str(thread_n)]
+ run_command(cmd)
+
+ # Get the measurement data and print it
+ cmd = "web/measurement_get_install_paths_time_nsec.py"
+ r = run_command(cmd) # Tuple: [<stdout>, <stderr>]
+ res = r[0].split() # Tuple: [<num>, nsec]
+ nsec_str = res[0]
+ msec = float(nsec_str) / (1000 * 1000)
+
+ # Get the measurement data and print it
+ cmd = "web/measurement_get_per_flow_install_time.py"
+ r = run_command(cmd) # Tuple: [<stdout>, <stderr>]
+ res = r[0]
+ print res
+
+ # Keep checking until all Flow Paths are installed
+ while True:
+ # time.sleep(3)
+ cmd = ["web/get_flow.py", "all"]
+ r = run_command(cmd)
+ if string.count(r[0], "FlowPath") != flow_n:
+ continue
+ if string.find(r[0], "NOT") == -1:
+ break
+
+ # Remove the installed Flow Paths
+ cmd = ["web/delete_flow.py", "all"]
+ run_command(cmd)
+
+ # Keep checking until all Flows are removed
+ while True:
+ # time.sleep(3)
+ cmd = ["web/get_flow.py", "all"]
+ r = run_command(cmd)
+ if r[0] == "":
+ break
+
+ return msec
+
+
+if __name__ == "__main__":
+
+ # Initial cleanup
+ cmd = "web/measurement_clear_all_paths.py"
+ run_command(cmd)
+
+ # Install the Flow Paths to measure
+ flowdef_filename = "web/flowdef_8node_" + str(flow_n) + ".txt"
+ run_install_paths(flowdef_filename)
+
+ # Do the work
+ for thread_n in threads_n:
+ for n in range(iterations_n):
+ msec = run_measurement(thread_n)
+ # Format: <number of threads> <time in ms>
+ print "%d %f" % (thread_n, msec / flow_n)
+
+ # Cleanup on exit
+ cmd = "web/measurement_clear_all_paths.py"
+ run_command(cmd)
diff --git a/web/measurement_store_flow.py b/web/measurement_store_flow.py
index 637ab3e..0e39465 100755
--- a/web/measurement_store_flow.py
+++ b/web/measurement_store_flow.py
@@ -60,8 +60,9 @@
my_dst_port = my_args[5]
#
- # Extract the "match" and "action" arguments
+ # Extract the "flowPathFlags", "match" and "action" arguments
#
+ flowPathFlags = 0L
match = {}
matchInPortEnabled = True # NOTE: Enabled by default
actions = []
@@ -80,8 +81,13 @@
arg2 = my_args[idx]
idx = idx + 1
- if arg1 == "matchInPort":
- # Just mark whether inPort matching is enabled
+ if arg1 == "flowPathFlags":
+ if "DISCARD_FIRST_HOP_ENTRY" in arg2:
+ flowPathFlags = flowPathFlags + 0x1
+ if "KEEP_ONLY_FIRST_HOP_ENTRY" in arg2:
+ flowPathFlags = flowPathFlags + 0x2
+ elif arg1 == "matchInPort":
+ # Mark whether ACTION_OUTPUT action is enabled
matchInPortEnabled = arg2 in ['True', 'true']
# inPort = {}
# inPort['value'] = int(arg2, 0)
@@ -97,21 +103,15 @@
dstMac['value'] = arg2
match['dstMac'] = dstMac
# match['matchDstMac'] = True
+ elif arg1 == "matchEthernetFrameType":
+ match['ethernetFrameType'] = int(arg2, 0)
+ # match['matchEthernetFrameType'] = True
elif arg1 == "matchVlanId":
match['vlanId'] = int(arg2, 0)
# match['matchVlanId'] = True
elif arg1 == "matchVlanPriority":
match['vlanPriority'] = int(arg2, 0)
# match['matchVlanPriority'] = True
- elif arg1 == "matchEthernetFrameType":
- match['ethernetFrameType'] = int(arg2, 0)
- # match['matchEthernetFrameType'] = True
- elif arg1 == "matchIpToS":
- match['ipToS'] = int(arg2, 0)
- # match['matchIpToS'] = True
- elif arg1 == "matchIpProto":
- match['ipProto'] = int(arg2, 0)
- # match['matchIpProto'] = True
elif arg1 == "matchSrcIPv4Net":
srcIPv4Net = {}
srcIPv4Net['value'] = arg2
@@ -122,6 +122,12 @@
dstIPv4Net['value'] = arg2
match['dstIPv4Net'] = dstIPv4Net
# match['matchDstIPv4Net'] = True
+ elif arg1 == "matchIpProto":
+ match['ipProto'] = int(arg2, 0)
+ # match['matchIpProto'] = True
+ elif arg1 == "matchIpToS":
+ match['ipToS'] = int(arg2, 0)
+ # match['matchIpToS'] = True
elif arg1 == "matchSrcTcpUdpPort":
match['srcTcpUdpPort'] = int(arg2, 0)
# match['matchSrcTcpUdpPort'] = True
@@ -129,18 +135,19 @@
match['dstTcpUdpPort'] = int(arg2, 0)
# match['matchDstTcpUdpPort'] = True
elif arg1 == "actionOutput":
- # Just mark whether ACTION_OUTPUT action is enabled
+ # Mark whether ACTION_OUTPUT action is enabled
actionOutputEnabled = arg2 in ['True', 'true']
- #
- # TODO: Complete the implementation for ACTION_OUTPUT
- # actionOutput = {}
- # outPort = {}
- # outPort['value'] = int(arg2, 0)
- # actionOutput['port'] = outPort
- # actionOutput['maxLen'] = int(arg3, 0)
- # action['actionOutput'] = actionOutput
- # # action['actionType'] = 'ACTION_OUTPUT'
- # actions.append(action)
+ # If ACTION_OUTPUT is explicitly enabled, add an entry with a fake
+ # port number. We need this entry to preserve the action ordering.
+ if actionOutputEnabled == True:
+ actionOutput = {}
+ outPort = {}
+ outPort['value'] = 0xffff
+ actionOutput['port'] = outPort
+ actionOutput['maxLen'] = 0
+ action['actionOutput'] = actionOutput
+ # action['actionType'] = 'ACTION_OUTPUT'
+ actions.append(action)
#
elif arg1 == "actionSetVlanId":
vlanId = {}
@@ -154,24 +161,6 @@
action['actionSetVlanPriority'] = vlanPriority
# action['actionType'] = 'ACTION_SET_VLAN_PCP'
actions.append(copy.deepcopy(action))
- elif arg1 == "actionSetIpToS":
- ipToS = {}
- ipToS['ipToS'] = int(arg2, 0)
- action['actionSetIpToS'] = ipToS
- # action['actionType'] = 'ACTION_SET_NW_TOS'
- actions.append(copy.deepcopy(action))
- elif arg1 == "actionSetTcpUdpSrcPort":
- tcpUdpSrcPort = {}
- tcpUdpSrcPort['port'] = int(arg2, 0)
- action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
- # action['actionType'] = 'ACTION_SET_TP_SRC'
- actions.append(copy.deepcopy(action))
- elif arg1 == "actionSetTcpUdpDstPort":
- tcpUdpDstPort = {}
- tcpUdpDstPort['port'] = int(arg2, 0)
- action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
- # action['actionType'] = 'ACTION_SET_TP_DST'
- actions.append(copy.deepcopy(action))
elif arg1 == "actionStripVlan":
stripVlan = {}
stripVlan['stripVlan'] = arg2 in ['True', 'true']
@@ -210,6 +199,24 @@
action['actionSetIPv4DstAddr'] = setIPv4DstAddr
# action['actionType'] = 'ACTION_SET_NW_DST'
actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetIpToS":
+ ipToS = {}
+ ipToS['ipToS'] = int(arg2, 0)
+ action['actionSetIpToS'] = ipToS
+ # action['actionType'] = 'ACTION_SET_NW_TOS'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetTcpUdpSrcPort":
+ tcpUdpSrcPort = {}
+ tcpUdpSrcPort['port'] = int(arg2, 0)
+ action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
+ # action['actionType'] = 'ACTION_SET_TP_SRC'
+ actions.append(copy.deepcopy(action))
+ elif arg1 == "actionSetTcpUdpDstPort":
+ tcpUdpDstPort = {}
+ tcpUdpDstPort['port'] = int(arg2, 0)
+ action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
+ # action['actionType'] = 'ACTION_SET_TP_DST'
+ actions.append(copy.deepcopy(action))
elif arg1 == "actionEnqueue":
# TODO: Implement ACTION_ENQUEUE
actionEnqueue = {}
@@ -233,6 +240,7 @@
'my_src_port' : my_src_port,
'my_dst_dpid' : my_dst_dpid,
'my_dst_port' : my_dst_port,
+ 'flowPathFlags' : flowPathFlags,
'match' : match,
'matchInPortEnabled' : matchInPortEnabled,
'actions' : actions,
@@ -243,6 +251,7 @@
my_flow_id = parsed_args['my_flow_id']
my_installer_id = parsed_args['my_installer_id']
+ myFlowPathFlags = parsed_args['flowPathFlags']
match = parsed_args['match']
matchInPortEnabled = parsed_args['matchInPortEnabled']
actions = parsed_args['actions']
@@ -253,10 +262,15 @@
flow_id['value'] = my_flow_id
installer_id = {}
installer_id['value'] = my_installer_id
+ flowPathFlags = {}
+ flowPathFlags['flags'] = myFlowPathFlags
+
+ flowEntryActions = {}
flow_path = {}
flow_path['flowId'] = flow_id
flow_path['installerId'] = installer_id
+ flow_path['flowPathFlags'] = flowPathFlags
if (len(match) > 0):
flow_path['flowEntryMatch'] = copy.deepcopy(match)
@@ -274,6 +288,11 @@
my_data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
idx = idx + 1
+
+ if (len(actions) > 0):
+ flowEntryActions['actions'] = copy.deepcopy(actions)
+ flow_path['flowEntryActions'] = flowEntryActions
+
#
# Set the actions for each flow entry
# NOTE: The actions from the command line are aplied
@@ -295,11 +314,12 @@
action['actionOutput'] = copy.deepcopy(actionOutput)
# action['actionType'] = 'ACTION_OUTPUT'
actions.append(copy.deepcopy(action))
+ flowEntryActions = {}
+ flowEntryActions['actions'] = copy.deepcopy(actions)
- my_data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
+ my_data_path['flowEntries'][idx]['flowEntryActions'] = flowEntryActions
idx = idx + 1
-
flow_path['dataPath'] = my_data_path
debug("Flow Path: %s" % flow_path)
return flow_path
@@ -346,42 +366,46 @@
if __name__ == "__main__":
usage_msg = "Store Flow Paths into ONOS for measurement purpose.\n"
usage_msg = usage_msg + "\n"
- usage_msg = usage_msg + "Usage: %s [Flags] <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Match Conditions] [Actions]\n" % (sys.argv[0])
+ usage_msg = usage_msg + "Usage: %s [Flags] <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Flow Path Flags] [Match Conditions] [Actions]\n" % (sys.argv[0])
usage_msg = usage_msg + "\n"
usage_msg = usage_msg + " Flags:\n"
usage_msg = usage_msg + " -f <filename> Read the flow(s) to install from a file\n"
usage_msg = usage_msg + " File format: one line per flow starting with <flow-id>\n"
usage_msg = usage_msg + "\n"
+ usage_msg = usage_msg + " Flow Path Flags:\n"
+ usage_msg = usage_msg + " flowPathFlags <Flags> (flag names separated by ',')\n"
+ usage_msg = usage_msg + "\n"
+ usage_msg = usage_msg + " Known flags:\n"
+ usage_msg = usage_msg + " DISCARD_FIRST_HOP_ENTRY : Discard the first-hop flow entry\n"
+ usage_msg = usage_msg + " KEEP_ONLY_FIRST_HOP_ENTRY : Keep only the first-hop flow entry\n"
+ usage_msg = usage_msg + "\n"
usage_msg = usage_msg + " Match Conditions:\n"
usage_msg = usage_msg + " matchInPort <True|False> (default to True)\n"
usage_msg = usage_msg + " matchSrcMac <source MAC address>\n"
usage_msg = usage_msg + " matchDstMac <destination MAC address>\n"
- usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
- usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
usage_msg = usage_msg + " matchEthernetFrameType <Ethernet frame type>\n"
- usage_msg = usage_msg + "\n"
- usage_msg = usage_msg + " Match Conditions (not implemented yet):\n"
usage_msg = usage_msg + " matchVlanId <VLAN ID>\n"
usage_msg = usage_msg + " matchVlanPriority <VLAN priority>\n"
- usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
+ usage_msg = usage_msg + " matchSrcIPv4Net <source IPv4 network address>\n"
+ usage_msg = usage_msg + " matchDstIPv4Net <destination IPv4 network address>\n"
usage_msg = usage_msg + " matchIpProto <IP protocol>\n"
+ usage_msg = usage_msg + " matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
usage_msg = usage_msg + " matchSrcTcpUdpPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " matchDstTcpUdpPort <destination TCP/UDP port>\n"
usage_msg = usage_msg + "\n"
usage_msg = usage_msg + " Actions:\n"
usage_msg = usage_msg + " actionOutput <True|False> (default to True)\n"
+ usage_msg = usage_msg + " actionSetVlanId <VLAN ID>\n"
+ usage_msg = usage_msg + " actionSetVlanPriority <VLAN priority>\n"
+ usage_msg = usage_msg + " actionStripVlan <True|False>\n"
usage_msg = usage_msg + " actionSetEthernetSrcAddr <source MAC address>\n"
usage_msg = usage_msg + " actionSetEthernetDstAddr <destination MAC address>\n"
usage_msg = usage_msg + " actionSetIPv4SrcAddr <source IPv4 address>\n"
usage_msg = usage_msg + " actionSetIPv4DstAddr <destination IPv4 address>\n"
- usage_msg = usage_msg + "\n"
- usage_msg = usage_msg + " Actions (not implemented yet):\n"
- usage_msg = usage_msg + " actionSetVlanId <VLAN ID>\n"
- usage_msg = usage_msg + " actionSetVlanPriority <VLAN priority>\n"
usage_msg = usage_msg + " actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
usage_msg = usage_msg + " actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
usage_msg = usage_msg + " actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
- usage_msg = usage_msg + " actionStripVlan <True|False>\n"
+ usage_msg = usage_msg + " Actions (not implemented yet):\n"
usage_msg = usage_msg + " actionEnqueue <dummy argument>\n"
# app.debug = False;
diff --git a/web/onos-topology.html b/web/onos-topology.html
index 72e9fc4..d72c0e1 100644
--- a/web/onos-topology.html
+++ b/web/onos-topology.html
@@ -52,8 +52,8 @@
<div id="topology"></div>
<script type="text/javascript" src="js/controller-status.js"></script>
<script type="text/javascript">
-controller_status("http://gui3.onlab.us:8081/controller_status");
-gui("http://gui3.onlab.us:8081/topology");
+controller_status("controller_status");
+gui("topology");
</script>
</svg>
</body>
diff --git a/web/ons-demo/data/configuration.json.devA b/web/ons-demo/data/configuration.json.devA
new file mode 100644
index 0000000..f8a6e63
--- /dev/null
+++ b/web/ons-demo/data/configuration.json.devA
@@ -0,0 +1,78 @@
+{
+ "core": [
+ "00:00:00:08:a2:08:f9:01",
+ "00:00:00:00:ba:5e:ba:11",
+ "00:00:20:4e:7f:51:8a:35",
+ "00:00:00:00:00:00:ba:12",
+ "00:00:00:00:ba:5e:ba:13",
+ "00:00:00:16:97:08:9a:46"
+ ],
+ "aggregation": [
+ "00:00:00:00:00:00:02:01",
+ "00:00:00:00:00:00:03:01",
+ "00:00:00:00:00:00:04:01",
+ "00:00:00:00:00:00:05:01",
+ "00:00:00:00:00:00:06:01",
+ "00:00:00:00:00:00:07:01",
+ "00:00:00:00:00:00:08:01"
+ ],
+ "association": {
+ "00:00:20:4e:7f:51:8a:35": [
+ "00:00:00:00:00:00:07:01"
+ ],
+ "00:00:00:00:ba:5e:ba:13": [
+ "00:00:00:00:00:00:06:01"
+ ],
+ "00:00:00:08:a2:08:f9:01": [
+ "00:00:00:00:00:00:03:01"
+ ],
+ "00:00:00:00:00:00:ba:12": [
+ "00:00:00:00:00:00:04:01",
+ "00:00:00:00:00:00:05:01"
+ ],
+ "00:00:00:00:ba:5e:ba:11": [
+ "00:00:00:00:00:00:02:01"
+ ],
+ "00:00:00:16:97:08:9a:46": [
+ "00:00:00:00:00:00:08:01"
+ ]
+ },
+ "geo": {
+ "00:00:20:4e:7f:51:8a:35": {
+ "lat": 41.891033,
+ "lng": -87.628326,
+ "label": "CHI",
+ "fanOutAngle": 180
+ },
+ "00:00:00:00:ba:5e:ba:13": {
+ "lat": 47.611024,
+ "lng": -122.33242,
+ "label": "SEA",
+ "fanOutAngle": 270
+ },
+ "00:00:00:08:a2:08:f9:01": {
+ "lat": 33.758599,
+ "lng": -84.387360,
+ "label": "ATL",
+ "fanOutAngle": 5
+ },
+ "00:00:00:16:97:08:9a:46": {
+ "lat": 41.225925,
+ "lng": -74.00528,
+ "label": "NYC",
+ "fanOutAngle": 150
+ },
+ "00:00:00:00:ba:5e:ba:11": {
+ "lat": 37.901187,
+ "lng": -76.037163,
+ "label": "DC",
+ "fanOutAngle": 45
+ },
+ "00:00:00:00:00:00:ba:12": {
+ "lat": 34.102708,
+ "lng": -118.238983,
+ "label": "LA",
+ "fanOutAngle": 315
+ }
+ }
+}
diff --git a/web/ons-demo/data/controllers.json.dev b/web/ons-demo/data/controllers.json.dev
index 4abcf5a..b936d96 100644
--- a/web/ons-demo/data/controllers.json.dev
+++ b/web/ons-demo/data/controllers.json.dev
@@ -1,10 +1,10 @@
[
- "onosdevb1",
- "onosdevb2",
- "onosdevb3",
- "onosdevb4",
- "onosdevb5",
- "onosdevb6",
- "onosdevb7",
- "onosdevb8"
-]
\ No newline at end of file
+ "onosdev1",
+ "onosdev2",
+ "onosdev3",
+ "onosdev4",
+ "onosdev5",
+ "onosdev6",
+ "onosdev7",
+ "onosdev8"
+]
diff --git a/web/ons-demo/index.html b/web/ons-demo/index.html
index 5c1a650..ab13250 100644
--- a/web/ons-demo/index.html
+++ b/web/ons-demo/index.html
@@ -15,6 +15,7 @@
<div id='status'>
<div class='status'><span class='dynamic' id='activeFlows'>????</span><span class='static'>Flows</span></div>
<div class='status'><span class='dynamic' id='activeSwitches'>???</span><span class='static'>Active Switches</span></div>
+ <div class='status'><span class='dynamic' id='activeLinks'>???</span><span class='static'>Links</span></div>
</div>
<div id='lastUpdated' class='status'><span class='static'>Last updated:</span><span id='lastUpdate' class='dynamic'>Mon Mar 18 11:11:12 PDT 2013</span></div>
</div>
diff --git a/web/ons-demo/js/constants.js b/web/ons-demo/js/constants.js
index 51b3aa6..236d79a 100644
--- a/web/ons-demo/js/constants.js
+++ b/web/ons-demo/js/constants.js
@@ -2,7 +2,8 @@
timeout used by controller functions. after the timeout expires the "pending" action
is removed and the topology view is whatever is reported by the API
***************************************************************************************************/
-var pendingTimeout = 30000;
+/* var pendingTimeout = 30000; */
+var pendingTimeout = 60000;
/***************************************************************************************************
CSS names for the pallette of colors used by the topology view
@@ -27,4 +28,4 @@
edge: 6,
aggregation: 16,
core: 20
-}
\ No newline at end of file
+}
diff --git a/web/ons-demo/js/utils.js b/web/ons-demo/js/utils.js
index 68e567f..d7220c5 100644
--- a/web/ons-demo/js/utils.js
+++ b/web/ons-demo/js/utils.js
@@ -103,6 +103,7 @@
d3.select('#activeFlows').text(model.flows.length);
+ d3.select('#activeLinks').text(model.links.length);
}
/***************************************************************************************************
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 6c2ea15..ea33a00 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -13,9 +13,9 @@
from flask import Flask, json, Response, render_template, make_response, request
-
CONFIG_FILE=os.getenv("HOME") + "/ONOS/web/config.json"
LINK_FILE=os.getenv("HOME") + "/ONOS/web/link.json"
+ONOSDIR=os.getenv("HOME") + "/ONOS"
## Global Var for ON.Lab local REST ##
RestIP="localhost"
@@ -216,19 +216,6 @@
resp = Response(result, status=200, mimetype='application/json')
return resp
-@app.route("/proxy/gui/switchctrl/<cmd>")
-def proxy_switch_controller_setting(cmd):
- try:
- command = "curl -s %s/gui/switchctrl/%s" % (ONOS_GUI3_CONTROL_HOST, cmd)
- print command
- result = os.popen(command).read()
- except:
- print "REST IF has issue"
- exit
-
- resp = Response(result, status=200, mimetype='application/json')
- return resp
-
@app.route("/proxy/gui/reset")
def proxy_gui_reset():
result = ""
@@ -373,7 +360,8 @@
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
- sys.exit(0)
+ return
+# sys.exit(0)
topo = {}
switches = []
@@ -439,7 +427,8 @@
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
- sys.exit(0)
+ return
+# sys.exit(0)
for v in parsedResult:
link = {}
@@ -479,7 +468,8 @@
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
- sys.exit(0)
+ return
+# sys.exit(0)
topo = {}
switches = []
@@ -526,7 +516,8 @@
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
- sys.exit(0)
+ return
+# sys.exit(0)
for v in parsedResult:
link = {}
@@ -565,7 +556,8 @@
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
- sys.exit(0)
+ return
+# sys.exit(0)
# print command
# print result
@@ -594,7 +586,8 @@
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
- sys.exit(0)
+ return
+# sys.exit(0)
devices = []
for v in parsedResult:
@@ -656,7 +649,8 @@
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
- sys.exit(0)
+ return
+# sys.exit(0)
debug("query_links %s" % command)
# pp.pprint(parsedResult)
@@ -672,7 +666,8 @@
except:
log_error("REST IF has issue: %s" % command)
log_error("%s" % result)
- sys.exit(0)
+ return
+# sys.exit(0)
for p in linkResults:
if p.has_key('type') and p['type'] == "port":
@@ -697,14 +692,14 @@
@app.route("/controller_status")
def controller_status():
# onos_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh status | awk '{print $1}'"
- onos_check="cd; onos status %s | grep %s | awk '{print $2}'"
+ onos_check="cd; onos status | grep %s | awk '{print $2}'"
#cassandra_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-cassandra.sh status"
cont_status=[]
for i in controllers:
status={}
onos=os.popen(onos_check % i).read()[:-1]
- onos=os.popen(onos_check % (i, i.lower())).read()[:-1]
+# onos=os.popen(onos_check % (i, i.lower())).read()[:-1]
status["name"]=i
status["onos"]=onos
status["cassandra"]=0
@@ -724,8 +719,11 @@
# stop_onos="/home/admin/bin/onos stop %s > /tmp/debug " % (controller_name[-1:])
# print "Debug: Controller command %s called %s" % (cmd, controller_name)
else:
- start_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh start" % (controller_name)
- stop_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh stop" % (controller_name)
+ # No longer use -i to specify keys (use .ssh/config to specify it)
+ start_onos="ssh %s ONOS/start-onos.sh start" % (controller_name)
+ stop_onos="ssh %s ONOS/start-onos.sh stop" % (controller_name)
+# start_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh start" % (controller_name)
+# stop_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh stop" % (controller_name)
if cmd == "up":
result=os.popen(start_onos).read()
@@ -743,8 +741,8 @@
result=""
if (TESTBED == "sw"):
for i in range(1, len(controllers)):
- cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./ctrl-local.sh'" % (controllers[i])
- result += os.popen(cmd_string).read()
+ cmd_string="ssh %s 'cd ONOS/scripts; ./ctrl-local.sh'" % (controllers[i])
+ result += os.popen(cmd_string).read()
else:
cmd_string="cd; switch local > /tmp/watch"
result += os.popen(cmd_string).read()
@@ -753,7 +751,8 @@
result=""
if (TESTBED == "sw"):
for i in range(1, len(controllers)):
- cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./ctrl-add-ext.sh'" % (controllers[i])
+ cmd_string="ssh %s 'cd ONOS/scripts; ./ctrl-add-ext.sh'" % (controllers[i])
+# cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./ctrl-add-ext.sh'" % (controllers[i])
print "cmd is: "+cmd_string
result += os.popen(cmd_string).read()
else:
@@ -789,7 +788,8 @@
r = re.compile(':')
dpid = re.sub(r, '', dpid)
host=controllers[0]
- cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./switch.sh %s %s'" % (host, dpid, cmd)
+ cmd_string="ssh %s 'cd ONOS/scripts; ./switch.sh %s %s'" % (host, dpid, cmd)
+# cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./switch.sh %s %s'" % (host, dpid, cmd)
get_status="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./switch.sh %s'" % (host, dpid)
print "cmd_string"
@@ -829,7 +829,8 @@
else:
(port, dontcare) = get_link_ports(dpid, src_dpid)
- cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./link.sh %s %s %s'" % (host, dpid, port, cmd)
+# cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./link.sh %s %s %s'" % (host, dpid, port, cmd)
+ cmd_string="ssh %s 'cd ONOS/scripts; ./link.sh %s %s %s'" % (host, dpid, port, cmd)
print cmd_string
res=os.popen(cmd_string).read()
result = result + ' ' + res
@@ -936,7 +937,7 @@
host = controllers[hostid-1]
if (TESTBED == "sw"):
- cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./link.sh %s %s %s'" % (host, src_dpid, src_port, cmd)
+ cmd_string="ssh %s 'cd ONOS/scripts; ./link.sh %s %s %s'" % (host, src_dpid, src_port, cmd)
else:
if ( src_dpid == "00:00:00:08:a2:08:f9:01" ):
cmd_string="~/ONOS/scripts/link-hw.sh %s %s %s " % ( dst_dpid, dst_port, cmd)
@@ -957,11 +958,17 @@
url ="%s/wm/flow/getsummary/%s/%s/json" % (host, 0, 0)
(code, result) = get_json(url)
parsedResult = json.loads(result)
- flow_nr = int(parsedResult[-1]['flowId'], 16)
+ if len(parsedResult) > 0:
+ if parsedResult[-1].has_key('flowId'):
+ flow_nr = int(parsedResult[-1]['flowId'], 16)
+ else:
+ flow_nr = -1 # first flow
+ print "first flow"
+
flow_nr += 1
- command = "/home/ubuntu/ONOS/web/add_flow.py -m onos %d %s %s %s %s %s matchSrcMac %s matchDstMac %s" % (flow_nr, "dummy", src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC)
+ command = "%s/web/add_flow.py -m onos %d %s %s %s %s %s matchSrcMac %s matchDstMac %s" % (ONOSDIR, flow_nr, "dummy", src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC)
flow_nr += 1
- command1 = "/home/ubuntu/ONOS/web/add_flow.py -m onos %d %s %s %s %s %s matchSrcMac %s matchDstMac %s" % (flow_nr, "dummy", dst_dpid, dst_port, src_dpid, src_port, dstMAC, srcMAC)
+ command1 = "%s/web/add_flow.py -m onos %d %s %s %s %s %s matchSrcMac %s matchDstMac %s" % (ONOSDIR, flow_nr, "dummy", dst_dpid, dst_port, src_dpid, src_port, dstMAC, srcMAC)
print "add flow: %s, %s" % (command, command1)
errcode = os.popen(command).read()
errcode1 = os.popen(command1).read()
@@ -973,7 +980,7 @@
#http://localhost:9000/gui/delflow/<flow_id>
@app.route("/gui/delflow/<flow_id>")
def del_flow(flow_id):
- command = "/home/ubuntu/ONOS/web/delete_flow.py %s" % (flow_id)
+ command = "%/web/delete_flow.py %s" % (ONOSDIR, flow_id)
print command
errcode = os.popen(command).read()
return errcode
@@ -1027,7 +1034,7 @@
if TESTBED == "hw":
cmd_string="dsh -w %s 'cd ONOS/scripts; " % dst_host
else:
- cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; " % dst_host
+ cmd_string="ssh %s 'cd ONOS/scripts; " % dst_host
cmd_string += "./runiperf.sh %d %s %s %s:%s %s/%s/%s/%s'" % (flowId, src_dpid, dst_dpid, TESTBED, "svr", protocol, duration, interval, samples)
print cmd_string
os.popen(cmd_string)
@@ -1035,7 +1042,7 @@
if TESTBED == "hw":
cmd_string="dsh -w %s 'cd ONOS/scripts; " % src_host
else:
- cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts;" % src_host
+ cmd_string="ssh %s 'cd ONOS/scripts;" % src_host
cmd_string+="./runiperf.sh %d %s %s %s:%s %s/%s/%s/%s'" % (flowId, src_dpid, dst_dpid, TESTBED, "client", protocol, duration, interval, samples)
print cmd_string
os.popen(cmd_string)