001/* 002 * Copyright 2009-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2019 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 046 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 047 * for proprietary functionality or for external specifications that are not 048 * considered stable or mature enough to be guaranteed to work in an 049 * interoperable way with 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.isEmpty()) 181 { 182 referralURLs = Collections.emptyList(); 183 } 184 else 185 { 186 final LinkedList<String> refs = new LinkedList<>(); 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<>(); 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.isEmpty()) 223 { 224 serversAccessed = Collections.emptyList(); 225 } 226 else 227 { 228 final LinkedList<String> servers = new LinkedList<>(); 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.isEmpty()) 242 { 243 usedPrivileges = Collections.emptyList(); 244 } 245 else 246 { 247 final LinkedList<String> privileges = new LinkedList<>(); 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.isEmpty()) 261 { 262 preAuthZUsedPrivileges = Collections.emptyList(); 263 } 264 else 265 { 266 final LinkedList<String> privileges = new LinkedList<>(); 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.isEmpty()) 278 { 279 missingPrivileges = Collections.emptyList(); 280 } 281 else 282 { 283 final LinkedList<String> privileges = new LinkedList<>(); 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 @Override() 303 public ResultCode getResultCode() 304 { 305 return resultCode; 306 } 307 308 309 310 /** 311 * Retrieves the diagnostic message for the operation. 312 * 313 * @return The diagnostic message for the operation, or {@code null} if it is 314 * not included in the log message. 315 */ 316 @Override() 317 public String getDiagnosticMessage() 318 { 319 return diagnosticMessage; 320 } 321 322 323 324 /** 325 * Retrieves a message with additional information about the result of the 326 * operation. 327 * 328 * @return A message with additional information about the result of the 329 * operation, or {@code null} if it is not included in the log 330 * message. 331 */ 332 @Override() 333 public String getAdditionalInformation() 334 { 335 return additionalInformation; 336 } 337 338 339 340 /** 341 * Retrieves the matched DN for the operation. 342 * 343 * @return The matched DN for the operation, or {@code null} if it is not 344 * included in the log message. 345 */ 346 @Override() 347 public String getMatchedDN() 348 { 349 return matchedDN; 350 } 351 352 353 354 /** 355 * Retrieves the list of referral URLs for the operation. 356 * 357 * @return The list of referral URLs for the operation, or an empty list if 358 * it is not included in the log message. 359 */ 360 @Override() 361 public List<String> getReferralURLs() 362 { 363 return referralURLs; 364 } 365 366 367 368 /** 369 * Retrieves the number of intermediate response messages returned in the 370 * course of processing the operation. 371 * 372 * @return The number of intermediate response messages returned to the 373 * client in the course of processing the operation, or {@code null} 374 * if it is not included in the log message. 375 */ 376 @Override() 377 public Long getIntermediateResponsesReturned() 378 { 379 return intermediateResponsesReturned; 380 } 381 382 383 384 /** 385 * Retrieves the length of time in milliseconds required to process the 386 * operation. 387 * 388 * @return The length of time in milliseconds required to process the 389 * operation, or {@code null} if it is not included in the log 390 * message. 391 */ 392 @Override() 393 public Double getProcessingTimeMillis() 394 { 395 return processingTime; 396 } 397 398 399 400 /** 401 * Retrieves the length of time in milliseconds the operation was required to 402 * wait on the work queue. 403 * 404 * @return The length of time in milliseconds the operation was required to 405 * wait on the work queue, or {@code null} if it is not included in 406 * the log message. 407 */ 408 @Override() 409 public Double getQueueTimeMillis() 410 { 411 return queueTime; 412 } 413 414 415 416 /** 417 * Retrieves the OIDs of any response controls contained in the log message. 418 * 419 * @return The OIDs of any response controls contained in the log message, or 420 * an empty list if it is not included in the log message. 421 */ 422 @Override() 423 public List<String> getResponseControlOIDs() 424 { 425 return responseControlOIDs; 426 } 427 428 429 430 /** 431 * Retrieves a list of the additional servers that were accessed in the course 432 * of processing the operation. For example, if the access log message is 433 * from a Directory Proxy Server instance, then this may contain a list of the 434 * backend servers used to process the operation. 435 * 436 * @return A list of the additional servers that were accessed in the course 437 * of processing the operation, or an empty list if it is not 438 * included in the log message. 439 */ 440 @Override() 441 public List<String> getServersAccessed() 442 { 443 return serversAccessed; 444 } 445 446 447 448 /** 449 * Indicates whether the server accessed any uncached data in the course of 450 * processing the operation. 451 * 452 * @return {@code true} if the server was known to access uncached data in 453 * the course of processing the operation, {@code false} if the 454 * server was known not to access uncached data, or {@code null} if 455 * it is not included in the log message (and the server likely did 456 * not access uncached data). 457 */ 458 public Boolean getUncachedDataAccessed() 459 { 460 return uncachedDataAccessed; 461 } 462 463 464 465 /** 466 * Retrieves the content of the intermediate client result for the 467 * operation. 468 * 469 * @return The content of the intermediate client result for the operation, 470 * or {@code null} if it is not included in the log message. 471 */ 472 @Override() 473 public String getIntermediateClientResult() 474 { 475 return intermediateClientResult; 476 } 477 478 479 480 /** 481 * Retrieves the alternate authorization DN for the operation. 482 * 483 * @return The alternate authorization DN for the operation, or {@code null} 484 * if it is not included in the log message. 485 */ 486 public String getAlternateAuthorizationDN() 487 { 488 return authzDN; 489 } 490 491 492 493 /** 494 * Retrieves the address of the backend server to which the request has been 495 * forwarded. 496 * 497 * @return The address of the backend server to which the request has been 498 * forwarded, or {@code null} if it is not included in the log 499 * message. 500 */ 501 public String getTargetHost() 502 { 503 return targetHost; 504 } 505 506 507 508 /** 509 * Retrieves the port of the backend server to which the request has been 510 * forwarded. 511 * 512 * @return The port of the backend server to which the request has been 513 * forwarded, or {@code null} if it is not included in the log 514 * message. 515 */ 516 public Integer getTargetPort() 517 { 518 return targetPort; 519 } 520 521 522 523 /** 524 * Retrieves the protocol used to forward the request to the backend server. 525 * 526 * @return The protocol used to forward the request to the backend server, or 527 * {@code null} if it is not included in the log message. 528 */ 529 public String getTargetProtocol() 530 { 531 return targetProtocol; 532 } 533 534 535 536 /** 537 * Retrieves the names of any privileges used during the course of processing 538 * the operation. 539 * 540 * @return The names of any privileges used during the course of processing 541 * the operation, or an empty list if no privileges were used or this 542 * is not included in the log message. 543 */ 544 public List<String> getUsedPrivileges() 545 { 546 return usedPrivileges; 547 } 548 549 550 551 /** 552 * Retrieves the names of any privileges used during the course of processing 553 * the operation before an alternate authorization identity was assigned. 554 * 555 * @return The names of any privileges used during the course of processing 556 * the operation before an alternate authorization identity was 557 * assigned, or an empty list if no privileges were used or this is 558 * not included in the log message. 559 */ 560 public List<String> getPreAuthorizationUsedPrivileges() 561 { 562 return preAuthZUsedPrivileges; 563 } 564 565 566 567 /** 568 * Retrieves the names of any privileges that would have been required for 569 * processing the operation but that the requester did not have. 570 * 571 * @return The names of any privileges that would have been required for 572 * processing the operation but that the requester did not have, or 573 * an empty list if there were no missing privileges or this is not 574 * included in the log message. 575 */ 576 public List<String> getMissingPrivileges() 577 { 578 return missingPrivileges; 579 } 580 581 582 583 /** 584 * {@inheritDoc} 585 */ 586 @Override() 587 public AccessLogMessageType getMessageType() 588 { 589 return AccessLogMessageType.RESULT; 590 } 591}