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