Group write Switch+Port at SouthboundNetworkGraph.addSwitch(Switch)
Change-Id: Ic2c231be3ca5ac24685f8e0a7bf81e684959d57f
diff --git a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/SouthboundNetworkGraph.java b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/SouthboundNetworkGraph.java
index cb52d15..b38c057 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/SouthboundNetworkGraph.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/SouthboundNetworkGraph.java
@@ -4,6 +4,7 @@
import java.util.List;
import net.onrc.onos.datastore.RCObject;
+import net.onrc.onos.datastore.RCObject.WriteOp;
import net.onrc.onos.datastore.topology.RCLink;
import net.onrc.onos.datastore.topology.RCPort;
import net.onrc.onos.datastore.topology.RCSwitch;
@@ -16,7 +17,7 @@
import edu.stanford.ramcloud.JRamCloud.WrongVersionException;
/**
- * The southbound interface to the network graph which allows clients to
+ * The southbound interface to the network graph which allows clients to
* mutate the graph. This class will maintain the invariants of the network
* graph. The southbound discovery modules will use this interface to update
* the network graph as they learn about the state of the network.
@@ -24,37 +25,55 @@
*/
public class SouthboundNetworkGraph {
private static final Logger log = LoggerFactory.getLogger(SouthboundNetworkGraph.class);
-
+
private static final int NUM_RETRIES = 10;
-
-
+
+
public void addSwitch(Switch sw) {
+
+ ArrayList<WriteOp> groupOp = new ArrayList<>();
+
RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
rcSwitch.setStatus(RCSwitch.STATUS.ACTIVE);
-
+
+ // XXX Is ForceCreating Switch on DB OK here?
+ // If ForceCreating, who ever is calling this method needs
+ // to assure that DPID is unique cluster-wide, etc.
+ groupOp.add(WriteOp.ForceCreate(rcSwitch));
+
for (Port port : sw.getPorts()) {
RCPort rcPort = new RCPort(sw.getDpid(), (long)port.getNumber());
rcPort.setStatus(RCPort.STATUS.ACTIVE);
rcSwitch.addPortId(rcPort.getId());
-
- // TODO check how to write switch+ports together
- writeObject(rcPort);
+
+ groupOp.add(WriteOp.ForceCreate(rcPort));
}
-
- writeObject(rcSwitch);
+
+ boolean failed = RCObject.multiWrite( groupOp );
+
+ if ( failed ) {
+ log.error("Adding Switch {} and it's ports failed.", sw.getDpid());
+ for ( WriteOp op : groupOp ) {
+ log.debug("Operation:{} for {} - Result:{}", op.getOp(), op.getObject(), op.getStatus() );
+
+ // If we changed the operation from ForceCreate to
+ // Conditional operation (Create/Update) then we should retry here.
+ }
+ }
+
}
-
+
public void deactivateSwitch(Switch sw) {
RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
-
+
List<RCObject> objectsToDeactive = new ArrayList<RCObject>();
-
+
for (int i = 0; i < NUM_RETRIES; i++) {
try {
rcSwitch.read();
rcSwitch.setStatus(RCSwitch.STATUS.INACTIVE);
objectsToDeactive.add(rcSwitch);
-
+
for (Port p : sw.getPorts()) {
RCPort rcPort = new RCPort(sw.getDpid(), (long)p.getNumber());
rcPort.read();
@@ -66,14 +85,14 @@
// We don't care to much if the object wasn't there, it's
// being deactivated anyway
}
-
+
try {
- for (RCObject rcObject : objectsToDeactive) {
+ for (RCObject rcObject : objectsToDeactive) {
rcObject.update();
}
break;
} catch (ObjectDoesntExistException e) {
- // Unlikely, and we don't care anyway.
+ // Unlikely, and we don't care anyway.
// TODO But, this will cause everything else to fail
log.warn("Trying to deactivate object that doesn't exist", e);
} catch (WrongVersionException e) {
@@ -81,28 +100,28 @@
}
}
}
-
+
public void addPort(Switch sw, Port port) {
RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
-
+
try {
rcSwitch.read();
} catch (ObjectDoesntExistException e) {
log.warn("Add port failed because switch {} doesn't exist", sw.getDpid(), e);
return;
}
-
+
RCPort rcPort = new RCPort(port.getSwitch().getDpid(), (long)port.getNumber());
rcPort.setStatus(RCPort.STATUS.ACTIVE);
rcSwitch.addPortId(rcPort.getId());
-
+
writeObject(rcPort);
writeObject(rcSwitch);
}
-
+
public void deactivatePort(Port port) {
RCPort rcPort = new RCPort(port.getSwitch().getDpid(), (long)port.getNumber());
-
+
for (int i = 0; i < NUM_RETRIES; i++) {
try {
rcPort.read();
@@ -111,9 +130,9 @@
log.warn("Trying to deactivate a port that doesn't exist: {}", port);
return;
}
-
+
rcPort.setStatus(RCPort.STATUS.INACTIVE);
-
+
try {
rcPort.update();
break;
@@ -122,14 +141,14 @@
}
}
}
-
+
public void addLink(Link link) {
RCLink rcLink = new RCLink(link.getSourceSwitchDpid(), (long)link.getSourcePortNumber(),
link.getDestinationSwitchDpid(), (long)link.getDestinationPortNumber());
-
+
RCPort rcSrcPort = new RCPort(link.getSourceSwitchDpid(), (long)link.getSourcePortNumber());
RCPort rcDstPort = new RCPort(link.getDestinationSwitchDpid(), (long)link.getDestinationPortNumber());
-
+
for (int i = 0; i < NUM_RETRIES; i++) {
try {
rcSrcPort.read();
@@ -143,12 +162,12 @@
log.debug("Link already exists {}", link);
return;
}
-
+
rcSrcPort.addLinkId(rcLink.getId());
rcDstPort.addLinkId(rcLink.getId());
-
+
rcLink.setStatus(RCLink.STATUS.ACTIVE);
-
+
try {
rcLink.update();
rcSrcPort.update();
@@ -160,14 +179,14 @@
}
}
}
-
+
public void removeLink(Link link) {
RCLink rcLink = new RCLink(link.getSourceSwitchDpid(), (long)link.getSourcePortNumber(),
link.getDestinationSwitchDpid(), (long)link.getDestinationPortNumber());
-
+
RCPort rcSrcPort = new RCPort(link.getSourceSwitchDpid(), (long)link.getSourcePortNumber());
RCPort rcDstPort = new RCPort(link.getDestinationSwitchDpid(), (long)link.getDestinationPortNumber());
-
+
for (int i = 0; i < NUM_RETRIES; i++) {
try {
rcSrcPort.read();
@@ -177,10 +196,10 @@
log.error("Remove link failed {}", link, e);
return;
}
-
+
rcSrcPort.removeLinkId(rcLink.getId());
rcDstPort.removeLinkId(rcLink.getId());
-
+
try {
rcSrcPort.update();
rcDstPort.update();
@@ -193,15 +212,15 @@
}
}
}
-
+
public void updateDevice(Device device) {
// TODO implement
}
-
+
public void removeDevice(Device device) {
// TODO implement
}
-
+
// TODO what happens if this fails? why could it fail?
private void writeObject(RCObject object) {
for (int i = 0; i < NUM_RETRIES; i++) {
@@ -216,7 +235,7 @@
return;
}
}
-
+
try {
// TODO check API for writing without caring what's there
object.update();