001/* 002 * Copyright 2009-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.logs; 022 023 024 025import java.util.Collections; 026import java.util.LinkedList; 027import java.util.List; 028import java.util.StringTokenizer; 029 030import com.unboundid.ldap.sdk.ResultCode; 031import com.unboundid.util.NotMutable; 032import com.unboundid.util.ThreadSafety; 033import com.unboundid.util.ThreadSafetyLevel; 034 035 036 037/** 038 * This class provides a data structure that holds information about a log 039 * message that may appear in the Directory Server access log about the result 040 * of an abandon operation processed by the Directory Server. 041 * <BR> 042 * <BLOCKQUOTE> 043 * <B>NOTE:</B> This class, and other classes within the 044 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 045 * supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661 046 * server products. These classes provide support for proprietary 047 * functionality or for external specifications that are not considered stable 048 * or mature enough to be guaranteed to work in an interoperable way with 049 * other types of LDAP servers. 050 * </BLOCKQUOTE> 051 */ 052@NotMutable() 053@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 054public final class AbandonResultAccessLogMessage 055 extends AbandonRequestAccessLogMessage 056 implements MinimalOperationResultAccessLogMessage 057{ 058 /** 059 * The serial version UID for this serializable class. 060 */ 061 private static final long serialVersionUID = 6714469240483228080L; 062 063 064 065 // Indicates whether the any uncached data was accessed in the course of 066 // processing this operation. 067 private final Boolean uncachedDataAccessed; 068 069 // The processing time for the operation. 070 private final Double processingTime; 071 072 // The queue time for the operation. 073 private final Double queueTime; 074 075 // The list of privileges required for processing the operation that the 076 // requester did not have. 077 private final List<String> missingPrivileges; 078 079 // The list of privileges used during the course of processing the operation 080 // before an alternate authorization identity was assigned. 081 private final List<String> preAuthZUsedPrivileges; 082 083 // The list of referral URLs for the operation. 084 private final List<String> referralURLs; 085 086 // The list of response control OIDs for the operation. 087 private final List<String> responseControlOIDs; 088 089 // The list of servers accessed while processing the operation. 090 private final List<String> serversAccessed; 091 092 // The list of privileges used during the course of processing the operation. 093 private final List<String> usedPrivileges; 094 095 // The result code for the operation. 096 private final ResultCode resultCode; 097 098 // Additional information about the operation result. 099 private final String additionalInformation; 100 101 // The diagnostic message for the operation. 102 private final String diagnosticMessage; 103 104 // The intermediate client result for the operation. 105 private final String intermediateClientResult; 106 107 // The matched DN for the operation. 108 private final String matchedDN; 109 110 // The port of the backend server to which the request has been forwarded. 111 private final Integer targetPort; 112 113 // The address of the backend server to which the request has been forwarded. 114 private final String targetHost; 115 116 // The protocol used to forward the request to the backend server. 117 private final String targetProtocol; 118 119 120 121 /** 122 * Creates a new abandon result access log message from the provided message 123 * string. 124 * 125 * @param s The string to be parsed as an abandon result access log message. 126 * 127 * @throws LogException If the provided string cannot be parsed as a valid 128 * log message. 129 */ 130 public AbandonResultAccessLogMessage(final String s) 131 throws LogException 132 { 133 this(new LogMessage(s)); 134 } 135 136 137 138 /** 139 * Creates a new abandon result access log message from the provided log 140 * message. 141 * 142 * @param m The log message to be parsed as an abandon result access log 143 * message. 144 */ 145 public AbandonResultAccessLogMessage(final LogMessage m) 146 { 147 super(m); 148 149 diagnosticMessage = getNamedValue("message"); 150 additionalInformation = getNamedValue("additionalInfo"); 151 matchedDN = getNamedValue("matchedDN"); 152 processingTime = getNamedValueAsDouble("etime"); 153 queueTime = getNamedValueAsDouble("qtime"); 154 intermediateClientResult = getNamedValue("from"); 155 targetHost = getNamedValue("targetHost"); 156 targetPort = getNamedValueAsInteger("targetPort"); 157 targetProtocol = getNamedValue("targetProtocol"); 158 159 final Integer rcInteger = getNamedValueAsInteger("resultCode"); 160 if (rcInteger == null) 161 { 162 resultCode = null; 163 } 164 else 165 { 166 resultCode = ResultCode.valueOf(rcInteger); 167 } 168 169 final String refStr = getNamedValue("referralURLs"); 170 if ((refStr == null) || (refStr.length() == 0)) 171 { 172 referralURLs = Collections.emptyList(); 173 } 174 else 175 { 176 final LinkedList<String> refs = new LinkedList<String>(); 177 int startPos = 0; 178 while (true) 179 { 180 final int commaPos = refStr.indexOf(",ldap", startPos); 181 if (commaPos < 0) 182 { 183 refs.add(refStr.substring(startPos)); 184 break; 185 } 186 else 187 { 188 refs.add(refStr.substring(startPos, commaPos)); 189 startPos = commaPos+1; 190 } 191 } 192 referralURLs = Collections.unmodifiableList(refs); 193 } 194 195 final String controlStr = getNamedValue("responseControls"); 196 if (controlStr == null) 197 { 198 responseControlOIDs = Collections.emptyList(); 199 } 200 else 201 { 202 final LinkedList<String> controlList = new LinkedList<String>(); 203 final StringTokenizer t = new StringTokenizer(controlStr, ","); 204 while (t.hasMoreTokens()) 205 { 206 controlList.add(t.nextToken()); 207 } 208 responseControlOIDs = Collections.unmodifiableList(controlList); 209 } 210 211 final String serversAccessedStr = getNamedValue("serversAccessed"); 212 if ((serversAccessedStr == null) || (serversAccessedStr.length() == 0)) 213 { 214 serversAccessed = Collections.emptyList(); 215 } 216 else 217 { 218 final LinkedList<String> servers = new LinkedList<String>(); 219 final StringTokenizer tokenizer = 220 new StringTokenizer(serversAccessedStr, ","); 221 while (tokenizer.hasMoreTokens()) 222 { 223 servers.add(tokenizer.nextToken()); 224 } 225 serversAccessed = Collections.unmodifiableList(servers); 226 } 227 228 uncachedDataAccessed = getNamedValueAsBoolean("uncachedDataAccessed"); 229 230 final String usedPrivilegesStr = getNamedValue("usedPrivileges"); 231 if ((usedPrivilegesStr == null) || (usedPrivilegesStr.length() == 0)) 232 { 233 usedPrivileges = Collections.emptyList(); 234 } 235 else 236 { 237 final LinkedList<String> privileges = new LinkedList<String>(); 238 final StringTokenizer tokenizer = 239 new StringTokenizer(usedPrivilegesStr, ","); 240 while (tokenizer.hasMoreTokens()) 241 { 242 privileges.add(tokenizer.nextToken()); 243 } 244 usedPrivileges = Collections.unmodifiableList(privileges); 245 } 246 247 final String preAuthZUsedPrivilegesStr = 248 getNamedValue("preAuthZUsedPrivileges"); 249 if ((preAuthZUsedPrivilegesStr == null) || 250 (preAuthZUsedPrivilegesStr.length() == 0)) 251 { 252 preAuthZUsedPrivileges = Collections.emptyList(); 253 } 254 else 255 { 256 final LinkedList<String> privileges = new LinkedList<String>(); 257 final StringTokenizer tokenizer = 258 new StringTokenizer(preAuthZUsedPrivilegesStr, ","); 259 while (tokenizer.hasMoreTokens()) 260 { 261 privileges.add(tokenizer.nextToken()); 262 } 263 preAuthZUsedPrivileges = Collections.unmodifiableList(privileges); 264 } 265 266 final String missingPrivilegesStr = getNamedValue("missingPrivileges"); 267 if ((missingPrivilegesStr == null) || (missingPrivilegesStr.length() == 0)) 268 { 269 missingPrivileges = Collections.emptyList(); 270 } 271 else 272 { 273 final LinkedList<String> privileges = new LinkedList<String>(); 274 final StringTokenizer tokenizer = 275 new StringTokenizer(missingPrivilegesStr, ","); 276 while (tokenizer.hasMoreTokens()) 277 { 278 privileges.add(tokenizer.nextToken()); 279 } 280 missingPrivileges = Collections.unmodifiableList(privileges); 281 } 282 } 283 284 285 286 /** 287 * Retrieves the result code for the operation. 288 * 289 * @return The result code for the operation, or {@code null} if it is not 290 * included in the log message. 291 */ 292 public ResultCode getResultCode() 293 { 294 return resultCode; 295 } 296 297 298 299 /** 300 * Retrieves the diagnostic message for the operation. 301 * 302 * @return The diagnostic message for the operation, or {@code null} if it is 303 * not included in the log message. 304 */ 305 public String getDiagnosticMessage() 306 { 307 return diagnosticMessage; 308 } 309 310 311 312 /** 313 * Retrieves a message with additional information about the result of the 314 * operation. 315 * 316 * @return A message with additional information about the result of the 317 * operation, or {@code null} if it is not included in the log 318 * message. 319 */ 320 public String getAdditionalInformation() 321 { 322 return additionalInformation; 323 } 324 325 326 327 /** 328 * Retrieves the matched DN for the operation. 329 * 330 * @return The matched DN for the operation, or {@code null} if it is not 331 * included in the log message. 332 */ 333 public String getMatchedDN() 334 { 335 return matchedDN; 336 } 337 338 339 340 /** 341 * Retrieves the list of referral URLs for the operation. 342 * 343 * @return The list of referral URLs for the operation, or an empty list if 344 * it is not included in the log message. 345 */ 346 public List<String> getReferralURLs() 347 { 348 return referralURLs; 349 } 350 351 352 353 /** 354 * Retrieves the length of time in milliseconds required to process the 355 * operation. 356 * 357 * @return The length of time in milliseconds required to process the 358 * operation, or {@code null} if it is not included in the log 359 * message. 360 */ 361 public Double getProcessingTimeMillis() 362 { 363 return processingTime; 364 } 365 366 367 368 /** 369 * Retrieves the length of time in milliseconds the operation was required to 370 * wait on the work queue. 371 * 372 * @return The length of time in milliseconds the operation was required to 373 * wait on the work queue, or {@code null} if it is not included in 374 * the log message. 375 */ 376 public Double getQueueTimeMillis() 377 { 378 return queueTime; 379 } 380 381 382 383 /** 384 * Retrieves the OIDs of any response controls contained in the log message. 385 * 386 * @return The OIDs of any response controls contained in the log message, or 387 * an empty list if it is not included in the log message. 388 */ 389 public List<String> getResponseControlOIDs() 390 { 391 return responseControlOIDs; 392 } 393 394 395 396 /** 397 * Retrieves a list of the additional servers that were accessed in the course 398 * of processing the operation. For example, if the access log message is 399 * from a Directory Proxy Server instance, then this may contain a list of the 400 * backend servers used to process the operation. 401 * 402 * @return A list of the additional servers that were accessed in the course 403 * of processing the operation, or an empty list if it is not 404 * included in the log message. 405 */ 406 public List<String> getServersAccessed() 407 { 408 return serversAccessed; 409 } 410 411 412 413 /** 414 * Indicates whether the server accessed any uncached data in the course of 415 * processing the operation. 416 * 417 * @return {@code true} if the server was known to access uncached data in 418 * the course of processing the operation, {@code false} if the 419 * server was known not to access uncached data, or {@code null} if 420 * it is not included in the log message (and the server likely did 421 * not access uncached data). 422 */ 423 public Boolean getUncachedDataAccessed() 424 { 425 return uncachedDataAccessed; 426 } 427 428 429 430 /** 431 * Retrieves the content of the intermediate client result for the 432 * operation. 433 * 434 * @return The content of the intermediate client result for the operation, 435 * or {@code null} if it is not included in the log message. 436 */ 437 public String getIntermediateClientResult() 438 { 439 return intermediateClientResult; 440 } 441 442 443 444 /** 445 * Retrieves the address of the backend server to which the request has been 446 * forwarded. 447 * 448 * @return The address of the backend server to which the request has been 449 * forwarded, or {@code null} if it is not included in the log 450 * message. 451 */ 452 public String getTargetHost() 453 { 454 return targetHost; 455 } 456 457 458 459 /** 460 * Retrieves the port of the backend server to which the request has been 461 * forwarded. 462 * 463 * @return The port of the backend server to which the request has been 464 * forwarded, or {@code null} if it is not included in the log 465 * message. 466 */ 467 public Integer getTargetPort() 468 { 469 return targetPort; 470 } 471 472 473 474 /** 475 * Retrieves the protocol used to forward the request to the backend server. 476 * 477 * @return The protocol used to forward the request to the backend server, or 478 * {@code null} if it is not included in the log message. 479 */ 480 public String getTargetProtocol() 481 { 482 return targetProtocol; 483 } 484 485 486 487 /** 488 * Retrieves the names of any privileges used during the course of processing 489 * the operation. 490 * 491 * @return The names of any privileges used during the course of processing 492 * the operation, or an empty list if no privileges were used or this 493 * is not included in the log message. 494 */ 495 public List<String> getUsedPrivileges() 496 { 497 return usedPrivileges; 498 } 499 500 501 502 /** 503 * Retrieves the names of any privileges used during the course of processing 504 * the operation before an alternate authorization identity was assigned. 505 * 506 * @return The names of any privileges used during the course of processing 507 * the operation before an alternate authorization identity was 508 * assigned, or an empty list if no privileges were used or this is 509 * not included in the log message. 510 */ 511 public List<String> getPreAuthorizationUsedPrivileges() 512 { 513 return preAuthZUsedPrivileges; 514 } 515 516 517 518 /** 519 * Retrieves the names of any privileges that would have been required for 520 * processing the operation but that the requester did not have. 521 * 522 * @return The names of any privileges that would have been required for 523 * processing the operation but that the requester did not have, or 524 * an empty list if there were no missing privileges or this is not 525 * included in the log message. 526 */ 527 public List<String> getMissingPrivileges() 528 { 529 return missingPrivileges; 530 } 531 532 533 534 /** 535 * {@inheritDoc} 536 */ 537 @Override() 538 public AccessLogMessageType getMessageType() 539 { 540 return AccessLogMessageType.RESULT; 541 } 542}