blob: 0a3de5009ff0544fc99d76aa904c9adea5a49dd1 [file] [log] [blame]
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -07001package org.onlab.onos.store.mastership.impl;
2
3import java.util.Collections;
Yuta HIGUCHI868def02014-10-23 12:09:43 -07004import java.util.EnumMap;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -07005import java.util.LinkedList;
6import java.util.List;
7import java.util.Map;
8
9import org.onlab.onos.cluster.NodeId;
Ayaka Koshibeabedb092014-10-20 17:01:31 -070010import org.onlab.onos.cluster.RoleInfo;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070011import org.onlab.onos.net.MastershipRole;
12
Ayaka Koshibefc981cf2014-10-21 12:44:17 -070013import com.google.common.base.MoreObjects;
14import com.google.common.base.MoreObjects.ToStringHelper;
15
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070016/**
17 * A structure that holds node mastership roles associated with a
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070018 * {@link org.onlab.onos.net.DeviceId}. This structure needs to be locked through IMap.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070019 */
Yuta HIGUCHI868def02014-10-23 12:09:43 -070020final class RoleValue {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070021
Yuta HIGUCHI868def02014-10-23 12:09:43 -070022 protected final Map<MastershipRole, List<NodeId>> value = new EnumMap<>(MastershipRole.class);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070023
24 public RoleValue() {
25 value.put(MastershipRole.MASTER, new LinkedList<NodeId>());
26 value.put(MastershipRole.STANDBY, new LinkedList<NodeId>());
27 value.put(MastershipRole.NONE, new LinkedList<NodeId>());
28 }
29
Yuta HIGUCHI868def02014-10-23 12:09:43 -070030 // exposing internals for serialization purpose only
31 Map<MastershipRole, List<NodeId>> value() {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070032 return Collections.unmodifiableMap(value);
33 }
34
35 public List<NodeId> nodesOfRole(MastershipRole type) {
36 return value.get(type);
37 }
38
39 public NodeId get(MastershipRole type) {
40 return value.get(type).isEmpty() ? null : value.get(type).get(0);
41 }
42
43 public boolean contains(MastershipRole type, NodeId nodeId) {
44 return value.get(type).contains(nodeId);
45 }
46
47 /**
48 * Associates a node to a certain role.
49 *
50 * @param type the role
51 * @param nodeId the node ID of the node to associate
52 */
53 public void add(MastershipRole type, NodeId nodeId) {
54 List<NodeId> nodes = value.get(type);
55
56 if (!nodes.contains(nodeId)) {
57 nodes.add(nodeId);
58 }
59 }
60
61 /**
62 * Removes a node from a certain role.
63 *
64 * @param type the role
65 * @param nodeId the ID of the node to remove
66 * @return
67 */
68 public boolean remove(MastershipRole type, NodeId nodeId) {
69 List<NodeId> nodes = value.get(type);
70 if (!nodes.isEmpty()) {
71 return nodes.remove(nodeId);
72 } else {
73 return false;
74 }
75 }
76
77 /**
78 * Reassigns a node from one role to another. If the node was not of the
79 * old role, it will still be assigned the new role.
80 *
81 * @param nodeId the Node ID of node changing roles
82 * @param from the old role
83 * @param to the new role
84 */
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070085 public void reassign(NodeId nodeId, MastershipRole from, MastershipRole to) {
86 remove(from, nodeId);
87 add(to, nodeId);
88 }
89
90 /**
91 * Replaces a node in one role with another node. Even if there is no node to
92 * replace, the new node is associated to the role.
93 *
94 * @param from the old NodeId to replace
95 * @param to the new NodeId
96 * @param type the role associated with the old NodeId
97 */
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070098 public void replace(NodeId from, NodeId to, MastershipRole type) {
99 remove(type, from);
100 add(type, to);
101 }
102
Ayaka Koshibe67af1f42014-10-20 15:26:37 -0700103 /**
104 * Summarizes this RoleValue as a RoleInfo. Note that master and/or backups
105 * may be empty, so the values should be checked for safety.
106 *
107 * @return the RoleInfo.
108 */
109 public RoleInfo roleInfo() {
110 return new RoleInfo(
111 get(MastershipRole.MASTER), nodesOfRole(MastershipRole.STANDBY));
112 }
113
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700114 @Override
115 public String toString() {
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700116 ToStringHelper helper = MoreObjects.toStringHelper(this.getClass());
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700117 for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) {
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700118 helper.add(el.getKey().toString(), el.getValue());
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700119 }
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700120 return helper.toString();
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700121 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700122}