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