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