diff options
Diffstat (limited to 'framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/RoleValue.java')
-rw-r--r-- | framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/RoleValue.java | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/RoleValue.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/RoleValue.java new file mode 100644 index 00000000..9d3b1686 --- /dev/null +++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/RoleValue.java @@ -0,0 +1,179 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.store.mastership.impl; + +import static org.onosproject.net.MastershipRole.MASTER; +import static org.onosproject.net.MastershipRole.NONE; +import static org.onosproject.net.MastershipRole.STANDBY; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.onosproject.cluster.NodeId; +import org.onosproject.cluster.RoleInfo; +import org.onosproject.net.MastershipRole; + +import com.google.common.base.MoreObjects; +import com.google.common.base.MoreObjects.ToStringHelper; +import com.google.common.collect.Lists; + +/** + * A structure that holds node mastership roles associated with a + * {@link org.onosproject.net.DeviceId}. This structure needs to be locked through IMap. + */ +final class RoleValue { + + protected final Map<MastershipRole, List<NodeId>> value = new EnumMap<>(MastershipRole.class); + + /** + * Constructs empty RoleValue. + */ + public RoleValue() { + value.put(MastershipRole.MASTER, new LinkedList<NodeId>()); + value.put(MastershipRole.STANDBY, new LinkedList<NodeId>()); + value.put(MastershipRole.NONE, new LinkedList<NodeId>()); + } + + /** + * Constructs copy of specified RoleValue. + * + * @param original original to create copy from + */ + public RoleValue(final RoleValue original) { + value.put(MASTER, Lists.newLinkedList(original.value.get(MASTER))); + value.put(STANDBY, Lists.newLinkedList(original.value.get(STANDBY))); + value.put(NONE, Lists.newLinkedList(original.value.get(NONE))); + } + + // exposing internals for serialization purpose only + Map<MastershipRole, List<NodeId>> value() { + return Collections.unmodifiableMap(value); + } + + public List<NodeId> nodesOfRole(MastershipRole type) { + return value.get(type); + } + + /** + * Returns the first node to match the MastershipRole, or if there + * are none, null. + * + * @param type the role + * @return a node ID or null + */ + public NodeId get(MastershipRole type) { + return value.get(type).isEmpty() ? null : value.get(type).get(0); + } + + public boolean contains(MastershipRole type, NodeId nodeId) { + return value.get(type).contains(nodeId); + } + + public MastershipRole getRole(NodeId nodeId) { + if (contains(MASTER, nodeId)) { + return MASTER; + } + if (contains(STANDBY, nodeId)) { + return STANDBY; + } + return NONE; + } + + /** + * Associates a node to a certain role. + * + * @param type the role + * @param nodeId the node ID of the node to associate + * @return true if modified + */ + public boolean add(MastershipRole type, NodeId nodeId) { + List<NodeId> nodes = value.get(type); + + if (!nodes.contains(nodeId)) { + return nodes.add(nodeId); + } + return false; + } + + /** + * Removes a node from a certain role. + * + * @param type the role + * @param nodeId the ID of the node to remove + * @return true if modified + */ + public boolean remove(MastershipRole type, NodeId nodeId) { + List<NodeId> nodes = value.get(type); + if (!nodes.isEmpty()) { + return nodes.remove(nodeId); + } else { + return false; + } + } + + /** + * Reassigns a node from one role to another. If the node was not of the + * old role, it will still be assigned the new role. + * + * @param nodeId the Node ID of node changing roles + * @param from the old role + * @param to the new role + * @return true if modified + */ + public boolean reassign(NodeId nodeId, MastershipRole from, MastershipRole to) { + boolean modified = remove(from, nodeId); + modified |= add(to, nodeId); + return modified; + } + + /** + * Replaces a node in one role with another node. Even if there is no node to + * replace, the new node is associated to the role. + * + * @param from the old NodeId to replace + * @param to the new NodeId + * @param type the role associated with the old NodeId + * @return true if modified + */ + public boolean replace(NodeId from, NodeId to, MastershipRole type) { + boolean modified = remove(type, from); + modified |= add(type, to); + return modified; + } + + /** + * 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() { + ToStringHelper helper = MoreObjects.toStringHelper(this.getClass()); + for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) { + helper.add(el.getKey().toString(), el.getValue()); + } + return helper.toString(); + } +} |