1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.serviceregistry.impl.jmx;
23
24 import org.opencastproject.job.api.Job.Status;
25 import org.opencastproject.util.data.Tuple3;
26 import org.opencastproject.util.jmx.JmxUtil;
27
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33
34 import javax.management.MBeanNotificationInfo;
35 import javax.management.Notification;
36 import javax.management.NotificationBroadcasterSupport;
37
38 public class JobsStatistics extends NotificationBroadcasterSupport implements JobsStatisticsMXBean {
39
40 private static final String DELIMITER = ";";
41
42 private Map<Tuple3<String, String, Status>, Long> jobCounts = new HashMap<Tuple3<String, String, Status>, Long>();
43 private Map<String, Long> avgRunTimes = new HashMap<String, Long>();
44 private Map<String, Long> avgQueueTimes = new HashMap<String, Long>();
45
46
47 private long sequenceNumber = 1;
48 private final String hostName;
49
50 public JobsStatistics(String hostName) {
51 this.hostName = hostName;
52 }
53
54 public void updateJobCount(List<Object[]> perHostServiceCount) {
55 jobCounts.clear();
56 for (Object[] result : perHostServiceCount) {
57 Status status = Status.values()[((Number) result[2]).intValue()];
58 jobCounts.put(Tuple3.tuple3((String) result[0], (String) result[1], status), (Long) result[3]);
59 }
60 sendNotification(JmxUtil.createUpdateNotification(this, sequenceNumber++, "Job updated"));
61 }
62
63 public void updateAvg(List<Object[]> avgOperations) {
64 avgRunTimes.clear();
65 avgQueueTimes.clear();
66 for (Object[] result : avgOperations) {
67 Long avgRunTime = ((Double) result[1]).longValue();
68 Long avgQueueTime = ((Double) result[2]).longValue();
69
70 avgRunTimes.put((String) result[0], avgRunTime);
71 avgQueueTimes.put((String) result[0], avgQueueTime);
72 }
73 sendNotification(JmxUtil.createUpdateNotification(this, sequenceNumber++, "Job updated"));
74 }
75
76 @Override
77 public MBeanNotificationInfo[] getNotificationInfo() {
78 String[] types = new String[] { JmxUtil.OPENCAST_UPDATE_NOTIFICATION };
79
80 String name = Notification.class.getName();
81 String description = "An update was executed";
82 MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description);
83 return new MBeanNotificationInfo[] { info };
84 }
85
86
87
88
89 @Override
90 public int getJobCount() {
91 return countJobs(null, null);
92 }
93
94
95
96
97 @Override
98 public int getRunningJobCount() {
99 return countJobs(null, Status.RUNNING);
100 }
101
102
103
104
105 @Override
106 public int getQueuedJobCount() {
107 return countJobs(null, Status.QUEUED);
108 }
109
110
111
112
113 @Override
114 public int getFinishedJobCount() {
115 return countJobs(null, Status.FINISHED);
116 }
117
118
119
120
121 @Override
122 public int getFailedJobCount() {
123 return countJobs(null, Status.FAILED);
124 }
125
126
127
128
129 @Override
130 public int getJobCountByNode() {
131 return countJobs(hostName, null);
132 }
133
134
135
136
137 @Override
138 public int getRunningJobCountByNode() {
139 return countJobs(hostName, Status.RUNNING);
140 }
141
142
143
144
145 @Override
146 public int getQueuedJobCountByNode() {
147 return countJobs(hostName, Status.QUEUED);
148 }
149
150
151
152
153 @Override
154 public int getFinishedJobCountByNode() {
155 return countJobs(hostName, Status.FINISHED);
156 }
157
158
159
160
161 @Override
162 public int getFailedJobCountByNode() {
163 return countJobs(hostName, Status.FAILED);
164 }
165
166
167
168
169 @Override
170 public String[] getAverageJobRunTime() {
171 List<String> avgJobList = new ArrayList<String>();
172 for (Entry<String, Long> entry : avgRunTimes.entrySet()) {
173 avgJobList.add(entry.getKey() + DELIMITER + entry.getValue());
174 }
175 return avgJobList.toArray(new String[avgJobList.size()]);
176 }
177
178
179
180
181 @Override
182 public String[] getAverageJobQueueTime() {
183 List<String> avgJobList = new ArrayList<String>();
184 for (Entry<String, Long> entry : avgQueueTimes.entrySet()) {
185 avgJobList.add(entry.getKey() + DELIMITER + entry.getValue());
186 }
187 return avgJobList.toArray(new String[avgJobList.size()]);
188 }
189
190
191
192
193 @Override
194 public String[] getJobs() {
195 return toJobCountArray(null, null);
196 }
197
198
199
200
201 @Override
202 public String[] getRunningJobs() {
203 return toJobCountArray(null, Status.RUNNING);
204 }
205
206
207
208
209 @Override
210 public String[] getQueuedJobs() {
211 return toJobCountArray(null, Status.QUEUED);
212 }
213
214
215
216
217 @Override
218 public String[] getFinishedJobs() {
219 return toJobCountArray(null, Status.FINISHED);
220 }
221
222
223
224
225 @Override
226 public String[] getFailedJobs() {
227 return toJobCountArray(null, Status.FAILED);
228 }
229
230
231
232
233 @Override
234 public String[] getJobsByNode() {
235 return toJobCountArray(hostName, null);
236 }
237
238
239
240
241 @Override
242 public String[] getRunningJobsByNode() {
243 return toJobCountArray(hostName, Status.RUNNING);
244 }
245
246
247
248
249 @Override
250 public String[] getQueuedJobsByNode() {
251 return toJobCountArray(hostName, Status.QUEUED);
252 }
253
254
255
256
257 @Override
258 public String[] getFinishedJobsByNode() {
259 return toJobCountArray(hostName, Status.FINISHED);
260 }
261
262
263
264
265 @Override
266 public String[] getFailedJobsByNode() {
267 return toJobCountArray(hostName, Status.FAILED);
268 }
269
270 private int countJobs(String hostName, Status status) {
271 int i = 0;
272 for (Entry<Tuple3<String, String, Status>, Long> entry : jobCounts.entrySet()) {
273 if (hostName != null && !hostName.equals(entry.getKey().getA()))
274 continue;
275 if (status != null && !status.equals(entry.getKey().getC()))
276 continue;
277 i += entry.getValue();
278 }
279 return i;
280 }
281
282 private String[] toJobCountArray(String hostName, Status status) {
283 List<String> list = new ArrayList<String>();
284 for (Entry<Tuple3<String, String, Status>, Long> entry : jobCounts.entrySet()) {
285 if (hostName != null && !hostName.equals(entry.getKey().getA()))
286 continue;
287 if (status != null && !status.equals(entry.getKey().getC()))
288 continue;
289 list.add(entry.getKey().getA() + DELIMITER + entry.getKey().getB() + DELIMITER + entry.getValue());
290 }
291 return list.toArray(new String[list.size()]);
292 }
293
294 }