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.util.Collections;
026import java.util.LinkedHashMap;
027import java.util.Map;
028
029import com.unboundid.ldap.sdk.Entry;
030import com.unboundid.ldap.sdk.OperationType;
031import com.unboundid.util.NotMutable;
032import com.unboundid.util.StaticUtils;
033import com.unboundid.util.ThreadSafety;
034import com.unboundid.util.ThreadSafetyLevel;
035
036import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
037
038
039
040/**
041 * This class defines a monitor entry that provides information about the result
042 * codes returned from various types of operations.
043 * <BR>
044 * <BLOCKQUOTE>
045 *   <B>NOTE:</B>  This class, and other classes within the
046 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
047 *   supported for use against Ping Identity, UnboundID, and
048 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
049 *   for proprietary functionality or for external specifications that are not
050 *   considered stable or mature enough to be guaranteed to work in an
051 *   interoperable way with other types of LDAP servers.
052 * </BLOCKQUOTE>
053 */
054@NotMutable()
055@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
056public final class ResultCodeMonitorEntry
057       extends MonitorEntry
058{
059  /**
060   * The structural object class used in group cache monitor entries.
061   */
062  static final String RESULT_CODE_MONITOR_OC =
063       "ds-ldap-result-codes-monitor-entry";
064
065
066
067  /**
068   * The serial version UID for this serializable class.
069   */
070  private static final long serialVersionUID = -963682306039266913L;
071
072
073
074  // The result code information for extended operations.
075  private final ExtendedOperationResultCodeInfo extendedOperationResultCodeInfo;
076
077  // The result code information for add operations.
078  private final OperationResultCodeInfo addOperationResultCodeInfo;
079
080  // The result code information for all types of operations.
081  private final OperationResultCodeInfo allOperationsResultCodeInfo;
082
083  // The result code information for bind operations.
084  private final OperationResultCodeInfo bindOperationResultCodeInfo;
085
086  // The result code information for compare operations.
087  private final OperationResultCodeInfo compareOperationResultCodeInfo;
088
089  // The result code information for delete operations.
090  private final OperationResultCodeInfo deleteOperationResultCodeInfo;
091
092  // The result code information for modify operations.
093  private final OperationResultCodeInfo modifyOperationResultCodeInfo;
094
095  // The result code information for modify DN operations.
096  private final OperationResultCodeInfo modifyDNOperationResultCodeInfo;
097
098  // The result code information for search operations.
099  private final OperationResultCodeInfo searchOperationResultCodeInfo;
100
101
102
103  /**
104   * Creates a new result code monitor entry from the provided entry.
105   *
106   * @param  entry  The entry to be parsed as a result code monitor entry.  It
107   *                must not be {@code null}.
108   */
109  public ResultCodeMonitorEntry(final Entry entry)
110  {
111    super(entry);
112
113    allOperationsResultCodeInfo =
114         new OperationResultCodeInfo(this, null, "all-ops-");
115    addOperationResultCodeInfo =
116         new OperationResultCodeInfo(this, OperationType.ADD, "add-op-");
117    bindOperationResultCodeInfo =
118         new OperationResultCodeInfo(this, OperationType.BIND, "bind-op-");
119    compareOperationResultCodeInfo =
120         new OperationResultCodeInfo(this, OperationType.COMPARE,
121              "compare-op-");
122    deleteOperationResultCodeInfo =
123         new OperationResultCodeInfo(this, OperationType.DELETE, "delete-op-");
124    extendedOperationResultCodeInfo = new ExtendedOperationResultCodeInfo(this);
125    modifyOperationResultCodeInfo =
126         new OperationResultCodeInfo(this, OperationType.MODIFY, "modify-op-");
127    modifyDNOperationResultCodeInfo =
128         new OperationResultCodeInfo(this, OperationType.MODIFY_DN,
129              "modifydn-op-");
130    searchOperationResultCodeInfo =
131         new OperationResultCodeInfo(this, OperationType.SEARCH, "search-op-");
132  }
133
134
135
136  /**
137   * Retrieves result code information that encompasses all types of operations.
138   *
139   * @return  Result code information that encompasses all types of operations.
140   */
141  public OperationResultCodeInfo getAllOperationsResultCodeInfo()
142  {
143    return allOperationsResultCodeInfo;
144  }
145
146
147
148  /**
149   * Retrieves result code information for add operations.
150   *
151   * @return  Result code information for add operations.
152   */
153  public OperationResultCodeInfo getAddOperationResultCodeInfo()
154  {
155    return addOperationResultCodeInfo;
156  }
157
158
159
160  /**
161   * Retrieves result code information for bind operations.
162   *
163   * @return  Result code information for bind operations.
164   */
165  public OperationResultCodeInfo getBindOperationResultCodeInfo()
166  {
167    return bindOperationResultCodeInfo;
168  }
169
170
171
172  /**
173   * Retrieves result code information for compare operations.
174   *
175   * @return  Result code information for compare operations.
176   */
177  public OperationResultCodeInfo getCompareOperationResultCodeInfo()
178  {
179    return compareOperationResultCodeInfo;
180  }
181
182
183
184  /**
185   * Retrieves result code information for delete operations.
186   *
187   * @return  Result code information for delete operations.
188   */
189  public OperationResultCodeInfo getDeleteOperationResultCodeInfo()
190  {
191    return deleteOperationResultCodeInfo;
192  }
193
194
195
196  /**
197   * Retrieves result code information for extended operations.
198   *
199   * @return  Result code information for extended operations.
200   */
201  public ExtendedOperationResultCodeInfo getExtendedOperationResultCodeInfo()
202  {
203    return extendedOperationResultCodeInfo;
204  }
205
206
207
208  /**
209   * Retrieves result code information for modify operations.
210   *
211   * @return  Result code information for modify operations.
212   */
213  public OperationResultCodeInfo getModifyOperationResultCodeInfo()
214  {
215    return modifyOperationResultCodeInfo;
216  }
217
218
219
220  /**
221   * Retrieves result code information for modify DN operations.
222   *
223   * @return  Result code information for modify DN operations.
224   */
225  public OperationResultCodeInfo getModifyDNOperationResultCodeInfo()
226  {
227    return modifyDNOperationResultCodeInfo;
228  }
229
230
231
232  /**
233   * Retrieves result code information for search operations.
234   *
235   * @return  Result code information for search operations.
236   */
237  public OperationResultCodeInfo getSearchOperationResultCodeInfo()
238  {
239    return searchOperationResultCodeInfo;
240  }
241
242
243
244  /**
245   * {@inheritDoc}
246   */
247  @Override()
248  public String getMonitorDisplayName()
249  {
250    return INFO_RESULT_CODE_MONITOR_DISPNAME.get();
251  }
252
253
254
255  /**
256   * {@inheritDoc}
257   */
258  @Override()
259  public String getMonitorDescription()
260  {
261    return INFO_RESULT_CODE_MONITOR_DESC.get();
262  }
263
264
265
266  /**
267   * {@inheritDoc}
268   */
269  @Override()
270  public Map<String,MonitorAttribute> getMonitorAttributes()
271  {
272    final LinkedHashMap<String,MonitorAttribute> attrs =
273         new LinkedHashMap<>(100);
274
275    addAttrs(attrs, allOperationsResultCodeInfo, "all-ops-");
276    addAttrs(attrs, addOperationResultCodeInfo, "add-op-");
277    addAttrs(attrs, bindOperationResultCodeInfo, "bind-op-");
278    addAttrs(attrs, compareOperationResultCodeInfo, "compare-op-");
279    addAttrs(attrs, deleteOperationResultCodeInfo, "delete-op-");
280    addAttrs(attrs, extendedOperationResultCodeInfo);
281    addAttrs(attrs, modifyOperationResultCodeInfo, "modify-op-");
282    addAttrs(attrs, modifyDNOperationResultCodeInfo, "modifydn-op-");
283    addAttrs(attrs, searchOperationResultCodeInfo, "search-op-");
284
285    return Collections.unmodifiableMap(attrs);
286  }
287
288
289
290  /**
291   * Updates the provided map with information about an appropriate set of
292   * monitor attributes.
293   *
294   * @param  attrs           The set of monitor attributes to be updated.
295   * @param  resultCodeInfo  The result code information to use.
296   * @param  attrPrefix      The attribute prefix
297   */
298  private static void addAttrs(
299       final LinkedHashMap<String,MonitorAttribute> attrs,
300       final OperationResultCodeInfo resultCodeInfo, final String attrPrefix)
301  {
302    final String opName;
303    if (resultCodeInfo.getOperationType() == null)
304    {
305      opName = INFO_RESULT_CODE_OP_NAME_ALL.get();
306    }
307    else
308    {
309      switch (resultCodeInfo.getOperationType())
310      {
311        case ADD:
312          opName = INFO_RESULT_CODE_OP_NAME_ADD.get();
313          break;
314        case BIND:
315          opName = INFO_RESULT_CODE_OP_NAME_BIND.get();
316          break;
317        case COMPARE:
318          opName = INFO_RESULT_CODE_OP_NAME_COMPARE.get();
319          break;
320        case DELETE:
321          opName = INFO_RESULT_CODE_OP_NAME_DELETE.get();
322          break;
323        case MODIFY:
324          opName = INFO_RESULT_CODE_OP_NAME_MODIFY.get();
325          break;
326        case MODIFY_DN:
327          opName = INFO_RESULT_CODE_OP_NAME_MODIFY_DN.get();
328          break;
329        case SEARCH:
330          opName = INFO_RESULT_CODE_OP_NAME_SEARCH.get();
331          break;
332        default:
333          opName = "Unknown";
334          break;
335      }
336    }
337
338    final String lowerOpName = StaticUtils.toLowerCase(opName);
339
340    final Long totalCount = resultCodeInfo.getTotalCount();
341    if (totalCount != null)
342    {
343      addMonitorAttribute(attrs,
344           attrPrefix + "total-count",
345           INFO_RESULT_CODE_DISPNAME_TOTAL_COUNT.get(opName),
346           INFO_RESULT_CODE_DESC_TOTAL_COUNT.get(lowerOpName),
347           totalCount);
348    }
349
350    final Long failedCount = resultCodeInfo.getFailedCount();
351    if (failedCount != null)
352    {
353      addMonitorAttribute(attrs,
354           attrPrefix + "failed-count",
355           INFO_RESULT_CODE_DISPNAME_FAILED_COUNT.get(opName),
356           INFO_RESULT_CODE_DESC_FAILED_COUNT.get(lowerOpName),
357           failedCount);
358    }
359
360    final Double failedPercent = resultCodeInfo.getFailedPercent();
361    if (failedPercent != null)
362    {
363      addMonitorAttribute(attrs,
364           attrPrefix + "failed-percent",
365           INFO_RESULT_CODE_DISPNAME_FAILED_PERCENT.get(opName),
366           INFO_RESULT_CODE_DESC_FAILED_PERCENT.get(lowerOpName),
367           failedPercent);
368    }
369
370    for (final ResultCodeInfo i :
371         resultCodeInfo.getResultCodeInfoMap().values())
372    {
373      addMonitorAttribute(attrs,
374           attrPrefix + i.intValue() + "-name",
375           INFO_RESULT_CODE_DISPNAME_RC_NAME.get(opName, i.intValue()),
376           INFO_RESULT_CODE_DESC_RC_NAME.get(lowerOpName, i.intValue()),
377           i.getName());
378
379      addMonitorAttribute(attrs,
380           attrPrefix + i.intValue() + "-count",
381           INFO_RESULT_CODE_DISPNAME_RC_COUNT.get(opName, i.intValue()),
382           INFO_RESULT_CODE_DESC_RC_COUNT.get(lowerOpName, i.intValue()),
383           i.getCount());
384
385      addMonitorAttribute(attrs,
386           attrPrefix + i.intValue() + "-percent",
387           INFO_RESULT_CODE_DISPNAME_RC_PERCENT.get(opName, i.intValue()),
388           INFO_RESULT_CODE_DESC_RC_PERCENT.get(lowerOpName, i.intValue()),
389           i.getPercent());
390
391      addMonitorAttribute(attrs,
392           attrPrefix + i.intValue() + "-average-response-time-millis",
393           INFO_RESULT_CODE_DISPNAME_RC_AVG_RT.get(opName, i.intValue()),
394           INFO_RESULT_CODE_DESC_RC_AVG_RT.get(lowerOpName, i.intValue()),
395           i.getAverageResponseTimeMillis());
396
397      addMonitorAttribute(attrs,
398           attrPrefix + i.intValue() + "-total-response-time-millis",
399           INFO_RESULT_CODE_DISPNAME_RC_TOTAL_RT.get(opName, i.intValue()),
400           INFO_RESULT_CODE_DESC_RC_TOTAL_RT.get(lowerOpName, i.intValue()),
401           i.getTotalResponseTimeMillis());
402    }
403  }
404
405
406
407  /**
408   * Updates the provided map with information about an appropriate set of
409   * monitor attributes.
410   *
411   * @param  attrs           The set of monitor attributes to be updated.
412   * @param  resultCodeInfo  The result code information to use.
413   */
414  private static void addAttrs(
415       final LinkedHashMap<String,MonitorAttribute> attrs,
416       final ExtendedOperationResultCodeInfo resultCodeInfo)
417  {
418    final String opName = INFO_RESULT_CODE_OP_NAME_EXTENDED.get();
419    final String lowerOpName = StaticUtils.toLowerCase(opName);
420
421    final Long totalCount = resultCodeInfo.getTotalCount();
422    if (totalCount != null)
423    {
424      addMonitorAttribute(attrs,
425           "extended-op-total-count",
426           INFO_RESULT_CODE_DISPNAME_TOTAL_COUNT.get(opName),
427           INFO_RESULT_CODE_DESC_TOTAL_COUNT.get(lowerOpName),
428           totalCount);
429    }
430
431    final Long failedCount = resultCodeInfo.getFailedCount();
432    if (failedCount != null)
433    {
434      addMonitorAttribute(attrs,
435           "extended-op-failed-count",
436           INFO_RESULT_CODE_DISPNAME_FAILED_COUNT.get(opName),
437           INFO_RESULT_CODE_DESC_FAILED_COUNT.get(lowerOpName),
438           failedCount);
439    }
440
441    final Double failedPercent = resultCodeInfo.getFailedPercent();
442    if (failedPercent != null)
443    {
444      addMonitorAttribute(attrs,
445           "extended-op-failed-percent",
446           INFO_RESULT_CODE_DISPNAME_FAILED_PERCENT.get(opName),
447           INFO_RESULT_CODE_DESC_FAILED_PERCENT.get(lowerOpName),
448           failedPercent);
449    }
450
451    for (final String oid :
452         resultCodeInfo.getExtendedRequestNamesByOID().keySet())
453    {
454      final String prefix = "extended-op-" + oid.replace('.', '-') + '-';
455
456      final String name =
457           resultCodeInfo.getExtendedRequestNamesByOID().get(oid);
458      if (name != null)
459      {
460        addMonitorAttribute(attrs,
461             prefix + "name",
462             INFO_RESULT_CODE_DISPNAME_EXTOP_NAME.get(oid),
463             INFO_RESULT_CODE_DESC_EXTOP_NAME.get(oid),
464             name);
465      }
466
467      final Long total = resultCodeInfo.getTotalCountsByOID().get(oid);
468      if (total != null)
469      {
470        addMonitorAttribute(attrs,
471             prefix + "total-count",
472             INFO_RESULT_CODE_DISPNAME_EXTOP_TOTAL_COUNT.get(oid),
473             INFO_RESULT_CODE_DESC_EXTOP_TOTAL_COUNT.get(oid),
474             total);
475      }
476
477      final Long failed = resultCodeInfo.getFailedCountsByOID().get(oid);
478      if (failed != null)
479      {
480        addMonitorAttribute(attrs,
481             prefix + "failed-count",
482             INFO_RESULT_CODE_DISPNAME_EXTOP_FAILED_COUNT.get(oid),
483             INFO_RESULT_CODE_DESC_EXTOP_FAILED_COUNT.get(oid),
484             failed);
485      }
486
487      final Double percent = resultCodeInfo.getFailedPercentsByOID().get(oid);
488      if (percent != null)
489      {
490        addMonitorAttribute(attrs,
491             prefix+ "failed-percent",
492             INFO_RESULT_CODE_DISPNAME_EXTOP_FAILED_PERCENT.get(oid),
493             INFO_RESULT_CODE_DESC_EXTOP_FAILED_PERCENT.get(oid),
494             percent);
495      }
496
497      final Map<Integer,ResultCodeInfo> rcInfoMap =
498           resultCodeInfo.getResultCodeInfoMap().get(oid);
499      if (rcInfoMap != null)
500      {
501        for (final ResultCodeInfo rcInfo : rcInfoMap.values())
502        {
503          final int intValue = rcInfo.intValue();
504          final String rcPrefix = prefix + intValue + '-';
505
506          addMonitorAttribute(attrs,
507               rcPrefix + "name",
508               INFO_RESULT_CODE_DISPNAME_EXTOP_RC_NAME.get(oid, intValue),
509               INFO_RESULT_CODE_DESC_EXTOP_RC_NAME.get(oid, intValue),
510               rcInfo.getName());
511          addMonitorAttribute(attrs,
512               rcPrefix + "count",
513               INFO_RESULT_CODE_DISPNAME_EXTOP_RC_COUNT.get(oid, intValue),
514               INFO_RESULT_CODE_DESC_EXTOP_RC_COUNT.get(oid, intValue),
515               rcInfo.getCount());
516          addMonitorAttribute(attrs,
517               rcPrefix + "percent",
518               INFO_RESULT_CODE_DISPNAME_EXTOP_RC_PERCENT.get(oid, intValue),
519               INFO_RESULT_CODE_DESC_EXTOP_RC_PERCENT.get(oid, intValue),
520               rcInfo.getPercent());
521          addMonitorAttribute(attrs,
522               rcPrefix + "average-response-time-millis",
523               INFO_RESULT_CODE_DISPNAME_EXTOP_RC_AVG_RT.get(oid, intValue),
524               INFO_RESULT_CODE_DESC_EXTOP_RC_AVG_RT.get(oid, intValue),
525               rcInfo.getAverageResponseTimeMillis());
526          addMonitorAttribute(attrs,
527               rcPrefix + "total-response-time-millis",
528               INFO_RESULT_CODE_DISPNAME_EXTOP_RC_TOTAL_RT.get(oid, intValue),
529               INFO_RESULT_CODE_DESC_EXTOP_RC_TOTAL_RT.get(oid, intValue),
530               rcInfo.getTotalResponseTimeMillis());
531        }
532      }
533    }
534  }
535}