Merge "Bug#1854 - Exit command in console causing OOM."
[controller.git] / opendaylight / md-sal / sal-common-util / src / main / java / org / opendaylight / controller / md / sal / common / util / jmx / ThreadExecutorStatsMXBeanImpl.java
1 /*
2  * Copyright (c) 2014 Brocade Communications 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.md.sal.common.util.jmx;
10
11 import com.google.common.base.Preconditions;
12 import java.util.concurrent.BlockingQueue;
13 import java.util.concurrent.Executor;
14 import java.util.concurrent.RejectedExecutionHandler;
15 import java.util.concurrent.ThreadPoolExecutor;
16 import javax.annotation.Nullable;
17 import org.opendaylight.yangtools.util.concurrent.CountingRejectedExecutionHandler;
18 import org.opendaylight.yangtools.util.concurrent.TrackingLinkedBlockingQueue;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 /**
23  * MXBean implementation of the ThreadExecutorStatsMXBean interface that retrieves statistics
24  * from a backing {@link java.util.concurrent.ExecutorService}.
25  *
26  * @author Thomas Pantelis
27  */
28 public class ThreadExecutorStatsMXBeanImpl extends AbstractMXBean
29                                            implements ThreadExecutorStatsMXBean {
30     private static final Logger LOG = LoggerFactory.getLogger(ThreadExecutorStatsMXBeanImpl.class);
31     private final ThreadPoolExecutor executor;
32
33     /**
34      * Constructs an instance for the given {@link Executor}.
35      *
36      * @param executor the backing {@link Executor}
37      * @param mBeanName Used as the <code>name</code> property in the bean's ObjectName.
38      * @param mBeanType Used as the <code>type</code> property in the bean's ObjectName.
39      * @param mBeanCategory Used as the <code>Category</code> property in the bean's ObjectName.
40      */
41     public ThreadExecutorStatsMXBeanImpl(final ThreadPoolExecutor executor, final String mBeanName,
42             final String mBeanType, @Nullable final String mBeanCategory) {
43         super(mBeanName, mBeanType, mBeanCategory);
44         this.executor = Preconditions.checkNotNull(executor);
45     }
46
47     /**
48      * Create a new bean for the statistics, which is already registered.
49      *
50      * @param executor
51      * @param mBeanName
52      * @param mBeanType
53      * @param mBeanCategory
54      * @return
55      */
56     public static ThreadExecutorStatsMXBeanImpl create(final Executor executor, final String mBeanName,
57             final String mBeanType, @Nullable final String mBeanCategory) {
58         if (executor instanceof ThreadPoolExecutor) {
59             final ThreadExecutorStatsMXBeanImpl ret = new ThreadExecutorStatsMXBeanImpl((ThreadPoolExecutor) executor, mBeanName, mBeanType, mBeanCategory);
60             ret.registerMBean();
61             return ret;
62         }
63
64         LOG.info("Executor {} is not supported", executor);
65         return null;
66     }
67
68     @Override
69     public long getCurrentThreadPoolSize() {
70         return executor.getPoolSize();
71     }
72
73     @Override
74     public long getLargestThreadPoolSize() {
75         return  executor.getLargestPoolSize();
76     }
77
78     @Override
79     public long getMaxThreadPoolSize() {
80         return executor.getMaximumPoolSize();
81     }
82
83     @Override
84     public long getCurrentQueueSize() {
85         return executor.getQueue().size();
86     }
87
88     @Override
89     public Long getLargestQueueSize() {
90         BlockingQueue<Runnable> queue = executor.getQueue();
91         if(queue instanceof TrackingLinkedBlockingQueue) {
92             return Long.valueOf(((TrackingLinkedBlockingQueue<?>)queue).getLargestQueueSize());
93         }
94
95         return null;
96     }
97
98     @Override
99     public long getMaxQueueSize() {
100         long queueSize = executor.getQueue().size();
101         return executor.getQueue().remainingCapacity() + queueSize;
102     }
103
104     @Override
105     public long getActiveThreadCount() {
106         return executor.getActiveCount();
107     }
108
109     @Override
110     public long getCompletedTaskCount() {
111         return  executor.getCompletedTaskCount();
112     }
113
114     @Override
115     public long getTotalTaskCount() {
116         return executor.getTaskCount();
117     }
118
119     @Override
120     public Long getRejectedTaskCount() {
121         RejectedExecutionHandler rejectedHandler = executor.getRejectedExecutionHandler();
122         if(rejectedHandler instanceof CountingRejectedExecutionHandler) {
123             return Long.valueOf(((CountingRejectedExecutionHandler)rejectedHandler)
124                                                                      .getRejectedTaskCount());
125         }
126
127         return null;
128     }
129
130     /**
131      * Returns a {@link ThreadExecutorStats} instance containing a snapshot of the statistic
132      * metrics.
133      */
134     public ThreadExecutorStats toThreadExecutorStats() {
135         return new ThreadExecutorStats(getActiveThreadCount(), getCurrentThreadPoolSize(),
136                 getLargestThreadPoolSize(), getMaxThreadPoolSize(), getCurrentQueueSize(),
137                 getLargestQueueSize(), getMaxQueueSize(), getCompletedTaskCount(),
138                 getTotalTaskCount(), getRejectedTaskCount());
139     }
140 }