View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
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    // Job Table runTime, queueTime
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     * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getJobCount()
88     */
89    @Override
90    public int getJobCount() {
91      return countJobs(null, null);
92    }
93  
94    /**
95     * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getRunningJobCount()
96     */
97    @Override
98    public int getRunningJobCount() {
99      return countJobs(null, Status.RUNNING);
100   }
101 
102   /**
103    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getQueuedJobCount()
104    */
105   @Override
106   public int getQueuedJobCount() {
107     return countJobs(null, Status.QUEUED);
108   }
109 
110   /**
111    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getFinishedJobCount()
112    */
113   @Override
114   public int getFinishedJobCount() {
115     return countJobs(null, Status.FINISHED);
116   }
117 
118   /**
119    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getFailedJobCount()
120    */
121   @Override
122   public int getFailedJobCount() {
123     return countJobs(null, Status.FAILED);
124   }
125 
126   /**
127    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getJobCountByNode()
128    */
129   @Override
130   public int getJobCountByNode() {
131     return countJobs(hostName, null);
132   }
133 
134   /**
135    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getRunningJobCountByNode()
136    */
137   @Override
138   public int getRunningJobCountByNode() {
139     return countJobs(hostName, Status.RUNNING);
140   }
141 
142   /**
143    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getQueuedJobCountByNode()
144    */
145   @Override
146   public int getQueuedJobCountByNode() {
147     return countJobs(hostName, Status.QUEUED);
148   }
149 
150   /**
151    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getFinishedJobCountByNode()
152    */
153   @Override
154   public int getFinishedJobCountByNode() {
155     return countJobs(hostName, Status.FINISHED);
156   }
157 
158   /**
159    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getFailedJobCountByNode()
160    */
161   @Override
162   public int getFailedJobCountByNode() {
163     return countJobs(hostName, Status.FAILED);
164   }
165 
166   /**
167    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getAverageJobRunTime()
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    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getAverageJobQueueTime()
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    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getJobs()
192    */
193   @Override
194   public String[] getJobs() {
195     return toJobCountArray(null, null);
196   }
197 
198   /**
199    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getRunningJobs()
200    */
201   @Override
202   public String[] getRunningJobs() {
203     return toJobCountArray(null, Status.RUNNING);
204   }
205 
206   /**
207    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getQueuedJobs()
208    */
209   @Override
210   public String[] getQueuedJobs() {
211     return toJobCountArray(null, Status.QUEUED);
212   }
213 
214   /**
215    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getFinishedJobs()
216    */
217   @Override
218   public String[] getFinishedJobs() {
219     return toJobCountArray(null, Status.FINISHED);
220   }
221 
222   /**
223    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getFailedJobs()
224    */
225   @Override
226   public String[] getFailedJobs() {
227     return toJobCountArray(null, Status.FAILED);
228   }
229 
230   /**
231    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getJobsByNode()
232    */
233   @Override
234   public String[] getJobsByNode() {
235     return toJobCountArray(hostName, null);
236   }
237 
238   /**
239    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getRunningJobsByNode()
240    */
241   @Override
242   public String[] getRunningJobsByNode() {
243     return toJobCountArray(hostName, Status.RUNNING);
244   }
245 
246   /**
247    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getQueuedJobsByNode()
248    */
249   @Override
250   public String[] getQueuedJobsByNode() {
251     return toJobCountArray(hostName, Status.QUEUED);
252   }
253 
254   /**
255    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getFinishedJobsByNode()
256    */
257   @Override
258   public String[] getFinishedJobsByNode() {
259     return toJobCountArray(hostName, Status.FINISHED);
260   }
261 
262   /**
263    * @see org.opencastproject.serviceregistry.impl.jmx.JobsStatisticsMXBean#getFailedJobsByNode()
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 }