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