001/*
002 * Copyright 2011-2013 UnboundID Corp.
003 *
004 * This program is free software; you can redistribute it and/or modify
005 * it under the terms of the GNU General Public License (GPLv2 only)
006 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
007 * as published by the Free Software Foundation.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU General Public License for more details.
013 *
014 * You should have received a copy of the GNU General Public License
015 * along with this program; if not, see <http://www.gnu.org/licenses>.
016 */
017
018package com.unboundid.scim.wink;
019
020import java.util.HashMap;
021import java.util.Map;
022import java.util.concurrent.ConcurrentHashMap;
023import java.util.concurrent.atomic.AtomicLong;
024
025/**
026 * This class holds various statistics of each SCIM resource being served.
027 */
028public class ResourceStats
029{
030  /**
031   * Number of query requests that were successful.
032   */
033  public static final String QUERY_OK = "query-successful";
034
035  /**
036   * Number of query requests that failed with code 400 Bad Request.
037   */
038  public static final String QUERY_BAD_REQUEST = "query-400";
039
040  /**
041   * Number of query requests that failed with code 401 Unauthorized.
042   */
043  public static final String QUERY_UNAUTHORIZED = "query-401";
044
045  /**
046   * Number of query requests that failed with code 403 Forbidden.
047   */
048  public static final String QUERY_FORBIDDEN = "query-403";
049
050  /**
051   * Number of query requests that failed with code 404 Not Found.
052   */
053  public static final String QUERY_NOT_FOUND = "query-404";
054
055  /**
056   * Number of query requests that failed with code 500 Internal Server Error.
057   */
058  public static final String QUERY_INTERNAL_SERVER_ERROR = "query-500";
059
060  /**
061   * Number of query requests that failed with code 505 Not Implemented.
062   */
063  public static final String QUERY_NOT_IMPLEMENTED = "query-505";
064
065  /**
066   * Number of query requests that responded in XML format.
067   */
068  public static final String QUERY_RESPONSE_XML = "query-response-xml";
069
070  /**
071   * Number of query requests that responded in JSON format.
072   */
073  public static final String QUERY_RESPONSE_JSON = "query-response-json";
074
075
076  /**
077   * Number of get requests that were successful.
078   */
079  public static final String GET_OK = "get-successful";
080
081  /**
082   * Number of get requests that failed with code 400 Bad Request.
083   */
084  public static final String GET_BAD_REQUEST = "get-400"
085
086  /**
087   * Number of get requests that failed with code 401 Unauthorized.
088   */;
089  public static final String GET_UNAUTHORIZED = "get-401";
090
091  /**
092   * Number of get requests that failed with code 403 Forbidden.
093   */
094  public static final String GET_FORBIDDEN = "get-403";
095
096  /**
097   * Number of get requests that failed with code 404 Not Found.
098   */
099  public static final String GET_NOT_FOUND = "get-404";
100
101  /**
102   * Number of get requests that failed with code 500 Internal Server Error.
103   */
104  public static final String GET_INTERNAL_SERVER_ERROR = "get-500";
105
106  /**
107   * Number of get requests that failed with code 505 Not Implemented.
108   */
109  public static final String GET_NOT_IMPLEMENTED = "get-505";
110
111  /**
112   * Number of get requests that responded in XML format.
113   */
114  public static final String GET_RESPONSE_XML = "get-response-xml";
115
116  /**
117   * Number of get requests that responded in JSON format.
118   */
119  public static final String GET_RESPONSE_JSON = "get-response-json";
120
121  /**
122   * Number of put requests that were successful.
123   */
124  public static final String PUT_OK = "put-successful";
125
126  /**
127   * Number of put requests that failed with code 400 Bad Request.
128   */
129  public static final String PUT_BAD_REQUEST = "put-400";
130
131  /**
132   * Number of put requests that failed with code 401 Unauthorized.
133   */
134  public static final String PUT_UNAUTHORIZED = "put-401";
135
136  /**
137   * Number of put requests that failed with code 403 Forbidden.
138   */
139  public static final String PUT_FORBIDDEN = "put-403";
140
141  /**
142   * Number of put requests that failed with code 404 Not Found.
143   */
144  public static final String PUT_NOT_FOUND = "put-404";
145
146  /**
147   * Number of put requests that failed with code 409 Conflict.
148   */
149  public static final String PUT_CONFLICT = "put-409";
150
151  /**
152   * Number of put requests that failed with code 412 Precondition Failed.
153   */
154  public static final String PUT_PRECONDITION_FAILED = "put-412";
155
156  /**
157   * Number of put requests that failed with code 500 Internal Server Error.
158   */
159  public static final String PUT_INTERNAL_SERVER_ERROR = "put-500";
160
161  /**
162   * Number of put requests that failed with code 505 Not Implemented.
163   */
164  public static final String PUT_NOT_IMPLEMENTED = "put-505";
165
166  /**
167   * Number of put requests that responded in XML format.
168   */
169  public static final String PUT_RESPONSE_XML = "put-response-xml";
170
171  /**
172   * Number of put requests that responded in JSON format.
173   */
174  public static final String PUT_RESPONSE_JSON = "put-response-json";
175
176  /**
177   * Number of put requests with content in XML format.
178   */
179  public static final String PUT_CONTENT_XML = "put-content-xml";
180
181  /**
182   * Number of put requests with content in JSON format.
183   */
184  public static final String PUT_CONTENT_JSON = "put-content-json";
185
186
187  /**
188   * Number of post requests that were successful.
189   */
190  public static final String POST_OK = "post-successful";
191
192  /**
193   * Number of post requests that failed with code 400 Bad Request.
194   */
195  public static final String POST_BAD_REQUEST = "post-400";
196
197  /**
198   * Number of post requests that failed with code 401 Unauthorized.
199   */
200  public static final String POST_UNAUTHORIZED = "post-401";
201
202  /**
203   * Number of post requests that failed with code 403 Forbidden.
204   */
205  public static final String POST_FORBIDDEN = "post-403";
206
207  /**
208   * Number of post requests that failed with code 409 Conflict.
209   */
210  public static final String POST_CONFLICT = "post-409";
211
212  /**
213   * Number of post requests that failed with code 413 Entity Too Large.
214   */
215  public static final String POST_REQUEST_ENTITY_TOO_LARGE = "post-413";
216
217  /**
218   * Number of post requests that failed with code 500 Internal Server Error.
219   */
220  public static final String POST_INTERNAL_SERVER_ERROR = "post-500";
221
222  /**
223   * Number of post requests that failed with code 505 Not Implemented.
224   */
225  public static final String POST_NOT_IMPLEMENTED = "post-505";
226
227  /**
228   * Number of post requests that responded in XML format.
229   */
230  public static final String POST_RESPONSE_XML = "post-response-xml";
231
232  /**
233   * Number of post requests that responded in JSON format.
234   */
235  public static final String POST_RESPONSE_JSON = "post-response-json";
236
237  /**
238   * Number of post requests with content in XML format.
239   */
240  public static final String POST_CONTENT_XML = "post-content-xml";
241
242  /**
243   * Number of post requests with content in JSON format.
244   */
245  public static final String POST_CONTENT_JSON = "post-content-json";
246
247
248  /**
249   * Number of patch requests that were successful.
250   */
251  public static final String PATCH_OK = "patch-successful";
252
253  /**
254   * Number of patch requests that failed with code 400 Bad Request.
255   */
256  public static final String PATCH_BAD_REQUEST = "patch-400";
257
258  /**
259   * Number of patch requests that failed with code 401 Unauthorized.
260   */
261  public static final String PATCH_UNAUTHORIZED = "patch-401";
262
263  /**
264   * Number of patch requests that failed with code 403 Forbidden.
265   */
266  public static final String PATCH_FORBIDDEN = "patch-403";
267
268  /**
269   * Number of patch requests that failed with code 404 Not Found.
270   */
271  public static final String PATCH_NOT_FOUND = "patch-404";
272
273  /**
274   * Number of patch requests that failed with code 409 Conflict.
275   */
276  public static final String PATCH_CONFLICT = "patch-409";
277
278  /**
279   * Number of patch requests that failed with code 412 Precondition Failed.
280   */
281  public static final String PATCH_PRECONDITION_FAILED = "patch-412";
282
283  /**
284   * Number of patch requests that failed with code 500 Internal Server Error.
285   */
286  public static final String PATCH_INTERNAL_SERVER_ERROR = "patch-500";
287
288  /**
289   * Number of patch requests that failed with code 505 Not Implemented.
290   */
291  public static final String PATCH_NOT_IMPLEMENTED = "patch-505";
292
293  /**
294   * Number of patch requests that responded in XML format.
295   */
296  public static final String PATCH_RESPONSE_XML = "patch-response-xml";
297
298  /**
299   * Number of patch requests that responded in JSON format.
300   */
301  public static final String PATCH_RESPONSE_JSON = "patch-response-json";
302
303  /**
304   * Number of patch requests with content in XML format.
305   */
306  public static final String PATCH_CONTENT_XML = "patch-content-xml";
307
308  /**
309   * Number of patch requests with content in JSON format.
310   */
311  public static final String PATCH_CONTENT_JSON = "patch-content-json";
312
313
314  /**
315   * Number of delete requests that were successful.
316   */
317  public static final String DELETE_OK = "delete-successful";
318
319  /**
320   * Number of delete requests that failed with code 400 Bad Request.
321   */
322  public static final String DELETE_BAD_REQUEST = "delete-400";
323
324  /**
325   * Number of delete requests that failed with code 401 Unauthorized.
326   */
327  public static final String DELETE_UNAUTHORIZED = "delete-401";
328
329  /**
330   * Number of delete requests that failed with code 403 Forbidden.
331   */
332  public static final String DELETE_FORBIDDEN = "delete-403";
333
334  /**
335   * Number of delete requests that failed with code 404 Not Found.
336   */
337  public static final String DELETE_NOT_FOUND = "delete-404";
338
339  /**
340   * Number of delete requests that failed with code 409 Conflict.
341   */
342  public static final String DELETE_CONFLICT = "delete-409";
343
344  /**
345   * Number of delete requests that failed with code 500 Internal Server Error.
346   */
347  public static final String DELETE_INTERNAL_SERVER_ERROR = "delete-500";
348
349  /**
350   * Number of delete requests that failed with code 505 Not Implemented.
351   */
352  public static final String DELETE_NOT_IMPLEMENTED = "delete-505";
353
354  private final String name;
355  private final ConcurrentHashMap<String, AtomicLong> stats =
356      new ConcurrentHashMap<String, AtomicLong>();
357
358  /**
359   * Create a new ResourceStats instance with the provided name.
360   *
361   * @param name The name of this ResourceStats instance, usually it should
362   *             be the name of the SCIM resource being served.
363   */
364  public ResourceStats(final String name) {
365    this.name = name;
366  }
367
368  /**
369   * Increments a single statistical value.
370   *
371   * @param stat The name of the statistical value to increment.
372   */
373  void incrementStat(final String stat)
374  {
375    AtomicLong num = stats.get(stat);
376    if(num == null)
377    {
378      num = new AtomicLong();
379      AtomicLong prev = stats.putIfAbsent(stat, num);
380      if(prev != null)
381      {
382        num = prev;
383      }
384    }
385    num.getAndIncrement();
386  }
387
388  /**
389   * Retrieves a single statistical value.
390   *
391   * @param stat The name of the statistical value to retrieve.
392   * @return The statistical value or 0 if it is not present.
393   */
394  public long getStat(final String stat)
395  {
396    AtomicLong i = stats.get(stat);
397    if(i != null)
398    {
399      return i.get();
400    }
401    return 0;
402  }
403
404  /**
405   * Retrieves all statistical values that are present.
406   *
407   * @return All statistical values that are present.
408   */
409  public Map<String, Long> getStats()
410  {
411    Map<String, Long> map = new HashMap<String, Long>(stats.size());
412    for(Map.Entry<String, AtomicLong> entry : stats.entrySet())
413    {
414      map.put(entry.getKey(), entry.getValue().get());
415    }
416    return map;
417  }
418
419  /**
420   * Retrieves the name of this ResourceStats instance, usually the name of
421   * the SCIM resource being served.
422   *
423   * @return The name of this ResourceStats instance, usually the name of
424   * the SCIM resource being served.
425   */
426  public String getName() {
427    return name;
428  }
429}