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