2 * Copyright 2014 Open Networking Laboratory
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.onosproject.store.mastership.impl;
18 import static org.onosproject.net.MastershipRole.MASTER;
19 import static org.onosproject.net.MastershipRole.NONE;
20 import static org.onosproject.net.MastershipRole.STANDBY;
22 import java.util.Collections;
23 import java.util.EnumMap;
24 import java.util.LinkedList;
25 import java.util.List;
28 import org.onosproject.cluster.NodeId;
29 import org.onosproject.cluster.RoleInfo;
30 import org.onosproject.net.MastershipRole;
32 import com.google.common.base.MoreObjects;
33 import com.google.common.base.MoreObjects.ToStringHelper;
34 import com.google.common.collect.Lists;
37 * A structure that holds node mastership roles associated with a
38 * {@link org.onosproject.net.DeviceId}. This structure needs to be locked through IMap.
40 final class RoleValue {
42 protected final Map<MastershipRole, List<NodeId>> value = new EnumMap<>(MastershipRole.class);
45 * Constructs empty RoleValue.
48 value.put(MastershipRole.MASTER, new LinkedList<NodeId>());
49 value.put(MastershipRole.STANDBY, new LinkedList<NodeId>());
50 value.put(MastershipRole.NONE, new LinkedList<NodeId>());
54 * Constructs copy of specified RoleValue.
56 * @param original original to create copy from
58 public RoleValue(final RoleValue original) {
59 value.put(MASTER, Lists.newLinkedList(original.value.get(MASTER)));
60 value.put(STANDBY, Lists.newLinkedList(original.value.get(STANDBY)));
61 value.put(NONE, Lists.newLinkedList(original.value.get(NONE)));
64 // exposing internals for serialization purpose only
65 Map<MastershipRole, List<NodeId>> value() {
66 return Collections.unmodifiableMap(value);
69 public List<NodeId> nodesOfRole(MastershipRole type) {
70 return value.get(type);
74 * Returns the first node to match the MastershipRole, or if there
77 * @param type the role
78 * @return a node ID or null
80 public NodeId get(MastershipRole type) {
81 return value.get(type).isEmpty() ? null : value.get(type).get(0);
84 public boolean contains(MastershipRole type, NodeId nodeId) {
85 return value.get(type).contains(nodeId);
88 public MastershipRole getRole(NodeId nodeId) {
89 if (contains(MASTER, nodeId)) {
92 if (contains(STANDBY, nodeId)) {
99 * Associates a node to a certain role.
101 * @param type the role
102 * @param nodeId the node ID of the node to associate
103 * @return true if modified
105 public boolean add(MastershipRole type, NodeId nodeId) {
106 List<NodeId> nodes = value.get(type);
108 if (!nodes.contains(nodeId)) {
109 return nodes.add(nodeId);
115 * Removes a node from a certain role.
117 * @param type the role
118 * @param nodeId the ID of the node to remove
119 * @return true if modified
121 public boolean remove(MastershipRole type, NodeId nodeId) {
122 List<NodeId> nodes = value.get(type);
123 if (!nodes.isEmpty()) {
124 return nodes.remove(nodeId);
131 * Reassigns a node from one role to another. If the node was not of the
132 * old role, it will still be assigned the new role.
134 * @param nodeId the Node ID of node changing roles
135 * @param from the old role
136 * @param to the new role
137 * @return true if modified
139 public boolean reassign(NodeId nodeId, MastershipRole from, MastershipRole to) {
140 boolean modified = remove(from, nodeId);
141 modified |= add(to, nodeId);
146 * Replaces a node in one role with another node. Even if there is no node to
147 * replace, the new node is associated to the role.
149 * @param from the old NodeId to replace
150 * @param to the new NodeId
151 * @param type the role associated with the old NodeId
152 * @return true if modified
154 public boolean replace(NodeId from, NodeId to, MastershipRole type) {
155 boolean modified = remove(type, from);
156 modified |= add(type, to);
161 * Summarizes this RoleValue as a RoleInfo. Note that master and/or backups
162 * may be empty, so the values should be checked for safety.
164 * @return the RoleInfo.
166 public RoleInfo roleInfo() {
168 get(MastershipRole.MASTER), nodesOfRole(MastershipRole.STANDBY));
172 public String toString() {
173 ToStringHelper helper = MoreObjects.toStringHelper(this.getClass());
174 for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) {
175 helper.add(el.getKey().toString(), el.getValue());
177 return helper.toString();