Ayaka Koshibe

add roleInfo structure and backup_changed mastership event

Change-Id: Iedee219fe250d681377d73a50a71f5fa72cd7802
......@@ -11,7 +11,7 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
//do we worry about explicitly setting slaves/equals? probably not,
//to keep it simple
NodeId master;
NodeId node;
/**
* Type of mastership events.
......@@ -20,7 +20,12 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
/**
* Signifies that the master for a device has changed.
*/
MASTER_CHANGED
MASTER_CHANGED,
/**
* Signifies that the list of backup nodes has changed.
*/
BACKUPS_CHANGED
}
/**
......@@ -29,11 +34,11 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
*
* @param type device event type
* @param device event device subject
* @param master master ID subject
* @param node master ID subject
*/
public MastershipEvent(Type type, DeviceId device, NodeId master) {
public MastershipEvent(Type type, DeviceId device, NodeId node) {
super(type, device);
this.master = master;
this.node = node;
}
/**
......@@ -47,15 +52,15 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
*/
public MastershipEvent(Type type, DeviceId device, NodeId master, long time) {
super(type, device, time);
this.master = master;
this.node = master;
}
/**
* Returns the current master's ID as a subject.
* Returns the NodeID of the node responsible for triggering the event.
*
* @return master ID subject
* @return node ID as a subject
*/
public NodeId master() {
return master;
public NodeId node() {
return node;
}
}
......
......@@ -228,8 +228,8 @@ implements MastershipService, MastershipAdminService {
return true;
}
//else {
//FIXME: break tie for equal-sized clusters,
// maybe by number of connected switches
//FIXME: break tie for equal-sized clusters, by number of
// connected switches, then masters, then nodeId hash
// }
return false;
}
......
......@@ -367,7 +367,7 @@ public class DeviceManager
final NodeId myNodeId = clusterService.getLocalNode().id();
log.info("## got Mastershipevent for dev {}", did);
if (myNodeId.equals(event.master())) {
if (myNodeId.equals(event.node())) {
MastershipTerm term = termService.getMastershipTerm(did);
if (!myNodeId.equals(term.master())) {
......
......@@ -86,7 +86,7 @@ public class ReplicaInfoManager implements ReplicaInfoService {
final List<NodeId> standbyList = Collections.<NodeId>emptyList();
eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED,
event.subject(),
new ReplicaInfo(event.master(), standbyList)));
new ReplicaInfo(event.node(), standbyList)));
}
}
......
......@@ -79,9 +79,9 @@ implements MastershipStore {
};
roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer);
roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true);
terms = new SMap(theInstance.getMap("terms"), this.serializer);
clusterSize = theInstance.getAtomicLong("clustersize");
roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true);
log.info("Started");
}
......
......@@ -8,6 +8,7 @@ import java.util.Map;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.store.common.RoleInfo;
/**
* A structure that holds node mastership roles associated with a
......@@ -77,7 +78,6 @@ public class RoleValue {
* @param from the old role
* @param to the new role
*/
// might want to add anyways as default behavior
public void reassign(NodeId nodeId, MastershipRole from, MastershipRole to) {
remove(from, nodeId);
add(to, nodeId);
......@@ -91,12 +91,22 @@ public class RoleValue {
* @param to the new NodeId
* @param type the role associated with the old NodeId
*/
// might want to add anyways as default behavior
public void replace(NodeId from, NodeId to, MastershipRole type) {
remove(type, from);
add(type, to);
}
/**
* Summarizes this RoleValue as a RoleInfo. Note that master and/or backups
* may be empty, so the values should be checked for safety.
*
* @return the RoleInfo.
*/
public RoleInfo roleInfo() {
return new RoleInfo(
get(MastershipRole.MASTER), nodesOfRole(MastershipRole.STANDBY));
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
......
......@@ -218,7 +218,7 @@ public class DistributedMastershipStoreTest {
public void notify(MastershipEvent event) {
assertEquals("wrong event:", Type.MASTER_CHANGED, event.type());
assertEquals("wrong subject", DID1, event.subject());
assertEquals("wrong subject", N1, event.master());
assertEquals("wrong subject", N1, event.node());
addLatch.countDown();
}
};
......
package org.onlab.onos.store.common;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import org.onlab.onos.cluster.NodeId;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A container for detailed role information for a device,
* within the current cluster. Role attributes include current
* master and a preference-ordered list of backup nodes.
*/
public class RoleInfo {
private final NodeId master;
private final List<NodeId> backups;
public RoleInfo(NodeId master, List<NodeId> backups) {
this.master = master;
this.backups = new LinkedList<>();
this.backups.addAll(checkNotNull(backups));
}
public NodeId master() {
return master;
}
public List<NodeId> backups() {
return Collections.unmodifiableList(backups);
}
@Override
public boolean equals(Object other) {
if (other == null) {
return false;
}
if (!(other instanceof RoleInfo)) {
return false;
}
RoleInfo that = (RoleInfo) other;
if (!Objects.equals(this.master, that.master)) {
return false;
}
if (!Objects.equals(this.backups, that.backups)) {
return false;
}
return true;
}
@Override
public int hashCode() {
return Objects.hash(master, backups.hashCode());
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("master: \n\t").append(master).append("\n");
builder.append("backups: \n");
for (NodeId n : backups) {
builder.append("\t").append(n).append("\n");
}
return builder.toString();
}
}
package org.onlab.onos.store.common;
import java.util.List;
import org.junit.Test;
import org.onlab.onos.cluster.NodeId;
import com.google.common.collect.Lists;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
/**
* Test to check behavioral correctness of the RoleInfo structure.
*/
public class RoleInfoTest {
private static final NodeId N1 = new NodeId("n1");
private static final NodeId N2 = new NodeId("n2");
private static final NodeId N3 = new NodeId("n3");
private static final NodeId N4 = new NodeId("n4");
private static final List<NodeId> BKUP1 = Lists.newArrayList(N2, N3);
private static final List<NodeId> BKUP2 = Lists.newArrayList(N3, N4);
private static final RoleInfo RI1 = new RoleInfo(N1, BKUP1);
private static final RoleInfo RI2 = new RoleInfo(N1, BKUP2);
private static final RoleInfo RI3 = new RoleInfo(N2, BKUP1);
@Test
public void basics() {
assertEquals("wrong master", new NodeId("n1"), RI1.master());
System.out.println(RI1.toString());
assertEquals("wrong Backups", RI1.backups(), Lists.newArrayList(N2, N3));
assertNotEquals("equals() broken", RI1, RI2);
assertNotEquals("equals() broken", RI1, RI3);
List<NodeId> bkup3 = Lists.newArrayList(N3, new NodeId("n4"));
assertEquals("equals() broken", new RoleInfo(N1, bkup3), RI2);
}
}