1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 import java.util.*;
37 import javax.management.*;
38 import javax.management.monitor.*;
39
40
41
42
43
44
45 public class MultiMonitorTest {
46 static final int N = 100;
47 static final ObjectName[] mbeanNames = new ObjectName[N];
48 static final Monitored[] monitored = new Monitored[N];
49 static final int COUNTER_THRESHOLD = 1000;
50 static final int OVER_COUNTER_THRESHOLD = 2000;
51 static final double GAUGE_THRESHOLD = 1000.0;
52 static final double OVER_GAUGE_THRESHOLD = 2000.0;
53 static final String STRING_TO_COMPARE = "chou";
54 static final String DIFFERENT_STRING = "chevre";
55
56 public static void main(String[] args) throws Exception {
57 System.out.println("Test that monitors can sample a large " +
58 "number of attributes");
59
60 final MBeanServer mbs = MBeanServerFactory.createMBeanServer();
61 for (int i = 0; i < N; i++) {
62 mbeanNames[i] = new ObjectName(":type=Monitored,instance=" + i);
63 monitored[i] = new Monitored();
64 mbs.registerMBean(monitored[i], mbeanNames[i]);
65 }
66 final ObjectName counterMonitor =
67 new ObjectName(":type=CounterMonitor");
68 final ObjectName gaugeMonitor =
69 new ObjectName(":type=GaugeMonitor");
70 final ObjectName stringMonitor =
71 new ObjectName(":type=StringMonitor");
72 final ObjectName[] monitorNames =
73 new ObjectName[] {counterMonitor, gaugeMonitor, stringMonitor};
74 final String[] attrNames =
75 new String[] {"CounterValue", "GaugeValue", "StringValue"};
76 mbs.createMBean(CounterMonitor.class.getName(), counterMonitor);
77 mbs.createMBean(GaugeMonitor.class.getName(), gaugeMonitor);
78 mbs.createMBean(StringMonitor.class.getName(), stringMonitor);
79 final CounterMonitorMBean counterProxy = (CounterMonitorMBean)
80 MBeanServerInvocationHandler
81 .newProxyInstance(mbs, counterMonitor, CounterMonitorMBean.class,
82 false);
83 final GaugeMonitorMBean gaugeProxy = (GaugeMonitorMBean)
84 MBeanServerInvocationHandler
85 .newProxyInstance(mbs, gaugeMonitor, GaugeMonitorMBean.class,
86 false);
87 final StringMonitorMBean stringProxy = (StringMonitorMBean)
88 MBeanServerInvocationHandler
89 .newProxyInstance(mbs, stringMonitor, StringMonitorMBean.class,
90 false);
91 final MonitorMBean[] proxies = new MonitorMBean[] {
92 counterProxy, gaugeProxy, stringProxy,
93 };
94 for (int i = 0; i < 3; i++) {
95 proxies[i].setGranularityPeriod(1);
96 proxies[i].setObservedAttribute(attrNames[i]);
97 for (int j = 0; j < N; j++)
98 proxies[i].addObservedObject(mbeanNames[j]);
99 }
100
101 final CountListener[] listeners = new CountListener[] {
102 new CountListener(), new CountListener(), new CountListener()
103 };
104 for (int i = 0; i < 3; i++) {
105 mbs.addNotificationListener(monitorNames[i], listeners[i],
106 null, null);
107 }
108
109 counterProxy.setInitThreshold(new Integer(COUNTER_THRESHOLD));
110 counterProxy.setNotify(true);
111 gaugeProxy.setThresholds(new Double(GAUGE_THRESHOLD), new Double(0.0));
112 gaugeProxy.setNotifyHigh(true);
113 stringProxy.setStringToCompare(STRING_TO_COMPARE);
114 stringProxy.setNotifyDiffer(true);
115
116
117 Thread.sleep(2);
118
119 System.out.println("Checking for all listeners to be 0");
120 if (!listenersAreAll(0, listeners)) {
121 System.out.println("TEST FAILED: listeners not all 0");
122 System.exit(1);
123 }
124
125 for (int i = 0; i < 3; i++)
126 proxies[i].start();
127
128 System.out.println("Waiting for listeners to all : " + N);
129 int iterations = 0;
130 while (!listenersAreAll(N, listeners)) {
131 Thread.sleep(500);
132
133 if (++iterations == 10) {
134 for (int i = 0; i < listeners.length; i++) {
135 System.out.print(" " + listeners[i].getCount());
136 }
137 System.out.println();
138 iterations = 0;
139 }
140 }
141
142 for (int i = 0; i < 3; i++) {
143 proxies[i].stop();
144 for (int j = 0; j < N; j++)
145 proxies[i].removeObservedObject(mbeanNames[j]);
146 ObjectName[] observed = proxies[i].getObservedObjects();
147 if (observed.length != 0) {
148 System.out.println("TEST FAILED: not all observed objects " +
149 "removed: " + Arrays.asList(observed));
150 System.exit(1);
151 }
152 }
153
154 System.out.println("Test passed");
155 }
156
157 public static interface MonitoredMBean {
158 public int getCounterValue();
159 public double getGaugeValue();
160 public String getStringValue();
161 }
162
163 public static class Monitored implements MonitoredMBean {
164
165
166
167 private int okCounter = randomInt(5);
168 private int okGauge = randomInt(5);
169 private int okString = randomInt(5);
170
171 public synchronized int getCounterValue() {
172 if (--okCounter >= 0)
173 return 0;
174 else
175 return OVER_COUNTER_THRESHOLD;
176 }
177
178 public synchronized double getGaugeValue() {
179 if (--okGauge >= 0)
180 return 0.0;
181 else
182 return OVER_GAUGE_THRESHOLD;
183 }
184
185 public synchronized String getStringValue() {
186 if (--okString >= 0)
187 return STRING_TO_COMPARE;
188 else
189 return DIFFERENT_STRING;
190 }
191 }
192
193 public static class CountListener implements NotificationListener {
194 private int count;
195
196 public synchronized void handleNotification(Notification n, Object h) {
197 if (!(n instanceof MonitorNotification)) {
198 System.out.println("TEST FAILED: bad notif: " +
199 n.getClass().getName());
200 System.exit(1);
201 }
202 if (n.getType().indexOf("error") >= 0) {
203 System.out.println("TEST FAILED: error notif: " + n.getType());
204 System.exit(1);
205 }
206 count++;
207 }
208
209 public synchronized int getCount() {
210 return count;
211 }
212 }
213
214 private static boolean listenersAreAll(int n, CountListener[] listeners) {
215 for (int i = 0; i < listeners.length; i++) {
216 if (listeners[i].getCount() != n)
217 return false;
218 }
219 return true;
220 }
221
222 private static final Random random = new Random();
223 static synchronized int randomInt(int n) {
224 return random.nextInt(n);
225 }
226 }