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