blob: 1ccee6bbb1e3546518701ea1341ae26414ffa0b8 [file] [log] [blame]
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -07001package org.onlab.onos.store.mastership.impl;
2
3import java.util.Collections;
Ayaka Koshibee8e45352014-10-16 00:37:19 -07004import java.util.HashMap;
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
13/**
14 * A structure that holds node mastership roles associated with a
15 * {@link DeviceId}. This structure needs to be locked through IMap.
16 */
17public class RoleValue {
18
Ayaka Koshibee8e45352014-10-16 00:37:19 -070019 protected Map<MastershipRole, List<NodeId>> value = new HashMap<>();
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070020
21 public RoleValue() {
22 value.put(MastershipRole.MASTER, new LinkedList<NodeId>());
23 value.put(MastershipRole.STANDBY, new LinkedList<NodeId>());
24 value.put(MastershipRole.NONE, new LinkedList<NodeId>());
25 }
26
27 public Map<MastershipRole, List<NodeId>> value() {
28 return Collections.unmodifiableMap(value);
29 }
30
31 public List<NodeId> nodesOfRole(MastershipRole type) {
32 return value.get(type);
33 }
34
35 public NodeId get(MastershipRole type) {
36 return value.get(type).isEmpty() ? null : value.get(type).get(0);
37 }
38
39 public boolean contains(MastershipRole type, NodeId nodeId) {
40 return value.get(type).contains(nodeId);
41 }
42
43 /**
44 * Associates a node to a certain role.
45 *
46 * @param type the role
47 * @param nodeId the node ID of the node to associate
48 */
49 public void add(MastershipRole type, NodeId nodeId) {
50 List<NodeId> nodes = value.get(type);
51
52 if (!nodes.contains(nodeId)) {
53 nodes.add(nodeId);
54 }
55 }
56
57 /**
58 * Removes a node from a certain role.
59 *
60 * @param type the role
61 * @param nodeId the ID of the node to remove
62 * @return
63 */
64 public boolean remove(MastershipRole type, NodeId nodeId) {
65 List<NodeId> nodes = value.get(type);
66 if (!nodes.isEmpty()) {
67 return nodes.remove(nodeId);
68 } else {
69 return false;
70 }
71 }
72
73 /**
74 * Reassigns a node from one role to another. If the node was not of the
75 * old role, it will still be assigned the new role.
76 *
77 * @param nodeId the Node ID of node changing roles
78 * @param from the old role
79 * @param to the new role
80 */
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070081 public void reassign(NodeId nodeId, MastershipRole from, MastershipRole to) {
82 remove(from, nodeId);
83 add(to, nodeId);
84 }
85
86 /**
87 * Replaces a node in one role with another node. Even if there is no node to
88 * replace, the new node is associated to the role.
89 *
90 * @param from the old NodeId to replace
91 * @param to the new NodeId
92 * @param type the role associated with the old NodeId
93 */
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070094 public void replace(NodeId from, NodeId to, MastershipRole type) {
95 remove(type, from);
96 add(type, to);
97 }
98
Ayaka Koshibe67af1f42014-10-20 15:26:37 -070099 /**
100 * Summarizes this RoleValue as a RoleInfo. Note that master and/or backups
101 * may be empty, so the values should be checked for safety.
102 *
103 * @return the RoleInfo.
104 */
105 public RoleInfo roleInfo() {
106 return new RoleInfo(
107 get(MastershipRole.MASTER), nodesOfRole(MastershipRole.STANDBY));
108 }
109
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700110 @Override
111 public String toString() {
112 final StringBuilder builder = new StringBuilder();
113 for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) {
114 builder.append(el.getKey().toString()).append(": [");
115 for (NodeId n : el.getValue()) {
116 builder.append(n);
117 }
118 builder.append("]\n");
119 }
120 return builder.toString();
121 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700122}