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