Implement cluster admin RPCs to change member voting states
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / jmx / mbeans / shard / ShardStats.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard;
10
11 import akka.actor.ActorRef;
12 import akka.pattern.Patterns;
13 import akka.util.Timeout;
14 import com.google.common.base.Joiner;
15 import com.google.common.base.Stopwatch;
16 import com.google.common.cache.Cache;
17 import com.google.common.cache.CacheBuilder;
18 import java.text.SimpleDateFormat;
19 import java.util.Date;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.atomic.AtomicLong;
24 import org.opendaylight.controller.cluster.datastore.Shard;
25 import org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot;
26 import org.opendaylight.controller.cluster.raft.client.messages.FollowerInfo;
27 import org.opendaylight.controller.cluster.raft.client.messages.GetOnDemandRaftState;
28 import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState;
29 import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
30 import scala.concurrent.Await;
31
32 /**
33  * Maintains statistics for a shard.
34  *
35  * @author  Basheeruddin syedbahm@cisco.com
36  */
37 public class ShardStats extends AbstractMXBean implements ShardStatsMXBean {
38     public static String JMX_CATEGORY_SHARD = "Shards";
39
40     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
41
42     private static final Cache<String, OnDemandRaftState> onDemandRaftStateCache =
43             CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build();
44
45     private long committedTransactionsCount;
46
47     private long readOnlyTransactionCount;
48
49     private long writeOnlyTransactionCount;
50
51     private long readWriteTransactionCount;
52
53     private long lastCommittedTransactionTime;
54
55     private long failedTransactionsCount;
56
57     private final AtomicLong failedReadTransactionsCount = new AtomicLong();
58
59     private long abortTransactionsCount;
60
61     private boolean followerInitialSyncStatus = false;
62
63     private Shard shard;
64
65     private String statRetrievalError;
66
67     private String statRetrievalTime;
68
69     private long leadershipChangeCount;
70
71     private long lastLeadershipChangeTime;
72
73     public ShardStats(final String shardName, final String mxBeanType) {
74         super(shardName, mxBeanType, JMX_CATEGORY_SHARD);
75     }
76
77     public void setShard(Shard shard) {
78         this.shard = shard;
79     }
80
81     private OnDemandRaftState getOnDemandRaftState() {
82         String name = getShardName();
83         OnDemandRaftState state = onDemandRaftStateCache.getIfPresent(name);
84         if(state == null) {
85             statRetrievalError = null;
86             statRetrievalTime = null;
87
88             if(shard != null) {
89                 Timeout timeout = new Timeout(10, TimeUnit.SECONDS);
90                 try {
91                     Stopwatch timer = Stopwatch.createStarted();
92
93                     state = (OnDemandRaftState) Await.result(Patterns.ask(shard.getSelf(),
94                             GetOnDemandRaftState.INSTANCE, timeout), timeout.duration());
95
96                     statRetrievalTime = timer.stop().toString();
97                     onDemandRaftStateCache.put(name, state);
98                 } catch (Exception e) {
99                     statRetrievalError = e.toString();
100                 }
101             }
102
103             state = state != null ? state : OnDemandRaftState.builder().build();
104         }
105
106         return state;
107     }
108
109     @Override
110     public String getShardName() {
111         return getMBeanName();
112     }
113
114     @Override
115     public long getCommittedTransactionsCount() {
116         return committedTransactionsCount;
117     }
118
119     @Override
120     public String getLeader() {
121         return getOnDemandRaftState().getLeader();
122     }
123
124     @Override
125     public String getRaftState() {
126         return getOnDemandRaftState().getRaftState();
127     }
128
129     @Override
130     public long getReadOnlyTransactionCount() {
131         return readOnlyTransactionCount;
132     }
133
134     @Override
135     public long getWriteOnlyTransactionCount() {
136         return writeOnlyTransactionCount;
137     }
138
139     @Override
140     public long getReadWriteTransactionCount() {
141         return readWriteTransactionCount;
142     }
143
144     @Override
145     public long getLastLogIndex() {
146         return getOnDemandRaftState().getLastLogIndex();
147     }
148
149     @Override
150     public long getLastLogTerm() {
151         return getOnDemandRaftState().getLastLogTerm();
152     }
153
154     @Override
155     public long getCurrentTerm() {
156         return getOnDemandRaftState().getCurrentTerm();
157     }
158
159     @Override
160     public long getCommitIndex() {
161         return getOnDemandRaftState().getCommitIndex();
162     }
163
164     @Override
165     public long getLastApplied() {
166         return getOnDemandRaftState().getLastApplied();
167     }
168
169     @Override
170     public long getLastIndex() {
171         return getOnDemandRaftState().getLastIndex();
172     }
173
174     @Override
175     public long getLastTerm() {
176         return getOnDemandRaftState().getLastTerm();
177     }
178
179     @Override
180     public long getSnapshotIndex() {
181         return getOnDemandRaftState().getSnapshotIndex();
182     }
183
184     @Override
185     public long getSnapshotTerm() {
186         return getOnDemandRaftState().getSnapshotTerm();
187     }
188
189     @Override
190     public long getReplicatedToAllIndex() {
191         return getOnDemandRaftState().getReplicatedToAllIndex();
192     }
193
194     @Override
195     public String getVotedFor() {
196         return getOnDemandRaftState().getVotedFor();
197     }
198     @Override
199     public boolean isVoting() {
200         return getOnDemandRaftState().isVoting();
201     }
202
203     @Override
204     public String getPeerVotingStates() {
205         return toStringMap(getOnDemandRaftState().getPeerVotingStates());
206     }
207
208     @Override
209     public boolean isSnapshotCaptureInitiated() {
210         return getOnDemandRaftState().isSnapshotCaptureInitiated();
211     }
212
213     @Override
214     public String getLastCommittedTransactionTime() {
215         return DATE_FORMAT.format(new Date(lastCommittedTransactionTime));
216     }
217
218     @Override
219     public long getFailedTransactionsCount() {
220         return failedTransactionsCount;
221     }
222
223     @Override
224     public long getFailedReadTransactionsCount() {
225         return failedReadTransactionsCount.get();
226     }
227
228     @Override
229     public long getAbortTransactionsCount() {
230         return abortTransactionsCount;
231     }
232
233     public long incrementCommittedTransactionCount() {
234         return ++committedTransactionsCount;
235     }
236
237     public long incrementReadOnlyTransactionCount() {
238         return ++readOnlyTransactionCount;
239     }
240
241     public long incrementWriteOnlyTransactionCount() {
242         return ++writeOnlyTransactionCount;
243     }
244
245     public long incrementReadWriteTransactionCount() {
246         return ++readWriteTransactionCount;
247     }
248
249     public long incrementFailedTransactionsCount() {
250         return ++failedTransactionsCount;
251     }
252
253     public long incrementFailedReadTransactionsCount() {
254         return failedReadTransactionsCount.incrementAndGet();
255     }
256
257     public long incrementAbortTransactionsCount ()
258     {
259         return ++abortTransactionsCount;
260     }
261
262     public void setLastCommittedTransactionTime(final long lastCommittedTransactionTime) {
263         this.lastCommittedTransactionTime = lastCommittedTransactionTime;
264     }
265
266     @Override
267     public long getInMemoryJournalDataSize(){
268         return getOnDemandRaftState().getInMemoryJournalDataSize();
269     }
270
271     @Override
272     public long getInMemoryJournalLogSize() {
273         return getOnDemandRaftState().getInMemoryJournalLogSize();
274     }
275
276     /**
277      * resets the counters related to transactions
278      */
279     @Override
280     public void resetTransactionCounters(){
281         committedTransactionsCount = 0;
282
283         readOnlyTransactionCount = 0;
284
285         writeOnlyTransactionCount = 0;
286
287         readWriteTransactionCount = 0;
288
289         lastCommittedTransactionTime = 0;
290
291         failedTransactionsCount = 0;
292
293         failedReadTransactionsCount.set(0);
294
295         abortTransactionsCount = 0;
296
297     }
298
299     public void setFollowerInitialSyncStatus(boolean followerInitialSyncStatus) {
300         this.followerInitialSyncStatus = followerInitialSyncStatus;
301     }
302
303     @Override
304     public boolean getFollowerInitialSyncStatus() {
305         return followerInitialSyncStatus;
306     }
307
308     @Override
309     public List<FollowerInfo> getFollowerInfo() {
310         return getOnDemandRaftState().getFollowerInfoList();
311     }
312
313     @Override
314     public String getPeerAddresses() {
315         return toStringMap(getOnDemandRaftState().getPeerAddresses());
316     }
317
318     private static String toStringMap(Map<?, ?> map) {
319         return Joiner.on(", ").withKeyValueSeparator(": ").join(map);
320     }
321
322     @Override
323     public String getStatRetrievalTime() {
324         getOnDemandRaftState();
325         return statRetrievalTime;
326     }
327
328     @Override
329     public String getStatRetrievalError() {
330         getOnDemandRaftState();
331         return statRetrievalError;
332     }
333
334     @Override
335     public long getLeadershipChangeCount() {
336         return leadershipChangeCount;
337     }
338
339     public void incrementLeadershipChangeCount() {
340         leadershipChangeCount++;
341         lastLeadershipChangeTime = System.currentTimeMillis();
342     }
343
344     @Override
345     public String getLastLeadershipChangeTime() {
346         return DATE_FORMAT.format(new Date(lastLeadershipChangeTime));
347     }
348
349     @Override
350     public int getPendingTxCommitQueueSize() {
351         return shard.getPendingTxCommitQueueSize();
352     }
353
354     @Override
355     public int getTxCohortCacheSize() {
356         return shard.getCohortCacheSize();
357     }
358
359     @Override
360     public void captureSnapshot() {
361         if(shard != null) {
362             shard.getSelf().tell(new InitiateCaptureSnapshot(), ActorRef.noSender());
363         }
364     }
365 }