Add mastership to Topology
Change-Id: Ibc2914682dac2fe124b69e40922e2d313190f168
diff --git a/src/main/java/net/onrc/onos/core/topology/BaseInternalTopology.java b/src/main/java/net/onrc/onos/core/topology/BaseInternalTopology.java
index 6f9d9bf..cf44c32 100644
--- a/src/main/java/net/onrc/onos/core/topology/BaseInternalTopology.java
+++ b/src/main/java/net/onrc/onos/core/topology/BaseInternalTopology.java
@@ -11,7 +11,7 @@
/**
* Interface to reference internal self-contained elements.
*/
-public interface BaseInternalTopology {
+public interface BaseInternalTopology extends BaseMastership {
/**
* Gets a SwitchEvent.
diff --git a/src/main/java/net/onrc/onos/core/topology/BaseMastership.java b/src/main/java/net/onrc/onos/core/topology/BaseMastership.java
new file mode 100644
index 0000000..fa05e1c
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/topology/BaseMastership.java
@@ -0,0 +1,22 @@
+package net.onrc.onos.core.topology;
+
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.OnosInstanceId;
+
+// TODO probably "Base" prefix is not required
+/**
+ * Interface to access switch mastership information in the network view.
+ */
+public interface BaseMastership {
+
+ /**
+ * Gets the master instance ID for a switch.
+ *
+ * @param dpid switch dpid
+ * @return master instance ID or null if there is no master
+ */
+ public OnosInstanceId getSwitchMaster(Dpid dpid);
+
+// We may need something like below in the future
+// public List<ImmutablePair<OnosInstanceId, Role>> getSwitchMasterCandidates(Dpid dpid);
+}
diff --git a/src/main/java/net/onrc/onos/core/topology/BaseTopology.java b/src/main/java/net/onrc/onos/core/topology/BaseTopology.java
index 6b2bef8..69db9fd 100644
--- a/src/main/java/net/onrc/onos/core/topology/BaseTopology.java
+++ b/src/main/java/net/onrc/onos/core/topology/BaseTopology.java
@@ -11,7 +11,7 @@
/**
* BaseTopology interface common to both {@link ImmutableTopology} and {@link MutableTopology}.
*/
-public interface BaseTopology {
+public interface BaseTopology extends BaseMastership {
/**
* Gets the switch for a given switch DPID.
diff --git a/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java b/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
index 3c6317e..2a6ac33 100644
--- a/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
+++ b/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
@@ -6,8 +6,10 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.OnosInstanceId;
import net.onrc.onos.core.util.PortNumber;
import net.onrc.onos.core.util.SwitchPort;
@@ -268,4 +270,10 @@
public Collection<Host> getHosts(SwitchPort port) {
return toHostImpls(internal, internal.getHostEvents(port));
}
+
+
+ @Override
+ public OnosInstanceId getSwitchMaster(Dpid dpid) {
+ return internal.getSwitchMaster(dpid);
+ }
}
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
index d407064..1dc14c6 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
@@ -1,12 +1,17 @@
package net.onrc.onos.core.topology;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -16,9 +21,11 @@
import javax.annotation.concurrent.GuardedBy;
+import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.LinkTuple;
+import net.onrc.onos.core.util.OnosInstanceId;
import net.onrc.onos.core.util.PortNumber;
import net.onrc.onos.core.util.SwitchPort;
@@ -30,6 +37,7 @@
import com.google.common.collect.Multimaps;
+// TODO add TopologyManager, etc. to populate Mastership information.
/**
* Class to represent an instance of Topology Snapshot.
*/
@@ -39,6 +47,10 @@
// TODO Revisit Map types after implementing CoW/lock-free
+ // Mastership info
+ // Dpid -> [ (InstanceID, Role) ]
+ private final Map<Dpid, SortedSet<MastershipEvent>> mastership;
+
// DPID -> Switch
private final ConcurrentMap<Dpid, SwitchEvent> switches;
private final ConcurrentMap<Dpid, ConcurrentMap<PortNumber, PortEvent>> ports;
@@ -60,6 +72,7 @@
* Create an empty Topology.
*/
public TopologyImpl() {
+ mastership = new HashMap<>();
// TODO: Does these object need to be stored in Concurrent Collection?
switches = new ConcurrentHashMap<>();
ports = new ConcurrentHashMap<>();
@@ -78,6 +91,13 @@
public TopologyImpl(TopologyImpl original) {
original.acquireReadLock();
try {
+ // shallow copy Set in Map
+ this.mastership = new HashMap<>(original.mastership.size());
+ for (Entry<Dpid, SortedSet<MastershipEvent>> e
+ : original.mastership.entrySet()) {
+ this.mastership.put(e.getKey(), new TreeSet<>(e.getValue()));
+ }
+
this.switches = new ConcurrentHashMap<>(original.switches);
// shallow copy Map in Map
@@ -481,6 +501,20 @@
return Collections.unmodifiableCollection(mac2Host.values());
}
+ @Override
+ public OnosInstanceId getSwitchMaster(Dpid dpid) {
+ final SortedSet<MastershipEvent> candidates = mastership.get(dpid);
+ if (candidates == null) {
+ return null;
+ }
+ for (MastershipEvent candidate : candidates) {
+ if (candidate.getRole() == Role.MASTER) {
+ return candidate.getOnosInstanceId();
+ }
+ }
+ return null;
+ }
+
/**
* Puts a SwitchEvent.
*
@@ -670,6 +704,49 @@
}
}
+ /**
+ * Puts a mastership change event.
+ *
+ * @param master MastershipEvent
+ */
+ @GuardedBy("writeLock")
+ protected void putSwitchMastershipEvent(MastershipEvent master) {
+ checkNotNull(master);
+
+ SortedSet<MastershipEvent> candidates
+ = mastership.get(master.getDpid());
+ if (candidates == null) {
+ // SortedSet, customized so that MASTER MastershipEvent appear
+ // earlier during iteration.
+ candidates = new TreeSet<>(new MastershipEvent.MasterFirstComparator());
+ }
+
+ // always replace
+ candidates.remove(master);
+ candidates.add(master);
+ }
+
+ /**
+ * Removes a mastership change event.
+ * <p>
+ * Note: Only Dpid and OnosInstanceId will be used to identify the
+ * {@link MastershipEvent} to remove.
+ *
+ * @param master {@link MastershipEvent} to remove. (Role is ignored)
+ */
+ @GuardedBy("writeLock")
+ protected void removeSwitchMastershipEvent(MastershipEvent master) {
+ checkNotNull(master);
+
+ SortedSet<MastershipEvent> candidates
+ = mastership.get(master.getDpid());
+ if (candidates == null) {
+ // nothing to do
+ return;
+ }
+ candidates.remove(master);
+ }
+
@Override
public void acquireReadLock() {