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