blob: 3944a6a6c3223fc6150e3a66432cf0c665ff1cb5 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070016package org.onlab.onos.store.mastership.impl;
17
18import java.util.Collections;
Yuta HIGUCHI868def02014-10-23 12:09:43 -070019import java.util.EnumMap;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070020import java.util.LinkedList;
21import java.util.List;
22import java.util.Map;
23
24import org.onlab.onos.cluster.NodeId;
Ayaka Koshibeabedb092014-10-20 17:01:31 -070025import org.onlab.onos.cluster.RoleInfo;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070026import org.onlab.onos.net.MastershipRole;
27
Ayaka Koshibefc981cf2014-10-21 12:44:17 -070028import com.google.common.base.MoreObjects;
29import com.google.common.base.MoreObjects.ToStringHelper;
30
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070031/**
32 * A structure that holds node mastership roles associated with a
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070033 * {@link org.onlab.onos.net.DeviceId}. This structure needs to be locked through IMap.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070034 */
Yuta HIGUCHI868def02014-10-23 12:09:43 -070035final class RoleValue {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070036
Yuta HIGUCHI868def02014-10-23 12:09:43 -070037 protected final Map<MastershipRole, List<NodeId>> value = new EnumMap<>(MastershipRole.class);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070038
39 public RoleValue() {
40 value.put(MastershipRole.MASTER, new LinkedList<NodeId>());
41 value.put(MastershipRole.STANDBY, new LinkedList<NodeId>());
42 value.put(MastershipRole.NONE, new LinkedList<NodeId>());
43 }
44
Yuta HIGUCHI868def02014-10-23 12:09:43 -070045 // exposing internals for serialization purpose only
46 Map<MastershipRole, List<NodeId>> value() {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070047 return Collections.unmodifiableMap(value);
48 }
49
50 public List<NodeId> nodesOfRole(MastershipRole type) {
51 return value.get(type);
52 }
53
54 public NodeId get(MastershipRole type) {
55 return value.get(type).isEmpty() ? null : value.get(type).get(0);
56 }
57
58 public boolean contains(MastershipRole type, NodeId nodeId) {
59 return value.get(type).contains(nodeId);
60 }
61
62 /**
63 * Associates a node to a certain role.
64 *
65 * @param type the role
66 * @param nodeId the node ID of the node to associate
67 */
68 public void add(MastershipRole type, NodeId nodeId) {
69 List<NodeId> nodes = value.get(type);
70
71 if (!nodes.contains(nodeId)) {
72 nodes.add(nodeId);
73 }
74 }
75
76 /**
77 * Removes a node from a certain role.
78 *
79 * @param type the role
80 * @param nodeId the ID of the node to remove
81 * @return
82 */
83 public boolean remove(MastershipRole type, NodeId nodeId) {
84 List<NodeId> nodes = value.get(type);
85 if (!nodes.isEmpty()) {
86 return nodes.remove(nodeId);
87 } else {
88 return false;
89 }
90 }
91
92 /**
93 * Reassigns a node from one role to another. If the node was not of the
94 * old role, it will still be assigned the new role.
95 *
96 * @param nodeId the Node ID of node changing roles
97 * @param from the old role
98 * @param to the new role
99 */
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700100 public void reassign(NodeId nodeId, MastershipRole from, MastershipRole to) {
101 remove(from, nodeId);
102 add(to, nodeId);
103 }
104
105 /**
106 * Replaces a node in one role with another node. Even if there is no node to
107 * replace, the new node is associated to the role.
108 *
109 * @param from the old NodeId to replace
110 * @param to the new NodeId
111 * @param type the role associated with the old NodeId
112 */
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700113 public void replace(NodeId from, NodeId to, MastershipRole type) {
114 remove(type, from);
115 add(type, to);
116 }
117
Ayaka Koshibe67af1f42014-10-20 15:26:37 -0700118 /**
119 * Summarizes this RoleValue as a RoleInfo. Note that master and/or backups
120 * may be empty, so the values should be checked for safety.
121 *
122 * @return the RoleInfo.
123 */
124 public RoleInfo roleInfo() {
125 return new RoleInfo(
126 get(MastershipRole.MASTER), nodesOfRole(MastershipRole.STANDBY));
127 }
128
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700129 @Override
130 public String toString() {
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700131 ToStringHelper helper = MoreObjects.toStringHelper(this.getClass());
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700132 for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) {
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700133 helper.add(el.getKey().toString(), el.getValue());
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700134 }
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700135 return helper.toString();
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700136 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700137}