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