001    /*
002     * Copyright 2011-2012 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    
018    package com.unboundid.scim.wink;
019    
020    import java.util.HashMap;
021    import java.util.Map;
022    import java.util.concurrent.ConcurrentHashMap;
023    import java.util.concurrent.atomic.AtomicLong;
024    
025    /**
026     * This class holds various statistics of each SCIM resource being served.
027     */
028    public 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_ACCEPT_XML = "patch-accept-xml";
297    
298      /**
299       * Number of patch requests that responded in JSON format.
300       */
301      public static final String PATCH_ACCEPT_JSON = "patch-accept-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    }