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