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 extended 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 ExtendedResultAccessLogMessage 055 extends ExtendedRequestAccessLogMessage 056 implements OperationResultAccessLogMessage 057{ 058 /** 059 * The serial version UID for this serializable class. 060 */ 061 private static final long serialVersionUID = -3980496377400403461L; 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 number of intermediate response messages returned to the client. 096 private final Long intermediateResponsesReturned; 097 098 // The result code for the operation. 099 private final ResultCode resultCode; 100 101 // Additional information about the operation result. 102 private final String additionalInformation; 103 104 // The name of the client connection policy selected for the client. 105 private final String clientConnectionPolicy; 106 107 // The diagnostic message for the operation. 108 private final String diagnosticMessage; 109 110 // The intermediate client result for the operation. 111 private final String intermediateClientResult; 112 113 // The matched DN for the operation. 114 private final String matchedDN; 115 116 // The OID of the extended response. 117 private final String responseOID; 118 119 // The port of the backend server to which the request has been forwarded. 120 private final Integer targetPort; 121 122 // The address of the backend server to which the request has been forwarded. 123 private final String targetHost; 124 125 // The protocol used to forward the request to the backend server. 126 private final String targetProtocol; 127 128 129 130 /** 131 * Creates a new extended result access log message from the provided message 132 * string. 133 * 134 * @param s The string to be parsed as an extended result access log 135 * message. 136 * 137 * @throws LogException If the provided string cannot be parsed as a valid 138 * log message. 139 */ 140 public ExtendedResultAccessLogMessage(final String s) 141 throws LogException 142 { 143 this(new LogMessage(s)); 144 } 145 146 147 148 /** 149 * Creates a new extended result access log message from the provided log 150 * message. 151 * 152 * @param m The log message to be parsed as an extended result access log 153 * message. 154 */ 155 public ExtendedResultAccessLogMessage(final LogMessage m) 156 { 157 super(m); 158 159 diagnosticMessage = getNamedValue("message"); 160 additionalInformation = getNamedValue("additionalInfo"); 161 matchedDN = getNamedValue("matchedDN"); 162 processingTime = getNamedValueAsDouble("etime"); 163 queueTime = getNamedValueAsDouble("qtime"); 164 intermediateClientResult = getNamedValue("from"); 165 responseOID = getNamedValue("responseOID"); 166 targetHost = getNamedValue("targetHost"); 167 targetPort = getNamedValueAsInteger("targetPort"); 168 targetProtocol = getNamedValue("targetProtocol"); 169 clientConnectionPolicy = getNamedValue("clientConnectionPolicy"); 170 171 intermediateResponsesReturned = 172 getNamedValueAsLong("intermediateResponsesReturned"); 173 174 final Integer rcInteger = getNamedValueAsInteger("resultCode"); 175 if (rcInteger == null) 176 { 177 resultCode = null; 178 } 179 else 180 { 181 resultCode = ResultCode.valueOf(rcInteger); 182 } 183 184 final String refStr = getNamedValue("referralURLs"); 185 if ((refStr == null) || (refStr.length() == 0)) 186 { 187 referralURLs = Collections.emptyList(); 188 } 189 else 190 { 191 final LinkedList<String> refs = new LinkedList<String>(); 192 int startPos = 0; 193 while (true) 194 { 195 final int commaPos = refStr.indexOf(",ldap", startPos); 196 if (commaPos < 0) 197 { 198 refs.add(refStr.substring(startPos)); 199 break; 200 } 201 else 202 { 203 refs.add(refStr.substring(startPos, commaPos)); 204 startPos = commaPos+1; 205 } 206 } 207 referralURLs = Collections.unmodifiableList(refs); 208 } 209 210 final String controlStr = getNamedValue("responseControls"); 211 if (controlStr == null) 212 { 213 responseControlOIDs = Collections.emptyList(); 214 } 215 else 216 { 217 final LinkedList<String> controlList = new LinkedList<String>(); 218 final StringTokenizer t = new StringTokenizer(controlStr, ","); 219 while (t.hasMoreTokens()) 220 { 221 controlList.add(t.nextToken()); 222 } 223 responseControlOIDs = Collections.unmodifiableList(controlList); 224 } 225 226 final String serversAccessedStr = getNamedValue("serversAccessed"); 227 if ((serversAccessedStr == null) || (serversAccessedStr.length() == 0)) 228 { 229 serversAccessed = Collections.emptyList(); 230 } 231 else 232 { 233 final LinkedList<String> servers = new LinkedList<String>(); 234 final StringTokenizer tokenizer = 235 new StringTokenizer(serversAccessedStr, ","); 236 while (tokenizer.hasMoreTokens()) 237 { 238 servers.add(tokenizer.nextToken()); 239 } 240 serversAccessed = Collections.unmodifiableList(servers); 241 } 242 243 uncachedDataAccessed = getNamedValueAsBoolean("uncachedDataAccessed"); 244 245 final String usedPrivilegesStr = getNamedValue("usedPrivileges"); 246 if ((usedPrivilegesStr == null) || (usedPrivilegesStr.length() == 0)) 247 { 248 usedPrivileges = Collections.emptyList(); 249 } 250 else 251 { 252 final LinkedList<String> privileges = new LinkedList<String>(); 253 final StringTokenizer tokenizer = 254 new StringTokenizer(usedPrivilegesStr, ","); 255 while (tokenizer.hasMoreTokens()) 256 { 257 privileges.add(tokenizer.nextToken()); 258 } 259 usedPrivileges = Collections.unmodifiableList(privileges); 260 } 261 262 final String preAuthZUsedPrivilegesStr = 263 getNamedValue("preAuthZUsedPrivileges"); 264 if ((preAuthZUsedPrivilegesStr == null) || 265 (preAuthZUsedPrivilegesStr.length() == 0)) 266 { 267 preAuthZUsedPrivileges = Collections.emptyList(); 268 } 269 else 270 { 271 final LinkedList<String> privileges = new LinkedList<String>(); 272 final StringTokenizer tokenizer = 273 new StringTokenizer(preAuthZUsedPrivilegesStr, ","); 274 while (tokenizer.hasMoreTokens()) 275 { 276 privileges.add(tokenizer.nextToken()); 277 } 278 preAuthZUsedPrivileges = Collections.unmodifiableList(privileges); 279 } 280 281 final String missingPrivilegesStr = getNamedValue("missingPrivileges"); 282 if ((missingPrivilegesStr == null) || (missingPrivilegesStr.length() == 0)) 283 { 284 missingPrivileges = Collections.emptyList(); 285 } 286 else 287 { 288 final LinkedList<String> privileges = new LinkedList<String>(); 289 final StringTokenizer tokenizer = 290 new StringTokenizer(missingPrivilegesStr, ","); 291 while (tokenizer.hasMoreTokens()) 292 { 293 privileges.add(tokenizer.nextToken()); 294 } 295 missingPrivileges = Collections.unmodifiableList(privileges); 296 } 297 } 298 299 300 301 /** 302 * Retrieves the result code for the operation. 303 * 304 * @return The result code for the operation, or {@code null} if it is not 305 * included in the log message. 306 */ 307 public ResultCode getResultCode() 308 { 309 return resultCode; 310 } 311 312 313 314 /** 315 * Retrieves the diagnostic message for the operation. 316 * 317 * @return The diagnostic message for the operation, or {@code null} if it is 318 * not included in the log message. 319 */ 320 public String getDiagnosticMessage() 321 { 322 return diagnosticMessage; 323 } 324 325 326 327 /** 328 * Retrieves a message with additional information about the result of the 329 * operation. 330 * 331 * @return A message with additional information about the result of the 332 * operation, or {@code null} if it is not included in the log 333 * message. 334 */ 335 public String getAdditionalInformation() 336 { 337 return additionalInformation; 338 } 339 340 341 342 /** 343 * Retrieves the matched DN for the operation. 344 * 345 * @return The matched DN for the operation, or {@code null} if it is not 346 * included in the log message. 347 */ 348 public String getMatchedDN() 349 { 350 return matchedDN; 351 } 352 353 354 355 /** 356 * Retrieves the list of referral URLs for the operation. 357 * 358 * @return The list of referral URLs for the operation, or an empty list if 359 * it is not included in the log message. 360 */ 361 public List<String> getReferralURLs() 362 { 363 return referralURLs; 364 } 365 366 367 368 /** 369 * Retrieves a list of the additional servers that were accessed in the course 370 * of processing the operation. For example, if the access log message is 371 * from a Directory Proxy Server instance, then this may contain a list of the 372 * backend servers used to process the operation. 373 * 374 * @return A list of the additional servers that were accessed in the course 375 * of processing the operation, or an empty list if it is not 376 * included in the log message. 377 */ 378 public List<String> getServersAccessed() 379 { 380 return serversAccessed; 381 } 382 383 384 385 /** 386 * Indicates whether the server accessed any uncached data in the course of 387 * processing the operation. 388 * 389 * @return {@code true} if the server was known to access uncached data in 390 * the course of processing the operation, {@code false} if the 391 * server was known not to access uncached data, or {@code null} if 392 * it is not included in the log message (and the server likely did 393 * not access uncached data). 394 */ 395 public Boolean getUncachedDataAccessed() 396 { 397 return uncachedDataAccessed; 398 } 399 400 401 402 /** 403 * Retrieves the number of intermediate response messages returned in the 404 * course of processing the operation. 405 * 406 * @return The number of intermediate response messages returned to the 407 * client in the course of processing the operation, or {@code null} 408 * if it is not included in the log message. 409 */ 410 public Long getIntermediateResponsesReturned() 411 { 412 return intermediateResponsesReturned; 413 } 414 415 416 417 /** 418 * Retrieves the length of time in milliseconds required to process the 419 * operation. 420 * 421 * @return The length of time in milliseconds required to process the 422 * operation, or {@code null} if it is not included in the log 423 * message. 424 */ 425 public Double getProcessingTimeMillis() 426 { 427 return processingTime; 428 } 429 430 431 432 /** 433 * Retrieves the length of time in milliseconds the operation was required to 434 * wait on the work queue. 435 * 436 * @return The length of time in milliseconds the operation was required to 437 * wait on the work queue, or {@code null} if it is not included in 438 * the log message. 439 */ 440 public Double getQueueTimeMillis() 441 { 442 return queueTime; 443 } 444 445 446 447 /** 448 * Retrieves the OIDs of any response controls contained in the log message. 449 * 450 * @return The OIDs of any response controls contained in the log message, or 451 * an empty list if it is not included in the log message. 452 */ 453 public List<String> getResponseControlOIDs() 454 { 455 return responseControlOIDs; 456 } 457 458 459 460 /** 461 * Retrieves the content of the intermediate client result for the 462 * operation. 463 * 464 * @return The content of the intermediate client result for the operation, 465 * or {@code null} if it is not included in the log message. 466 */ 467 public String getIntermediateClientResult() 468 { 469 return intermediateClientResult; 470 } 471 472 473 474 /** 475 * Retrieves the OID for the extended response. 476 * 477 * @return The OID for the extended response, or {@code null} if it is not 478 * included in the log message. 479 */ 480 public String getResponseOID() 481 { 482 return responseOID; 483 } 484 485 486 487 /** 488 * Retrieves the address of the backend server to which the request has been 489 * forwarded. 490 * 491 * @return The address of the backend server to which the request has been 492 * forwarded, or {@code null} if it is not included in the log 493 * message. 494 */ 495 public String getTargetHost() 496 { 497 return targetHost; 498 } 499 500 501 502 /** 503 * Retrieves the port of the backend server to which the request has been 504 * forwarded. 505 * 506 * @return The port of the backend server to which the request has been 507 * forwarded, or {@code null} if it is not included in the log 508 * message. 509 */ 510 public Integer getTargetPort() 511 { 512 return targetPort; 513 } 514 515 516 517 /** 518 * Retrieves the protocol used to forward the request to the backend server. 519 * 520 * @return The protocol used to forward the request to the backend server, or 521 * {@code null} if it is not included in the log message. 522 */ 523 public String getTargetProtocol() 524 { 525 return targetProtocol; 526 } 527 528 529 530 /** 531 * Retrieves the name of the client connection policy that was selected for 532 * the client connection. 533 * 534 * @return The name of the client connection policy that was selected for the 535 * client connection, or {@code null} if it is not included in the 536 * log message. 537 */ 538 public String getClientConnectionPolicy() 539 { 540 return clientConnectionPolicy; 541 } 542 543 544 545 /** 546 * Retrieves the names of any privileges used during the course of processing 547 * the operation. 548 * 549 * @return The names of any privileges used during the course of processing 550 * the operation, or an empty list if no privileges were used or this 551 * is not included in the log message. 552 */ 553 public List<String> getUsedPrivileges() 554 { 555 return usedPrivileges; 556 } 557 558 559 560 /** 561 * Retrieves the names of any privileges used during the course of processing 562 * the operation before an alternate authorization identity was assigned. 563 * 564 * @return The names of any privileges used during the course of processing 565 * the operation before an alternate authorization identity was 566 * assigned, or an empty list if no privileges were used or this is 567 * not included in the log message. 568 */ 569 public List<String> getPreAuthorizationUsedPrivileges() 570 { 571 return preAuthZUsedPrivileges; 572 } 573 574 575 576 /** 577 * Retrieves the names of any privileges that would have been required for 578 * processing the operation but that the requester did not have. 579 * 580 * @return The names of any privileges that would have been required for 581 * processing the operation but that the requester did not have, or 582 * an empty list if there were no missing privileges or this is not 583 * included in the log message. 584 */ 585 public List<String> getMissingPrivileges() 586 { 587 return missingPrivileges; 588 } 589 590 591 592 /** 593 * {@inheritDoc} 594 */ 595 @Override() 596 public AccessLogMessageType getMessageType() 597 { 598 return AccessLogMessageType.RESULT; 599 } 600}