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