Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONOS
Conflicts:
start-onos.sh
diff --git a/cluster-mgmt/bin/func.sh b/cluster-mgmt/bin/func.sh
index 05c2adb..9785e66 100755
--- a/cluster-mgmt/bin/func.sh
+++ b/cluster-mgmt/bin/func.sh
@@ -83,6 +83,10 @@
echo "Removing all data in db"
dsh -w ${basename}1 "cd $ONOS_DIR; ./scripts/cleanup-cassandra.sh"
;;
+ checkdb)
+ echo "Check DB Status"
+ dsh -w ${basename}1 "cd $ONOS_DIR; ./scripts/check-db-status.sh"
+ ;;
status)
echo "Checking Cassandra Status"
dsh -w ${basename}1 "cd $ONOS_DIR; ./start-cassandra.sh status"
diff --git a/cluster-mgmt/bin/start.sh b/cluster-mgmt/bin/start.sh
index dac6bb1..23fcde7 100755
--- a/cluster-mgmt/bin/start.sh
+++ b/cluster-mgmt/bin/start.sh
@@ -9,5 +9,11 @@
zk start
cassandra start
cassandra cleandb
+db_status=`cassandra checkdb |grep OK | wc -l`
+if [ $db_status != 1 ];then
+ echo $db_status
+ echo "Cassandra DB was screwed up. Need DB key drop"
+ exit
+fi
onos start
dsh -g $basename 'cd ONOS; ./ctrl-local.sh'
diff --git a/cluster-mgmt/bin/test-link-failure.sh b/cluster-mgmt/bin/test-link-failure.sh
new file mode 100755
index 0000000..6c5f128
--- /dev/null
+++ b/cluster-mgmt/bin/test-link-failure.sh
@@ -0,0 +1,55 @@
+#! /bin/sh
+basename=$ONOS_CLUSTER_BASENAME
+wait=10
+
+fdef="flowdef_8node_42.txt"
+
+function log()
+{
+ date > error.$1.$2.log
+ check_status.py >> error.$1.$2.log
+ dsh -w ${basename}1 "cd ONOS/web; ./get_flow.py all" >> error.$1.$2.log
+ dsh "cd ONOS/scripts; ./showflow.sh" >> error.$1.$2.log
+}
+
+echo "all links up"
+dsh -w ${basename}1 "cd ONOS/scripts; ./all-linkup.sh"
+echo "clean up flow"
+dsh -w ${basename}1 "cd ONOS/web; ./delete_flow.py 1 100"
+dsh -w ${basename}1 "cd ONOS/web; ./clear_flow.py 1 100"
+sleep 1
+dsh -w ${basename}1 "cd ONOS/web; ./get_flow.py all"
+dsh "cd ONOS/scripts; ./delflow.sh"
+echo "checkup status"
+check_status.py
+read -p "hit anykey> "
+
+echo "install pre-set flows"
+dsh -w ${basename}1 "cd ONOS/web; ./add_flow.py -m onos -f $fdef"
+sleep 6
+echo "check"
+dsh -w ${basename}1 "cd ONOS/web; ./pingall.py $fdef"
+
+#ports=`dsh -w ${basename}1 "cd ONOS/scripts; ./listports.sh" | awk '{print $2}' |grep -v tap`
+operation=("sw3-eth3 down" "sw4-eth4 down" "sw4-eth3 down" "sw3-eth3 up" "sw1-eth2 down" "sw4-eth4 up" "sw4-eth3 up" "sw1-eth2 up")
+
+((n=0))
+while [ 1 ] ; do
+ for (( i = 0; i< ${#operation[@]}; i ++)); do
+ echo "Test $n-$i"
+ p=`echo ${operation[$i]}`
+ echo "operation: $p"
+# read -p "hit anykey> "
+ dsh -w ${basename}1 "sudo ifconfig $p"
+ echo "wait $wait sec"
+ sleep $wait
+ result=`dsh -w ${basename}1 "cd ONOS/web; ./pingall.py $fdef"`
+ echo $result
+ nr_fail=`echo $result |grep fail | wc -l`
+ if [ $nr_fail -gt 0 ]; then
+ log $n $i
+ fi
+ done
+ ((n++))
+done
+
diff --git a/cluster-mgmt/template/onsdemo_core.py b/cluster-mgmt/template/onsdemo_core.py
index b9da603..61d2dcc 100755
--- a/cluster-mgmt/template/onsdemo_core.py
+++ b/cluster-mgmt/template/onsdemo_core.py
@@ -51,12 +51,12 @@
def __init__( self, *args, **kwargs ):
Topo.__init__( self, *args, **kwargs )
- sw1 = self.addSwitch('sw1', dpid='0000001697089a46')
- sw2 = self.addSwitch('sw2', dpid='00000000ba5eba11')
- sw3 = self.addSwitch('sw3', dpid='00000008a208f901')
- sw4 = self.addSwitch('sw4', dpid='000000000000ba12')
- sw5 = self.addSwitch('sw5', dpid='00000000ba5eba13')
- sw6 = self.addSwitch('sw6', dpid='0000204e7f518a35')
+ sw1 = self.addSwitch('sw1', dpid='0000000000000101')
+ sw2 = self.addSwitch('sw2', dpid='0000000000000102')
+ sw3 = self.addSwitch('sw3', dpid='0000000000000103')
+ sw4 = self.addSwitch('sw4', dpid='0000000000000104')
+ sw5 = self.addSwitch('sw5', dpid='0000000000000105')
+ sw6 = self.addSwitch('sw6', dpid='0000000000000106')
host1 = self.addHost( 'host1' )
host2 = self.addHost( 'host2' )
diff --git a/scripts/all-linkup.sh b/scripts/all-linkup.sh
new file mode 100755
index 0000000..9067012
--- /dev/null
+++ b/scripts/all-linkup.sh
@@ -0,0 +1,16 @@
+#! /bin/bash
+
+controller=`hostname`
+switches=`sudo ovs-vsctl list-br`
+
+function host2ip (){
+ ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
+ echo $ip
+}
+
+for s in $switches; do
+ ports=`sudo ovs-vsctl --pretty list-ports $s`
+ for p in $ports; do
+ sudo ifconfig $p up
+ done
+done
diff --git a/scripts/check-db-clean b/scripts/check-db-clean
new file mode 100644
index 0000000..e49d267
--- /dev/null
+++ b/scripts/check-db-clean
@@ -0,0 +1,6 @@
+g = TitanFactory.open('cassandra.local')
+g.stopTransaction(SUCCESS);
+g.V('type', 'port').each{println it.type};
+g.V('type', 'switch').each{println it.type};
+g.V('type', 'flow').each{println it.type};
+g.V('type', 'flow_entry').each{println it.type};
diff --git a/scripts/check-db-status.sh b/scripts/check-db-status.sh
new file mode 100755
index 0000000..b81e02d
--- /dev/null
+++ b/scripts/check-db-status.sh
@@ -0,0 +1,8 @@
+#! /bin/bash
+DIR=~/ONOS
+status=`~/titan-0.2.0/bin/gremlin.sh -e $DIR/scripts/check-db-clean | grep null | wc -l`
+if [ $status == 0 ]; then
+ echo "OK"
+else
+ echo "BAD"
+fi
diff --git a/scripts/listports.sh b/scripts/listports.sh
new file mode 100755
index 0000000..792ea37
--- /dev/null
+++ b/scripts/listports.sh
@@ -0,0 +1,13 @@
+#! /bin/bash
+
+controller=`hostname`
+switches=`sudo ovs-vsctl list-br`
+
+function host2ip (){
+ ip=`grep $1 /etc/hosts |grep -v "ip6"| awk '{print $1}'`
+ echo $ip
+}
+
+for s in $switches; do
+ sudo ovs-vsctl --pretty list-ports $s
+done
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
index e72baf7..5264648 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
@@ -42,7 +42,8 @@
@Adjacency(label="on")
public Iterable<IPortObject> getPorts();
- @Adjacency(label="on")
+ @JsonIgnore
+ @GremlinGroovy("_().out('on').has('number',portnum)")
public IPortObject getPort(final short port_num);
@Adjacency(label="on")
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index 098e02f..e84a3e8 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -102,169 +102,17 @@
private static Logger log = LoggerFactory.getLogger(FlowManager.class);
// The periodic task(s)
- private final ScheduledExecutorService measureShortestPathScheduler =
- Executors.newScheduledThreadPool(1);
- private final ScheduledExecutorService measureMapReaderScheduler =
- Executors.newScheduledThreadPool(1);
private final ScheduledExecutorService mapReaderScheduler =
Executors.newScheduledThreadPool(1);
- private BlockingQueue<Runnable> shortestPathQueue = new LinkedBlockingQueue<Runnable>();
- private ThreadPoolExecutor shortestPathExecutor =
- new ThreadPoolExecutor(10, 10, 5, TimeUnit.SECONDS, shortestPathQueue);
-
- class ShortestPathTask implements Runnable {
- private int hint;
- private ITopoRouteService topoRouteService;
- private ArrayList<DataPath> dpList;
-
- public ShortestPathTask(int hint,
- ITopoRouteService topoRouteService,
- ArrayList<DataPath> dpList) {
- this.hint = hint;
- this.topoRouteService = topoRouteService;
- this.dpList = dpList;
- }
-
- @Override
- public void run() {
- /*
- String logMsg = "MEASUREMENT: Running Thread hint " + this.hint;
- log.debug(logMsg);
- long startTime = System.nanoTime();
- */
- for (DataPath dp : this.dpList) {
- topoRouteService.getTopoShortestPath(dp.srcPort(), dp.dstPort());
- }
- /*
- long estimatedTime = System.nanoTime() - startTime;
- double rate = (estimatedTime > 0)? ((double)dpList.size() * 1000000000) / estimatedTime: 0.0;
- logMsg = "MEASUREMENT: Computed Thread hint " + hint + ": " + dpList.size() + " shortest paths in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " flows/s";
- log.debug(logMsg);
- */
- }
- }
-
- final Runnable measureShortestPath = new Runnable() {
- public void run() {
- log.debug("Recomputing Shortest Paths from the Network Map Flows...");
- if (floodlightProvider == null) {
- log.debug("FloodlightProvider service not found!");
- return;
- }
-
- if (topoRouteService == null) {
- log.debug("Topology Route Service not found");
- return;
- }
-
- int leftoverQueueSize = shortestPathExecutor.getQueue().size();
- if (leftoverQueueSize > 0) {
- String logMsg = "MEASUREMENT: Leftover Shortest Path Queue Size: " + leftoverQueueSize;
- log.debug(logMsg);
- return;
- }
- log.debug("MEASUREMENT: Beginning Shortest Path Computation");
-
- //
- // Recompute the Shortest Paths for all Flows
- //
- int counter = 0;
- int hint = 0;
- ArrayList<DataPath> dpList = new ArrayList<DataPath>();
- long startTime = System.nanoTime();
-
- topoRouteService.prepareShortestPathTopo();
-
- Iterable<IFlowPath> allFlowPaths = conn.utils().getAllFlowPaths(conn);
- for (IFlowPath flowPathObj : allFlowPaths) {
- FlowId flowId = new FlowId(flowPathObj.getFlowId());
-
- // log.debug("Found Path {}", flowId.toString());
- Dpid srcDpid = new Dpid(flowPathObj.getSrcSwitch());
- Port srcPort = new Port(flowPathObj.getSrcPort());
- Dpid dstDpid = new Dpid(flowPathObj.getDstSwitch());
- Port dstPort = new Port(flowPathObj.getDstPort());
- SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
- SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
-
- /*
- DataPath dp = new DataPath();
- dp.setSrcPort(srcSwitchPort);
- dp.setDstPort(dstSwitchPort);
- dpList.add(dp);
- if ((dpList.size() % 10) == 0) {
- shortestPathExecutor.execute(
- new ShortestPathTask(hint, topoRouteService,
- dpList));
- dpList = new ArrayList<DataPath>();
- hint++;
- }
- */
-
- DataPath dataPath =
- topoRouteService.getTopoShortestPath(srcSwitchPort,
- dstSwitchPort);
- counter++;
- }
- if (dpList.size() > 0) {
- shortestPathExecutor.execute(
- new ShortestPathTask(hint, topoRouteService,
- dpList));
- }
-
- /*
- // Wait for all tasks to finish
- try {
- while (shortestPathExecutor.getQueue().size() > 0) {
- Thread.sleep(100);
- }
- } catch (InterruptedException ex) {
- log.debug("MEASUREMENT: Shortest Path Computation interrupted");
- }
- */
-
- conn.endTx(Transaction.COMMIT);
- topoRouteService.dropShortestPathTopo();
-
- long estimatedTime = System.nanoTime() - startTime;
- double rate = (estimatedTime > 0)? ((double)counter * 1000000000) / estimatedTime: 0.0;
- String logMsg = "MEASUREMENT: Computed " + counter + " shortest paths in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " flows/s";
- log.debug(logMsg);
- }
- };
-
- final Runnable measureMapReader = new Runnable() {
- public void run() {
- if (floodlightProvider == null) {
- log.debug("FloodlightProvider service not found!");
- return;
- }
-
- //
- // Fetch all Flow Entries
- //
- int counter = 0;
- long startTime = System.nanoTime();
- Iterable<IFlowEntry> allFlowEntries = conn.utils().getAllFlowEntries(conn);
- for (IFlowEntry flowEntryObj : allFlowEntries) {
- counter++;
- FlowEntryId flowEntryId =
- new FlowEntryId(flowEntryObj.getFlowEntryId());
- String userState = flowEntryObj.getUserState();
- String switchState = flowEntryObj.getSwitchState();
- }
- conn.endTx(Transaction.COMMIT);
-
- long estimatedTime = System.nanoTime() - startTime;
- double rate = (estimatedTime > 0)? ((double)counter * 1000000000) / estimatedTime: 0.0;
- String logMsg = "MEASUREMENT: Fetched " + counter + " flow entries in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " entries/s";
- log.debug(logMsg);
- }
- };
-
final Runnable mapReader = new Runnable() {
public void run() {
+ long startTime = System.nanoTime();
+ int counterAllFlowEntries = 0;
+ int counterMyNotUpdatedFlowEntries = 0;
+ int counterAllFlowPaths = 0;
+ int counterMyFlowPaths = 0;
+
if (floodlightProvider == null) {
log.debug("FloodlightProvider service not found!");
return;
@@ -284,6 +132,7 @@
Iterable<IFlowEntry> allFlowEntries =
conn.utils().getAllFlowEntries(conn);
for (IFlowEntry flowEntryObj : allFlowEntries) {
+ counterAllFlowEntries++;
String flowEntryIdStr = flowEntryObj.getFlowEntryId();
String userState = flowEntryObj.getUserState();
String switchState = flowEntryObj.getSwitchState();
@@ -298,14 +147,6 @@
FlowEntryId flowEntryId = new FlowEntryId(flowEntryIdStr);
Dpid dpid = new Dpid(dpidStr);
- /*
- log.debug("Found Flow Entry Id = {} {}",
- flowEntryId.toString(),
- "DPID = " + dpid.toString() +
- " User State: " + userState +
- " Switch State: " + switchState);
- */
-
if (! switchState.equals("FE_SWITCH_NOT_UPDATED"))
continue; // Ignore the entry: nothing to do
@@ -316,11 +157,15 @@
myFlowEntries.put(flowEntryId.value(), flowEntryObj);
}
+ log.debug("MEASUREMENT: Found {} My Flow Entries NOT_UPDATED",
+ myFlowEntries.size());
+
//
// Process my Flow Entries
//
boolean processed_measurement_flow = false;
for (Map.Entry<Long, IFlowEntry> entry : myFlowEntries.entrySet()) {
+ counterMyNotUpdatedFlowEntries++;
IFlowEntry flowEntryObj = entry.getValue();
IFlowPath flowObj =
conn.utils().getFlowPathByFlowEntry(conn,
@@ -329,11 +174,14 @@
continue; // Should NOT happen
// Code for measurement purpose
+ // TODO: Commented-out for now
+ /*
{
if (flowObj.getFlowId().equals(measurementFlowIdStr)) {
processed_measurement_flow = true;
}
}
+ */
//
// TODO: Eliminate the re-fetching of flowEntryId,
@@ -477,6 +325,9 @@
}
}
+ log.debug("MEASUREMENT: Found {} Flow Entries to delete",
+ deleteFlowEntries.size());
+
//
// Delete all entries marked for deletion
//
@@ -514,15 +365,11 @@
// Fetch and recompute the Shortest Path for those
// Flow Paths this controller is responsible for.
//
-
- /*
- * TODO: For now, the computation of the reconciliation is
- * commented-out.
- */
topoRouteService.prepareShortestPathTopo();
Iterable<IFlowPath> allFlowPaths = conn.utils().getAllFlowPaths(conn);
HashSet<IFlowPath> flowObjSet = new HashSet<IFlowPath>();
for (IFlowPath flowPathObj : allFlowPaths) {
+ counterAllFlowPaths++;
if (flowPathObj == null)
continue;
String dataPathSummaryStr = flowPathObj.getDataPathSummary();
@@ -553,6 +400,21 @@
Port dstPort = new Port(dstPortShort);
SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+ //
+ // Use the source DPID as a heuristic to decide
+ // which controller is responsible for maintaining the
+ // shortest path.
+ // NOTE: This heuristic is error-prone: if the switch
+ // goes away and no controller is responsible for that
+ // switch, then the original Flow Path is not cleaned-up
+ //
+ IOFSwitch mySwitch = mySwitches.get(srcDpid.value());
+ if (mySwitch == null)
+ continue; // Ignore: not my responsibility
+
+ counterMyFlowPaths++;
+
//
// NOTE: Using here the regular getShortestPath() method
// won't work here, because that method calls internally
@@ -576,22 +438,12 @@
if (dataPathSummaryStr.equals(newDataPathSummaryStr))
continue; // Nothing changed
- //
- // Use the source DPID as a heuristic to decide
- // which controller is responsible for maintaining the
- // shortest path.
- // NOTE: This heuristic is error-prone: if the switch
- // goes away and no controller is responsible for that
- // switch, then the original Flow Path is not cleaned-up
- //
- IOFSwitch mySwitch = mySwitches.get(srcDpid.value());
- if (mySwitch == null)
- continue; // Ignore: not my responsibility
-
log.debug("RECONCILE: Need to Reconcile Shortest Path for FlowID {}",
flowId.toString());
flowObjSet.add(flowPathObj);
}
+ log.debug("MEASUREMENT: Found {} Flows to reconcile",
+ flowObjSet.size());
reconcileFlows(flowObjSet);
topoRouteService.dropShortestPathTopo();
@@ -604,19 +456,14 @@
(double)estimatedTime / 1000000000 + " sec";
log.debug(logMsg);
}
+
+ long estimatedTime = System.nanoTime() - startTime;
+ double rate = (estimatedTime > 0)? ((double)counterAllFlowPaths * 1000000000) / estimatedTime: 0.0;
+ String logMsg = "MEASUREMENT: Processed AllFlowEntries: " + counterAllFlowEntries + " MyNotUpdatedFlowEntries: " + counterMyNotUpdatedFlowEntries + " AllFlowPaths: " + counterAllFlowPaths + " MyFlowPaths: " + counterMyFlowPaths + " in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " paths/s";
+ log.debug(logMsg);
}
};
- /*
- final ScheduledFuture<?> measureShortestPathHandle =
- measureShortestPathScheduler.scheduleAtFixedRate(measureShortestPath, 10, 10, TimeUnit.SECONDS);
- */
-
- /*
- final ScheduledFuture<?> measureMapReaderHandle =
- measureMapReaderScheduler.scheduleAtFixedRate(measureMapReader, 10, 10, TimeUnit.SECONDS);
- */
-
final ScheduledFuture<?> mapReaderHandle =
mapReaderScheduler.scheduleAtFixedRate(mapReader, 3, 3, TimeUnit.SECONDS);
@@ -720,9 +567,12 @@
@Override
public boolean addFlow(FlowPath flowPath, FlowId flowId,
String dataPathSummaryStr) {
+ /*
+ * TODO: Commented-out for now
if (flowPath.flowId().value() == measurementFlowId) {
modifiedMeasurementFlowTime = System.nanoTime();
}
+ */
//
// Assign the FlowEntry IDs
@@ -937,9 +787,12 @@
*/
@Override
public boolean deleteFlow(FlowId flowId) {
+ /*
+ * TODO: Commented-out for now
if (flowId.value() == measurementFlowId) {
modifiedMeasurementFlowTime = System.nanoTime();
}
+ */
IFlowPath flowObj = null;
//
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index 11643fa..634f7eb 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -82,10 +82,7 @@
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.util.EventHistory;
import net.floodlightcontroller.util.EventHistory.EvAction;
-
import net.onrc.onos.registry.controller.IControllerRegistryService;
-import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
-import net.onrc.onos.registry.controller.RegistryException;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
@@ -130,6 +127,12 @@
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";
@@ -183,13 +186,13 @@
// Link discovery task details.
protected SingletonTask discoveryTask;
protected final int DISCOVERY_TASK_INTERVAL = 1;
- protected final int LINK_TIMEOUT = 5; // decreased timeout as part of LLDP process from 35 secs
- protected final int LLDP_TO_ALL_INTERVAL = 2 ; //decreased from 15 seconds.
+ protected final int LINK_TIMEOUT = 35; // original 35 secs, aggressive 5 secs
+ protected final int LLDP_TO_ALL_INTERVAL = 15 ; //original 15 seconds, aggressive 2 secs.
protected long lldpClock = 0;
// This value is intentionally kept higher than LLDP_TO_ALL_INTERVAL.
// If we want to identify link failures faster, we could decrease this
// value to a small number, say 1 or 2 sec.
- protected final int LLDP_TO_KNOWN_INTERVAL= 2; // LLDP frequency for known links from 20 secs
+ protected final int LLDP_TO_KNOWN_INTERVAL= 20; // LLDP frequency for known links
protected LLDPTLV controllerTLV;
protected ReentrantReadWriteLock lock;
@@ -1025,6 +1028,7 @@
NodePortTuple srcNpt, dstNpt;
boolean linkChanged = false;
+ NetworkMapOperation operation = NetworkMapOperation.NONE;
lock.writeLock().lock();
try {
@@ -1073,7 +1077,8 @@
writeLinkToStorage(lt, newInfo);
// Write link to network map
- linkStore.update(lt, newInfo, DM_OPERATION.INSERT);
+ operation = NetworkMapOperation.INSERT;
+ //linkStore.update(lt, newInfo, DM_OPERATION.INSERT);
updateOperation = UpdateOperation.LINK_UPDATED;
linkChanged = true;
@@ -1132,7 +1137,8 @@
writeLinkToStorage(lt, newInfo);
// Write link to network map
- linkStore.update(lt, newInfo, DM_OPERATION.UPDATE);
+ operation = NetworkMapOperation.UPDATE;
+ //linkStore.update(lt, newInfo, DM_OPERATION.UPDATE);
if (linkChanged) {
updateOperation = getUpdateOperation(newInfo.getSrcPortState(),
@@ -1162,6 +1168,18 @@
} 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;
}
diff --git a/src/main/java/net/onrc/onos/util/GraphDBUtils.java b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
index a3d106c..b0ca23b 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBUtils.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
@@ -57,11 +57,12 @@
@Override
public IPortObject searchPort(GraphDBConnection conn, String dpid, short number) {
ISwitchObject sw = searchSwitch(conn, dpid);
- GremlinPipeline<Vertex, IPortObject> pipe = new GremlinPipeline<Vertex, IPortObject>();
+ return sw != null ? sw.getPort(number): 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.iterator().hasNext() ? r.iterator().next() : null;
+ return r.iterator().hasNext() ? r.iterator().next() : null; */
}
@Override
diff --git a/start-onos.sh b/start-onos.sh
index 3f2213d..1263b8a 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -17,7 +17,7 @@
JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8"
-JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
+#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'`
diff --git a/web/ons-demo/RELEASE_NOTES.txt b/web/ons-demo/RELEASE_NOTES.txt
index 8649e9b..916a965 100644
--- a/web/ons-demo/RELEASE_NOTES.txt
+++ b/web/ons-demo/RELEASE_NOTES.txt
@@ -1,3 +1,11 @@
+** April 4, 2013 **
+Fix issues:
+ 305 - "close x" now unselects flow. double click to delete a flow
+ 323 - gui now recovers on timeout errors and polls again
+ 324 - fixed problem with added flows not displaying
+ 325 - fixed logic displaying flows in topology view
+
+
** March 28, 2013 **
- add and delete flow implemented
- to add flow
diff --git a/web/ons-demo/css/skin.default.css b/web/ons-demo/css/skin.default.css
index d88814e..1ce4897 100644
--- a/web/ons-demo/css/skin.default.css
+++ b/web/ons-demo/css/skin.default.css
@@ -366,6 +366,6 @@
-webkit-animation-duration: .5s;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: ease-in-out;
- -webkit-animation-iteration-count: 24;
+ -webkit-animation-iteration-count: 70;
}
diff --git a/web/ons-demo/data/configuration.json.dev b/web/ons-demo/data/configuration.json.dev
index 90cad6a..5968375 100644
--- a/web/ons-demo/data/configuration.json.dev
+++ b/web/ons-demo/data/configuration.json.dev
@@ -8,6 +8,7 @@
"00:00:00:00:00:00:01:06"
],
"aggregation": [
+ "00:00:00:00:00:00:01:01",
"00:00:00:00:00:00:02:01",
"00:00:00:00:00:00:03:01",
"00:00:00:00:00:00:04:01",
@@ -18,13 +19,13 @@
],
"association": {
"00:00:00:00:00:00:01:01": [
- "00:00:00:00:00:00:03:01"
+ "00:00:00:00:00:00:08:01"
],
"00:00:00:00:00:00:01:02": [
"00:00:00:00:00:00:02:01"
],
"00:00:00:00:00:00:01:03": [
- "00:00:00:00:00:00:07:01"
+ "00:00:00:00:00:00:03:01"
],
"00:00:00:00:00:00:01:04": [
"00:00:00:00:00:00:04:01",
@@ -34,7 +35,7 @@
"00:00:00:00:00:00:06:01"
],
"00:00:00:00:00:00:01:06": [
- "00:00:00:00:00:00:08:01"
+ "00:00:00:00:00:00:07:01"
]
}
}
\ No newline at end of file
diff --git a/web/ons-demo/js/app.js b/web/ons-demo/js/app.js
index e342213..695e4bb 100644
--- a/web/ons-demo/js/app.js
+++ b/web/ons-demo/js/app.js
@@ -20,7 +20,7 @@
var pendingLinks = {};
var selectedFlows = [];
-var pendingTimeout = 10000;
+var pendingTimeout = 30000;
var colors = [
'color1',
@@ -70,7 +70,14 @@
function updateSelectedFlowsTopology() {
// DRAW THE FLOWS
- var flows = d3.select('svg').selectAll('.flow').data(selectedFlows);
+ var topologyFlows = [];
+ selectedFlows.forEach(function (flow) {
+ if (flow) {
+ topologyFlows.push(flow);
+ }
+ });
+
+ var flows = d3.select('svg').selectAll('.flow').data(topologyFlows);
flows.enter().append("svg:path").attr('class', 'flow')
.attr('stroke-dasharray', '4, 10')
@@ -82,13 +89,14 @@
.attr('dur', '20s')
.attr('repeatCount', 'indefinite');
+ flows.exit().remove();
flows.attr('d', function (d) {
if (!d) {
return;
}
var pts = [];
- if (!d.dataPath.flowEntries) {
+ if (!d.dataPath.flowEntries || !d.dataPath.flowEntries.length) {
// create a temporary vector to indicate the pending flow
var s1 = d3.select(document.getElementById(d.dataPath.srcPort.dpid.value));
var s2 = d3.select(document.getElementById(d.dataPath.dstPort.dpid.value));
@@ -162,6 +170,10 @@
function rowUpdate(d) {
var row = d3.select(this);
row.select('.deleteFlow').on('click', function () {
+ selectedFlows[selectedFlows.indexOf(d)] = null;
+ updateSelectedFlows();
+ });
+ row.on('dblclick', function () {
if (d) {
var prompt = 'Delete flow ' + d.flowId.value + '?';
if (confirm(prompt)) {
@@ -187,7 +199,9 @@
}
}
})
- .classed('pending', d && (d.deletePending || d.createPending));
+ .classed('pending', function (d) {
+ return d && (d.createPending || d.deletePending);
+ });
row.select('.srcDPID')
.text(function (d) {
@@ -238,8 +252,6 @@
} else if (flow.createPending) {
newSelectedFlows.push(flow);
}
- } else {
- newSelectedFlows.push(null);
}
});
selectedFlows = newSelectedFlows;
@@ -1059,21 +1071,23 @@
updateModel(function (newModel) {
// console.log('Update time: ' + (Date.now() - d)/1000 + 's');
- var modelChanged = false;
- if (!model || JSON.stringify(model) != JSON.stringify(newModel)) {
- modelChanged = true;
- model = newModel;
- } else {
-// console.log('no change');
- }
+ if (newModel) {
+ var modelChanged = false;
+ if (!model || JSON.stringify(model) != JSON.stringify(newModel)) {
+ modelChanged = true;
+ model = newModel;
+ } else {
+ // console.log('no change');
+ }
- if (modelChanged) {
- updateControllers();
- updateSelectedFlows();
- updateTopology();
- }
+ if (modelChanged) {
+ updateControllers();
+ updateSelectedFlows();
+ updateTopology();
+ }
- updateHeader(newModel);
+ updateHeader(newModel);
+ }
// do it again in 1s
setTimeout(function () {
diff --git a/web/ons-demo/js/model.js b/web/ons-demo/js/model.js
index 29859a6..5026bd4 100644
--- a/web/ons-demo/js/model.js
+++ b/web/ons-demo/js/model.js
@@ -126,7 +126,8 @@
var model = toD3(results);
cb(model);
} else {
- alert(JSON.stringify(err));
+ console.log(JSON.stringify(err));
+ cb(null);
}
});
}
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 89a074a..3238656 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -192,15 +192,15 @@
resp = Response(result, status=200, mimetype='application/json')
return resp
-@app.route("/wm/flow/getsummary/0/0/json")
-def flows():
+@app.route("/wm/flow/getsummary/<start>/<range>/json")
+def flows(start, range):
if request.args.get('proxy') == None:
host = ONOS_LOCAL_HOST
else:
host = ONOS_GUI3_HOST
try:
- command = "curl -s %s/wm/flow/getsummary/0/0/json" % (host)
+ command = "curl -s %s/wm/flow/getsummary/%s/%s/json" % (host, start, range)
# print command
result = os.popen(command).read()
except:
@@ -813,9 +813,11 @@
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)
+ 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)
print command
errcode = os.popen(command).read()
- return errcode
+ errcode1 = os.popen(command1).read()
+ return errcode+" "+errcode1
#* Delete Flow
#http://localhost:9000/gui/delflow/<flow_id>
@@ -861,7 +863,7 @@
print cmd_string
os.popen(cmd_string)
- return
+ return cmd_string
#* Get Iperf Throughput
#http://localhost:9000/gui/iperf/rate/<flow_id>