Move FollowerInfo
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / 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 package org.opendaylight.controller.cluster.datastore;
9
10 import akka.actor.ActorRef;
11 import com.google.common.base.Joiner;
12 import com.google.common.base.Joiner.MapJoiner;
13 import java.text.SimpleDateFormat;
14 import java.util.Date;
15 import java.util.List;
16 import java.util.concurrent.atomic.AtomicLong;
17 import org.checkerframework.checker.lock.qual.GuardedBy;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStatsMXBean;
20 import org.opendaylight.controller.cluster.mgmt.api.FollowerInfo;
21 import org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot;
22 import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState;
23 import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
24
25 /**
26  * Maintains statistics for a shard.
27  *
28  * @author  Basheeruddin syedbahm@cisco.com
29  */
30 final class ShardStats extends AbstractMXBean implements ShardStatsMXBean {
31     public static final String JMX_CATEGORY_SHARD = "Shards";
32
33     // FIXME: migrate this to Java 8 thread-safe time
34     @GuardedBy("DATE_FORMAT")
35     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
36
37     private static final MapJoiner MAP_JOINER = Joiner.on(", ").withKeyValueSeparator(": ");
38
39     private final Shard shard;
40
41     private final OnDemandShardStateCache stateCache;
42
43     private long committedTransactionsCount;
44
45     private long readOnlyTransactionCount;
46
47     private long readWriteTransactionCount;
48
49     private long lastCommittedTransactionTime;
50
51     private long failedTransactionsCount;
52
53     private final AtomicLong failedReadTransactionsCount = new AtomicLong();
54
55     private long abortTransactionsCount;
56
57     private boolean followerInitialSyncStatus = false;
58
59     private String statRetrievalError;
60
61     private long leadershipChangeCount;
62
63     private long lastLeadershipChangeTime;
64
65     ShardStats(final String shardName, final String mxBeanType, final @Nullable Shard shard) {
66         super(shardName, mxBeanType, JMX_CATEGORY_SHARD);
67         this.shard = shard;
68         stateCache = new OnDemandShardStateCache(shardName, shard != null ? shard.self() : null);
69     }
70
71     @SuppressWarnings("checkstyle:IllegalCatch")
72     private OnDemandRaftState getOnDemandRaftState() {
73         try {
74             final OnDemandRaftState state = stateCache.get();
75             statRetrievalError = null;
76             return state;
77         } catch (Exception e) {
78             statRetrievalError = e.getCause().toString();
79             return OnDemandRaftState.builder().build();
80         }
81     }
82
83     private static String formatMillis(final long timeMillis) {
84         synchronized (DATE_FORMAT) {
85             return DATE_FORMAT.format(new Date(timeMillis));
86         }
87     }
88
89     @Override
90     public String getShardName() {
91         return getMBeanName();
92     }
93
94     @Override
95     public long getCommittedTransactionsCount() {
96         return committedTransactionsCount;
97     }
98
99     @Override
100     public String getLeader() {
101         return getOnDemandRaftState().getLeader();
102     }
103
104     @Override
105     public String getRaftState() {
106         return getOnDemandRaftState().getRaftState();
107     }
108
109     @Override
110     public long getReadOnlyTransactionCount() {
111         return readOnlyTransactionCount;
112     }
113
114     @Override
115     public long getReadWriteTransactionCount() {
116         return readWriteTransactionCount;
117     }
118
119     @Override
120     public long getLastLogIndex() {
121         return getOnDemandRaftState().getLastLogIndex();
122     }
123
124     @Override
125     public long getLastLogTerm() {
126         return getOnDemandRaftState().getLastLogTerm();
127     }
128
129     @Override
130     public long getCurrentTerm() {
131         return getOnDemandRaftState().getCurrentTerm();
132     }
133
134     @Override
135     public long getCommitIndex() {
136         return getOnDemandRaftState().getCommitIndex();
137     }
138
139     @Override
140     public long getLastApplied() {
141         return getOnDemandRaftState().getLastApplied();
142     }
143
144     @Override
145     public long getLastIndex() {
146         return getOnDemandRaftState().getLastIndex();
147     }
148
149     @Override
150     public long getLastTerm() {
151         return getOnDemandRaftState().getLastTerm();
152     }
153
154     @Override
155     public long getSnapshotIndex() {
156         return getOnDemandRaftState().getSnapshotIndex();
157     }
158
159     @Override
160     public long getSnapshotTerm() {
161         return getOnDemandRaftState().getSnapshotTerm();
162     }
163
164     @Override
165     public long getReplicatedToAllIndex() {
166         return getOnDemandRaftState().getReplicatedToAllIndex();
167     }
168
169     @Override
170     public String getVotedFor() {
171         return getOnDemandRaftState().getVotedFor();
172     }
173
174     @Override
175     public boolean isVoting() {
176         return getOnDemandRaftState().isVoting();
177     }
178
179     @Override
180     public String getPeerVotingStates() {
181         return MAP_JOINER.join(getOnDemandRaftState().getPeerVotingStates());
182     }
183
184     @Override
185     public boolean isSnapshotCaptureInitiated() {
186         return getOnDemandRaftState().isSnapshotCaptureInitiated();
187     }
188
189     @Override
190     public String getLastCommittedTransactionTime() {
191         return formatMillis(lastCommittedTransactionTime);
192     }
193
194     @Override
195     public long getFailedTransactionsCount() {
196         return failedTransactionsCount;
197     }
198
199     @Override
200     public long getFailedReadTransactionsCount() {
201         return failedReadTransactionsCount.get();
202     }
203
204     @Override
205     public long getAbortTransactionsCount() {
206         return abortTransactionsCount;
207     }
208
209     public long incrementCommittedTransactionCount() {
210         return ++committedTransactionsCount;
211     }
212
213     public long incrementReadOnlyTransactionCount() {
214         return ++readOnlyTransactionCount;
215     }
216
217     public long incrementReadWriteTransactionCount() {
218         return ++readWriteTransactionCount;
219     }
220
221     public long incrementFailedTransactionsCount() {
222         return ++failedTransactionsCount;
223     }
224
225     public long incrementFailedReadTransactionsCount() {
226         return failedReadTransactionsCount.incrementAndGet();
227     }
228
229     public long incrementAbortTransactionsCount() {
230         return ++abortTransactionsCount;
231     }
232
233     public void setLastCommittedTransactionTime(final long lastCommittedTransactionTime) {
234         this.lastCommittedTransactionTime = lastCommittedTransactionTime;
235     }
236
237     @Override
238     public long getInMemoryJournalDataSize() {
239         return getOnDemandRaftState().getInMemoryJournalDataSize();
240     }
241
242     @Override
243     public long getInMemoryJournalLogSize() {
244         return getOnDemandRaftState().getInMemoryJournalLogSize();
245     }
246
247     /**
248      * Resets the counters related to transactions.
249      */
250     @Override
251     public void resetTransactionCounters() {
252         committedTransactionsCount = 0;
253
254         readOnlyTransactionCount = 0;
255
256         readWriteTransactionCount = 0;
257
258         lastCommittedTransactionTime = 0;
259
260         failedTransactionsCount = 0;
261
262         failedReadTransactionsCount.set(0);
263
264         abortTransactionsCount = 0;
265
266     }
267
268     public void setFollowerInitialSyncStatus(final boolean followerInitialSyncStatus) {
269         this.followerInitialSyncStatus = followerInitialSyncStatus;
270     }
271
272     @Override
273     public boolean getFollowerInitialSyncStatus() {
274         return followerInitialSyncStatus;
275     }
276
277     @Override
278     public List<FollowerInfo> getFollowerInfo() {
279         return getOnDemandRaftState().getFollowerInfoList();
280     }
281
282     @Override
283     public String getPeerAddresses() {
284         return MAP_JOINER.join(getOnDemandRaftState().getPeerAddresses());
285     }
286
287     @Override
288     public String getStatRetrievalTime() {
289         getOnDemandRaftState();
290         return stateCache.getStatRetrievaelTime();
291     }
292
293     @Override
294     public String getStatRetrievalError() {
295         getOnDemandRaftState();
296         return statRetrievalError;
297     }
298
299     @Override
300     public long getLeadershipChangeCount() {
301         return leadershipChangeCount;
302     }
303
304     public void incrementLeadershipChangeCount() {
305         leadershipChangeCount++;
306         lastLeadershipChangeTime = System.currentTimeMillis();
307     }
308
309     @Override
310     public String getLastLeadershipChangeTime() {
311         return formatMillis(lastLeadershipChangeTime);
312     }
313
314     @Override
315     public int getPendingTxCommitQueueSize() {
316         return shard != null ? shard.getPendingTxCommitQueueSize() : -1;
317     }
318
319     @Override
320     public int getTxCohortCacheSize() {
321         return shard != null ? shard.getCohortCacheSize() : -1;
322     }
323
324     @Override
325     public void captureSnapshot() {
326         if (shard != null) {
327             shard.getSelf().tell(new InitiateCaptureSnapshot(), ActorRef.noSender());
328         }
329     }
330 }