001/*
002 * Copyright 2014-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2019 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
049 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
050 *   for proprietary functionality or for external specifications that are not
051 *   considered stable or mature enough to be guaranteed to work in an
052 *   interoperable way with 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<>();
109    final TreeMap<String,Long> totalCounts = new TreeMap<>();
110    final TreeMap<String,Long> failedCounts = new TreeMap<>();
111    final TreeMap<String,Double> failedPercents = new TreeMap<>();
112    final TreeMap<String,Map<Integer,ResultCodeInfo>> rcMaps = new TreeMap<>();
113    final Entry e = entry.getEntry();
114    for (final Attribute a : e.getAttributes())
115    {
116      try
117      {
118        final String lowerName = StaticUtils.toLowerCase(a.getName());
119        if (lowerName.startsWith("extended-op-") &&
120            lowerName.endsWith("-total-count"))
121        {
122          final String dashedOID =
123               lowerName.substring(12, (lowerName.length() - 12));
124          final String dottedOID = dashedOID.replace('-', '.');
125
126          final String name = entry.getString(
127               "extended-op-" + dashedOID + "-name");
128          final long total = a.getValueAsLong();
129          final long failed = entry.getLong(
130               "extended-op-" + dashedOID + "-failed-count");
131          final double failedPct = entry.getDouble(
132               "extended-op-" + dashedOID + "-failed-percent");
133
134          names.put(dottedOID, name);
135          totalCounts.put(dottedOID, total);
136          failedCounts.put(dottedOID, failed);
137          failedPercents.put(dottedOID, failedPct);
138          rcMaps.put(dottedOID,
139               getRCMap(e, "extended-op-" + dashedOID + "-result-"));
140        }
141      }
142      catch (final Exception ex)
143      {
144        Debug.debugException(ex);
145      }
146    }
147
148    requestNamesByOID = Collections.unmodifiableMap(names);
149    totalCountsByOID = Collections.unmodifiableMap(totalCounts);
150    failedCountsByOID = Collections.unmodifiableMap(failedCounts);
151    failedPercentsByOID = Collections.unmodifiableMap(failedPercents);
152    resultCodeInfoMap = Collections.unmodifiableMap(rcMaps);
153  }
154
155
156
157  /**
158   * Retrieves a map with result code information for a particular type of
159   * extended operation.
160   *
161   * @param  entry   The entry to be examined.
162   * @param  prefix  The prefix that will be used for all attributes of
163   *                 interest.
164   *
165   * @return  A map with result code information for a particular type of
166   *          extended operation.
167   */
168  private static Map<Integer,ResultCodeInfo> getRCMap(final Entry entry,
169                                                      final String prefix)
170  {
171    final TreeMap<Integer,ResultCodeInfo> m = new TreeMap<>();
172
173    for (final Attribute a : entry.getAttributes())
174    {
175      try
176      {
177        final String lowerName = StaticUtils.toLowerCase(a.getName());
178        if (lowerName.startsWith(prefix) && lowerName.endsWith("-name"))
179        {
180          final int intValue = Integer.parseInt(lowerName.substring(
181               prefix.length(), (lowerName.length() - 5)));
182          final String name = a.getValue();
183          final long count = entry.getAttributeValueAsLong(
184               prefix + intValue + "-count");
185          final double percent = Double.parseDouble(
186               entry.getAttributeValue(prefix + intValue + "-percent"));
187          final double totalResponseTimeMillis = Double.parseDouble(
188               entry.getAttributeValue(prefix + intValue +
189                    "-total-response-time-millis"));
190          final double averageResponseTimeMillis = Double.parseDouble(
191               entry.getAttributeValue(prefix + intValue +
192                    "-average-response-time-millis"));
193          m.put(intValue, new ResultCodeInfo(intValue, name,
194               OperationType.EXTENDED, count, percent, totalResponseTimeMillis,
195               averageResponseTimeMillis));
196        }
197      }
198      catch (final Exception ex)
199      {
200        Debug.debugException(ex);
201      }
202    }
203
204    return Collections.unmodifiableMap(m);
205  }
206
207
208
209  /**
210   * Retrieves the total number of extended operations of all types that have
211   * been processed, if available.
212   *
213   * @return  The total number of extended operations of all types that have
214   *          been processed, or {@code null} if this information was not in the
215   *          monitor entry.
216   */
217  public Long getTotalCount()
218  {
219    return totalCount;
220  }
221
222
223
224  /**
225   * Retrieves the number of extended operations of each type that have been
226   * processed, indexed by extended request OID, if available.
227   *
228   * @return  The number of extended operations of each type that have been
229   *          processed, or an empty map if this information was not in the
230   *          monitor entry.
231   */
232  public Map<String,Long> getTotalCountsByOID()
233  {
234    return totalCountsByOID;
235  }
236
237
238
239  /**
240   * Retrieves the number of extended operations of all types that resulted in
241   * failure, if available.
242   *
243   * @return  The number of extended operations of all types that resulted in
244   *          failure, or {@code null} if this information was not in the
245   *          monitor entry.
246   */
247  public Long getFailedCount()
248  {
249    return failedCount;
250  }
251
252
253
254  /**
255   * Retrieves the number of extended operations of each type that resulted in
256   * failure, indexed by extended request OID, if available.
257   *
258   * @return  The number of extended operations of each type that resulted in
259   *          failure, or an empty map if this information was not in the
260   *          monitor entry.
261   */
262  public Map<String,Long> getFailedCountsByOID()
263  {
264    return failedCountsByOID;
265  }
266
267
268
269  /**
270   * Retrieves the percent of extended operations of all types that resulted in
271   * failure, if available.
272   *
273   * @return  The percent of extended operations of all types that resulted in
274   *          failure, or {@code null} if this information was not in the
275   *          monitor entry.
276   */
277  public Double getFailedPercent()
278  {
279    return failedPercent;
280  }
281
282
283
284  /**
285   * Retrieves the percent of extended operations of each type that resulted in
286   * failure, indexed by extended request OID, if available.
287   *
288   * @return  The percent of extended operations of each type that resulted in
289   *          failure, or an empty map if this information was not in the
290   *          monitor entry.
291   */
292  public Map<String,Double> getFailedPercentsByOID()
293  {
294    return failedPercentsByOID;
295  }
296
297
298
299  /**
300   * Retrieves a map with information about the result codes that have been
301   * returned for extended operations of each type, indexed first by extended
302   * request OID, and then by the result code's integer value.
303   *
304   * @return  A map with information about the result codes that have been
305   *          returned for extended operations of each type, or an empty map if
306   *          this information was not in the monitor entry.
307   */
308  public Map<String,Map<Integer,ResultCodeInfo>> getResultCodeInfoMap()
309  {
310    return resultCodeInfoMap;
311  }
312
313
314
315  /**
316   * Retrieves a map with the human-readable names for each type of extended
317   * request, indexed by request OID, if available.
318   *
319   * @return  A map with the human-readable names for each type of extended
320   *          request, or an empty map if this information was not in the
321   *          monitor entry.
322   */
323  public Map<String,String> getExtendedRequestNamesByOID()
324  {
325    return requestNamesByOID;
326  }
327}