001    /*
002     * Copyright 2014-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2015 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.ldap.sdk.unboundidds.monitors;
022    
023    
024    
025    import java.io.Serializable;
026    import java.util.Collections;
027    import java.util.Map;
028    import java.util.TreeMap;
029    
030    import com.unboundid.ldap.sdk.Attribute;
031    import com.unboundid.ldap.sdk.Entry;
032    import com.unboundid.ldap.sdk.OperationType;
033    import com.unboundid.util.Debug;
034    import com.unboundid.util.NotMutable;
035    import com.unboundid.util.StaticUtils;
036    import com.unboundid.util.ThreadSafety;
037    import com.unboundid.util.ThreadSafetyLevel;
038    
039    
040    
041    /**
042     * <BLOCKQUOTE>
043     *   <B>NOTE:</B>  This class is part of the Commercial Edition of the UnboundID
044     *   LDAP SDK for Java.  It is not available for use in applications that
045     *   include only the Standard Edition of the LDAP SDK, and is not supported for
046     *   use in conjunction with non-UnboundID products.
047     * </BLOCKQUOTE>
048     * This class provides a data structure that provides information about the
049     * result codes associated with various types of extended operations.
050     */
051    @NotMutable()
052    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
053    public final class ExtendedOperationResultCodeInfo
054           implements Serializable
055    {
056      /**
057       * The serial version UID for this serializable class.
058       */
059      private static final long serialVersionUID = 2412562905271298484L;
060    
061    
062    
063      // The percentage of all extended operations that failed.
064      private final Double failedPercent;
065    
066      // The total number of operations of the associated type that failed.
067      private final Long failedCount;
068    
069      // The total number of operations of the associated type.
070      private final Long totalCount;
071    
072      // The percentage of extended operations that failed, indexed by OID.
073      private final Map<String,Double> failedPercentsByOID;
074    
075      // The number of extended operations that failed, indexed by OID.
076      private final Map<String,Long> failedCountsByOID;
077    
078      // The number of extended operations processed, indexed by OID.
079      private final Map<String,Long> totalCountsByOID;
080    
081      // Information about each result code returned for each type of extended
082      // operation, indexed first by extended request OID, then by the result code's
083      // integer value.
084      private final Map<String,Map<Integer,ResultCodeInfo>> resultCodeInfoMap;
085    
086      // The names of the types of extended operations processed, indexed by OID.
087      private final Map<String,String> requestNamesByOID;
088    
089    
090    
091      /**
092       * Creates a new extended operation result code information object from the
093       * provided information.
094       *
095       * @param  entry  The monitor entry to use to obtain the result code
096       *                information.
097       */
098      ExtendedOperationResultCodeInfo(final MonitorEntry entry)
099      {
100        totalCount = entry.getLong("extended-op-total-count");
101        failedCount = entry.getLong("extended-op-failed-count");
102        failedPercent = entry.getDouble("extended-op-failed-percent");
103    
104        final TreeMap<String,String> names = new TreeMap<String,String>();
105        final TreeMap<String,Long> totalCounts = new TreeMap<String,Long>();
106        final TreeMap<String,Long> failedCounts = new TreeMap<String,Long>();
107        final TreeMap<String,Double> failedPercents = new TreeMap<String,Double>();
108        final TreeMap<String,Map<Integer,ResultCodeInfo>> rcMaps =
109             new TreeMap<String,Map<Integer,ResultCodeInfo>>();
110        final Entry e = entry.getEntry();
111        for (final Attribute a : e.getAttributes())
112        {
113          try
114          {
115            final String lowerName = StaticUtils.toLowerCase(a.getName());
116            if (lowerName.startsWith("extended-op-") &&
117                lowerName.endsWith("-total-count"))
118            {
119              final String dashedOID =
120                   lowerName.substring(12, (lowerName.length() - 12));
121              final String dottedOID = dashedOID.replace('-', '.');
122    
123              final String name = entry.getString(
124                   "extended-op-" + dashedOID + "-name");
125              final long total = a.getValueAsLong();
126              final long failed = entry.getLong(
127                   "extended-op-" + dashedOID + "-failed-count");
128              final double failedPct = entry.getDouble(
129                   "extended-op-" + dashedOID + "-failed-percent");
130    
131              names.put(dottedOID, name);
132              totalCounts.put(dottedOID, total);
133              failedCounts.put(dottedOID, failed);
134              failedPercents.put(dottedOID, failedPct);
135              rcMaps.put(dottedOID,
136                   getRCMap(e, "extended-op-" + dashedOID + "-result-"));
137            }
138          }
139          catch (final Exception ex)
140          {
141            Debug.debugException(ex);
142          }
143        }
144    
145        requestNamesByOID = Collections.unmodifiableMap(names);
146        totalCountsByOID = Collections.unmodifiableMap(totalCounts);
147        failedCountsByOID = Collections.unmodifiableMap(failedCounts);
148        failedPercentsByOID = Collections.unmodifiableMap(failedPercents);
149        resultCodeInfoMap = Collections.unmodifiableMap(rcMaps);
150      }
151    
152    
153    
154      /**
155       * Retrieves a map with result code information for a particular type of
156       * extended operation.
157       *
158       * @param  entry   The entry to be examined.
159       * @param  prefix  The prefix that will be used for all attributes of
160       *                 interest.
161       *
162       * @return  A map with result code information for a particular type of
163       *          extended operation.
164       */
165      private static Map<Integer,ResultCodeInfo> getRCMap(final Entry entry,
166                                                          final String prefix)
167      {
168        final TreeMap<Integer,ResultCodeInfo> m =
169             new TreeMap<Integer,ResultCodeInfo>();
170    
171        for (final Attribute a : entry.getAttributes())
172        {
173          try
174          {
175            final String lowerName = StaticUtils.toLowerCase(a.getName());
176            if (lowerName.startsWith(prefix) && lowerName.endsWith("-name"))
177            {
178              final int intValue = Integer.parseInt(lowerName.substring(
179                   prefix.length(), (lowerName.length() - 5)));
180              final String name = a.getValue();
181              final long count = entry.getAttributeValueAsLong(
182                   prefix + intValue + "-count");
183              final double percent = Double.parseDouble(
184                   entry.getAttributeValue(prefix + intValue + "-percent"));
185              final double totalResponseTimeMillis = Double.parseDouble(
186                   entry.getAttributeValue(prefix + intValue +
187                        "-total-response-time-millis"));
188              final double averageResponseTimeMillis = Double.parseDouble(
189                   entry.getAttributeValue(prefix + intValue +
190                        "-average-response-time-millis"));
191              m.put(intValue, new ResultCodeInfo(intValue, name,
192                   OperationType.EXTENDED, count, percent, totalResponseTimeMillis,
193                   averageResponseTimeMillis));
194            }
195          }
196          catch (final Exception ex)
197          {
198            Debug.debugException(ex);
199          }
200        }
201    
202        return Collections.unmodifiableMap(m);
203      }
204    
205    
206    
207      /**
208       * Retrieves the total number of extended operations of all types that have
209       * been processed, if available.
210       *
211       * @return  The total number of extended operations of all types that have
212       *          been processed, or {@code null} if this information was not in the
213       *          monitor entry.
214       */
215      public Long getTotalCount()
216      {
217        return totalCount;
218      }
219    
220    
221    
222      /**
223       * Retrieves the number of extended operations of each type that have been
224       * processed, indexed by extended request OID, if available.
225       *
226       * @return  The number of extended operations of each type that have been
227       *          processed, or an empty map if this information was not in the
228       *          monitor entry.
229       */
230      public Map<String,Long> getTotalCountsByOID()
231      {
232        return totalCountsByOID;
233      }
234    
235    
236    
237      /**
238       * Retrieves the number of extended operations of all types that resulted in
239       * failure, if available.
240       *
241       * @return  The number of extended operations of all types that resulted in
242       *          failure, or {@code null} if this information was not in the
243       *          monitor entry.
244       */
245      public Long getFailedCount()
246      {
247        return failedCount;
248      }
249    
250    
251    
252      /**
253       * Retrieves the number of extended operations of each type that resulted in
254       * failure, indexed by extended request OID, if available.
255       *
256       * @return  The number of extended operations of each type that resulted in
257       *          failure, or an empty map if this information was not in the
258       *          monitor entry.
259       */
260      public Map<String,Long> getFailedCountsByOID()
261      {
262        return failedCountsByOID;
263      }
264    
265    
266    
267      /**
268       * Retrieves the percent of extended operations of all types that resulted in
269       * failure, if available.
270       *
271       * @return  The percent of extended operations of all types that resulted in
272       *          failure, or {@code null} if this information was not in the
273       *          monitor entry.
274       */
275      public Double getFailedPercent()
276      {
277        return failedPercent;
278      }
279    
280    
281    
282      /**
283       * Retrieves the percent of extended operations of each type that resulted in
284       * failure, indexed by extended request OID, if available.
285       *
286       * @return  The percent of extended operations of each type that resulted in
287       *          failure, or an empty map if this information was not in the
288       *          monitor entry.
289       */
290      public Map<String,Double> getFailedPercentsByOID()
291      {
292        return failedPercentsByOID;
293      }
294    
295    
296    
297      /**
298       * Retrieves a map with information about the result codes that have been
299       * returned for extended operations of each type, indexed first by extended
300       * request OID, and then by the result code's integer value.
301       *
302       * @return  A map with information about the result codes that have been
303       *          returned for extended operations of each type, or an empty map if
304       *          this information was not in the monitor entry.
305       */
306      public Map<String,Map<Integer,ResultCodeInfo>> getResultCodeInfoMap()
307      {
308        return resultCodeInfoMap;
309      }
310    
311    
312    
313      /**
314       * Retrieves a map with the human-readable names for each type of extended
315       * request, indexed by request OID, if available.
316       *
317       * @return  A map with the human-readable names for each type of extended
318       *          request, or an empty map if this information was not in the
319       *          monitor entry.
320       */
321      public Map<String,String> getExtendedRequestNamesByOID()
322      {
323        return requestNamesByOID;
324      }
325    }