blob: 113e19cbdc24b67c18fe710a21edac06d093a321 [file] [log] [blame]
alshabibab984662014-12-04 18:56:18 -08001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
alshabibab984662014-12-04 18:56:18 -08003 *
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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.cluster;
Madan Jampani1d3494e2014-11-20 11:24:22 -080017
18import java.util.Objects;
Ayaka Koshibea48f7522015-04-01 17:06:09 -070019import java.util.List;
Ayaka Koshibefd26a302015-04-13 13:59:54 -070020import java.util.Optional;
Madan Jampani1d3494e2014-11-20 11:24:22 -080021
Madan Jampani30a57f82015-03-02 12:19:41 -080022import org.joda.time.DateTime;
23
Madan Jampani1d3494e2014-11-20 11:24:22 -080024import com.google.common.base.MoreObjects;
Ayaka Koshibea48f7522015-04-01 17:06:09 -070025import com.google.common.collect.ImmutableList;
Madan Jampani1d3494e2014-11-20 11:24:22 -080026
27/**
Ayaka Koshibea48f7522015-04-01 17:06:09 -070028 * Abstract leadership concept. The information carried by this construct
29 * include the topic of contention, the {@link NodeId}s of Nodes that could
30 * become leader for the topic, the epoch when the term for a given leader
31 * began, and the system time when the term began. Note:
32 * <ul>
33 * <li>The list of NodeIds may include the current leader at index 0, and the
34 * rest in decreasing preference order.</li>
35 * <li>The epoch is the logical age of a Leadership construct, and should be
36 * used for comparing two Leaderships, but only of the same topic.</li>
Ayaka Koshibefd26a302015-04-13 13:59:54 -070037 * <li>The leader may be null if its accuracy can't be guaranteed. This applies
38 * to CANDIDATES_CHANGED events and candidate board contents.</li>
Ayaka Koshibea48f7522015-04-01 17:06:09 -070039 * </ul>
Madan Jampani1d3494e2014-11-20 11:24:22 -080040 */
41public class Leadership {
42
43 private final String topic;
Ayaka Koshibefd26a302015-04-13 13:59:54 -070044 private final Optional<NodeId> leader;
Ayaka Koshibea48f7522015-04-01 17:06:09 -070045 private final List<NodeId> candidates;
Madan Jampani1ee91782014-11-20 20:24:24 -080046 private final long epoch;
Madan Jampani30a57f82015-03-02 12:19:41 -080047 private final long electedTime;
Madan Jampani1d3494e2014-11-20 11:24:22 -080048
Madan Jampani30a57f82015-03-02 12:19:41 -080049 public Leadership(String topic, NodeId leader, long epoch, long electedTime) {
Madan Jampani1d3494e2014-11-20 11:24:22 -080050 this.topic = topic;
Ayaka Koshibefd26a302015-04-13 13:59:54 -070051 this.leader = Optional.of(leader);
Ayaka Koshibea48f7522015-04-01 17:06:09 -070052 this.candidates = ImmutableList.of(leader);
53 this.epoch = epoch;
54 this.electedTime = electedTime;
55 }
56
57 public Leadership(String topic, NodeId leader, List<NodeId> candidates,
58 long epoch, long electedTime) {
59 this.topic = topic;
Ayaka Koshibefd26a302015-04-13 13:59:54 -070060 this.leader = Optional.of(leader);
61 this.candidates = ImmutableList.copyOf(candidates);
62 this.epoch = epoch;
63 this.electedTime = electedTime;
64 }
65
66 public Leadership(String topic, List<NodeId> candidates,
67 long epoch, long electedTime) {
68 this.topic = topic;
69 this.leader = Optional.empty();
Ayaka Koshibea48f7522015-04-01 17:06:09 -070070 this.candidates = ImmutableList.copyOf(candidates);
Madan Jampani1ee91782014-11-20 20:24:24 -080071 this.epoch = epoch;
Madan Jampani30a57f82015-03-02 12:19:41 -080072 this.electedTime = electedTime;
Madan Jampani1d3494e2014-11-20 11:24:22 -080073 }
74
75 /**
76 * The topic for which this leadership applies.
Sho SHIMIZU25d843c2015-04-10 16:52:33 -070077 *
Madan Jampani1d3494e2014-11-20 11:24:22 -080078 * @return leadership topic.
79 */
80 public String topic() {
81 return topic;
82 }
83
84 /**
Madan Jampani8d21c792014-12-01 16:31:07 -080085 * The nodeId of leader for this topic.
Sho SHIMIZU25d843c2015-04-10 16:52:33 -070086 *
Madan Jampani1d3494e2014-11-20 11:24:22 -080087 * @return leader node.
88 */
Ayaka Koshibefd26a302015-04-13 13:59:54 -070089 // This will return Optional<NodeId> in the future.
Madan Jampani8d21c792014-12-01 16:31:07 -080090 public NodeId leader() {
Ayaka Koshibefd26a302015-04-13 13:59:54 -070091 return leader.orElse(null);
Madan Jampani1d3494e2014-11-20 11:24:22 -080092 }
93
94 /**
Ayaka Koshibea48f7522015-04-01 17:06:09 -070095 * Returns an preference-ordered list of nodes that are in the leadership
96 * race for this topic.
97 *
98 * @return a list of NodeIds in priority-order, or an empty list.
99 */
100 public List<NodeId> candidates() {
101 return candidates;
102 }
103
104 /**
Madan Jampani1ee91782014-11-20 20:24:24 -0800105 * The epoch when the leadership was assumed.
Madan Jampani30a57f82015-03-02 12:19:41 -0800106 * <p>
Ayaka Koshibea48f7522015-04-01 17:06:09 -0700107 * Comparing epochs is only appropriate for leadership events for the same
108 * topic. The system guarantees that for any given topic the epoch for a new
109 * term is higher (not necessarily by 1) than the epoch for any previous
110 * term.
111 *
Madan Jampani1ee91782014-11-20 20:24:24 -0800112 * @return leadership epoch
Madan Jampani1d3494e2014-11-20 11:24:22 -0800113 */
Madan Jampani1ee91782014-11-20 20:24:24 -0800114 public long epoch() {
115 return epoch;
Madan Jampani1d3494e2014-11-20 11:24:22 -0800116 }
117
Madan Jampani30a57f82015-03-02 12:19:41 -0800118 /**
119 * The system time when the term started.
120 * <p>
121 * The elected time is initially set on the node coordinating
122 * the leader election using its local system time. Due to possible
123 * clock skew, relying on this value for determining event ordering
124 * is discouraged. Epoch is more appropriate for determining
125 * event ordering.
Sho SHIMIZU25d843c2015-04-10 16:52:33 -0700126 *
Madan Jampani30a57f82015-03-02 12:19:41 -0800127 * @return elected time.
128 */
129 public long electedTime() {
130 return electedTime;
131 }
132
Madan Jampani1d3494e2014-11-20 11:24:22 -0800133 @Override
134 public int hashCode() {
Ray Milkey50510402015-06-11 14:36:01 -0700135 return Objects.hash(topic, leader, candidates, epoch, electedTime);
Madan Jampani1d3494e2014-11-20 11:24:22 -0800136 }
137
138 @Override
Ray Milkey30edb162014-11-24 15:02:14 -0800139 public boolean equals(Object obj) {
140 if (this == obj) {
141 return true;
142 }
143 if (obj instanceof Leadership) {
144 final Leadership other = (Leadership) obj;
145 return Objects.equals(this.topic, other.topic) &&
Ray Milkey50510402015-06-11 14:36:01 -0700146 Objects.equals(this.leader, other.leader) &&
147 Objects.equals(this.candidates, other.candidates) &&
148 Objects.equals(this.epoch, other.epoch) &&
149 Objects.equals(this.electedTime, other.electedTime);
Ray Milkey30edb162014-11-24 15:02:14 -0800150 }
151 return false;
152 }
153
154 @Override
Madan Jampani1d3494e2014-11-20 11:24:22 -0800155 public String toString() {
156 return MoreObjects.toStringHelper(this.getClass())
157 .add("topic", topic)
158 .add("leader", leader)
Ayaka Koshibea48f7522015-04-01 17:06:09 -0700159 .add("candidates", candidates)
Madan Jampani1ee91782014-11-20 20:24:24 -0800160 .add("epoch", epoch)
Madan Jampani30a57f82015-03-02 12:19:41 -0800161 .add("electedTime", new DateTime(electedTime))
Madan Jampani1d3494e2014-11-20 11:24:22 -0800162 .toString();
163 }
Ray Milkey30edb162014-11-24 15:02:14 -0800164}