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.ldap.sdk.unboundidds.controls.AssuredReplicationLocalLevel; 032import com.unboundid.ldap.sdk.unboundidds.controls. 033 AssuredReplicationRemoteLevel; 034import com.unboundid.util.NotExtensible; 035import com.unboundid.util.NotMutable; 036import com.unboundid.util.ThreadSafety; 037import com.unboundid.util.ThreadSafetyLevel; 038 039 040 041/** 042 * This class provides a data structure that holds information about a log 043 * message that may appear in the Directory Server access log about the result 044 * of a delete operation processed by the Directory Server. 045 * <BR> 046 * <BLOCKQUOTE> 047 * <B>NOTE:</B> This class, and other classes within the 048 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 049 * supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661 050 * server products. These classes provide support for proprietary 051 * functionality or for external specifications that are not considered stable 052 * or mature enough to be guaranteed to work in an interoperable way with 053 * other types of LDAP servers. 054 * </BLOCKQUOTE> 055 */ 056@NotExtensible() 057@NotMutable() 058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 059public class DeleteResultAccessLogMessage 060 extends DeleteRequestAccessLogMessage 061 implements OperationResultAccessLogMessage 062{ 063 /** 064 * The serial version UID for this serializable class. 065 */ 066 private static final long serialVersionUID = -4379716182028950134L; 067 068 069 070 // The assured replication level to use for local servers. 071 private final AssuredReplicationLocalLevel assuredReplicationLocalLevel; 072 073 // The assured replication level to use for remote servers. 074 private final AssuredReplicationRemoteLevel assuredReplicationRemoteLevel; 075 076 // Indicates whether the delete operation targeted a soft-deleted entry. 077 private final Boolean changeToSoftDeletedEntry; 078 079 // Indicates whether the response was known to be delayed by replication 080 // assurance processing. 081 private final Boolean responseDelayedByAssurance; 082 083 // Indicates whether the any uncached data was accessed in the course of 084 // processing this operation. 085 private final Boolean uncachedDataAccessed; 086 087 // The processing time for the operation. 088 private final Double processingTime; 089 090 // The queue time for the operation. 091 private final Double queueTime; 092 093 // The port of the backend server to which the request has been forwarded. 094 private final Integer targetPort; 095 096 // The list of indexes for which keys near the index entry limit were accessed 097 // while processing the operation. 098 private final List<String> indexesWithKeysAccessedNearEntryLimit; 099 100 // The list of indexes for which keys over the index entry limit were accessed 101 // while processing the operation. 102 private final List<String> indexesWithKeysAccessedOverEntryLimit; 103 104 // The list of privileges required for processing the operation that the 105 // requester did not have. 106 private final List<String> missingPrivileges; 107 108 // The list of privileges used during the course of processing the operation 109 // before an alternate authorization identity was assigned. 110 private final List<String> preAuthZUsedPrivileges; 111 112 // The list of referral URLs for the operation. 113 private final List<String> referralURLs; 114 115 // The list of response control OIDs for the operation. 116 private final List<String> responseControlOIDs; 117 118 // The list of servers accessed while processing the operation. 119 private final List<String> serversAccessed; 120 121 // The list of privileges used during the course of processing the operation. 122 private final List<String> usedPrivileges; 123 124 // The assured replication timeout, in milliseconds. 125 private final Long assuredReplicationTimeoutMillis; 126 127 // The number of intermediate response messages returned to the client. 128 private final Long intermediateResponsesReturned; 129 130 // The result code for the operation. 131 private final ResultCode resultCode; 132 133 // Additional information about the operation result. 134 private final String additionalInformation; 135 136 // The alternate authorization DN for the operation. 137 private final String authzDN; 138 139 // The diagnostic message for the operation. 140 private final String diagnosticMessage; 141 142 // The intermediate client result for the operation. 143 private final String intermediateClientResult; 144 145 // The matched DN for the operation. 146 private final String matchedDN; 147 148 // The replication change ID for the operation. 149 private final String replicationChangeID; 150 151 // The DN of the soft-deleted entry that was created as a result of a soft 152 // delete operation rather than a hard delete. 153 private final String softDeletedEntryDN; 154 155 // The address of the backend server to which the request has been forwarded. 156 private final String targetHost; 157 158 // The protocol used to forward the request to the backend server. 159 private final String targetProtocol; 160 161 162 163 /** 164 * Creates a new delete result access log message from the provided message 165 * string. 166 * 167 * @param s The string to be parsed as a delete result access log message. 168 * 169 * @throws LogException If the provided string cannot be parsed as a valid 170 * log message. 171 */ 172 public DeleteResultAccessLogMessage(final String s) 173 throws LogException 174 { 175 this(new LogMessage(s)); 176 } 177 178 179 180 /** 181 * Creates a new delete result access log message from the provided log 182 * message. 183 * 184 * @param m The log message to be parsed as a delete result access log 185 * message. 186 */ 187 public DeleteResultAccessLogMessage(final LogMessage m) 188 { 189 super(m); 190 191 diagnosticMessage = getNamedValue("message"); 192 additionalInformation = getNamedValue("additionalInfo"); 193 matchedDN = getNamedValue("matchedDN"); 194 processingTime = getNamedValueAsDouble("etime"); 195 queueTime = getNamedValueAsDouble("qtime"); 196 intermediateClientResult = getNamedValue("from"); 197 authzDN = getNamedValue("authzDN"); 198 replicationChangeID = getNamedValue("replicationChangeID"); 199 softDeletedEntryDN = getNamedValue("softDeleteEntryDN"); 200 targetHost = getNamedValue("targetHost"); 201 targetPort = getNamedValueAsInteger("targetPort"); 202 targetProtocol = getNamedValue("targetProtocol"); 203 204 changeToSoftDeletedEntry = 205 getNamedValueAsBoolean("changeToSoftDeletedEntry"); 206 intermediateResponsesReturned = 207 getNamedValueAsLong("intermediateResponsesReturned"); 208 209 final Integer rcInteger = getNamedValueAsInteger("resultCode"); 210 if (rcInteger == null) 211 { 212 resultCode = null; 213 } 214 else 215 { 216 resultCode = ResultCode.valueOf(rcInteger); 217 } 218 219 final String refStr = getNamedValue("referralURLs"); 220 if ((refStr == null) || (refStr.length() == 0)) 221 { 222 referralURLs = Collections.emptyList(); 223 } 224 else 225 { 226 final LinkedList<String> refs = new LinkedList<String>(); 227 int startPos = 0; 228 while (true) 229 { 230 final int commaPos = refStr.indexOf(",ldap", startPos); 231 if (commaPos < 0) 232 { 233 refs.add(refStr.substring(startPos)); 234 break; 235 } 236 else 237 { 238 refs.add(refStr.substring(startPos, commaPos)); 239 startPos = commaPos+1; 240 } 241 } 242 referralURLs = Collections.unmodifiableList(refs); 243 } 244 245 final String controlStr = getNamedValue("responseControls"); 246 if (controlStr == null) 247 { 248 responseControlOIDs = Collections.emptyList(); 249 } 250 else 251 { 252 final LinkedList<String> controlList = new LinkedList<String>(); 253 final StringTokenizer t = new StringTokenizer(controlStr, ","); 254 while (t.hasMoreTokens()) 255 { 256 controlList.add(t.nextToken()); 257 } 258 responseControlOIDs = Collections.unmodifiableList(controlList); 259 } 260 261 final String serversAccessedStr = getNamedValue("serversAccessed"); 262 if ((serversAccessedStr == null) || (serversAccessedStr.length() == 0)) 263 { 264 serversAccessed = Collections.emptyList(); 265 } 266 else 267 { 268 final LinkedList<String> servers = new LinkedList<String>(); 269 final StringTokenizer tokenizer = 270 new StringTokenizer(serversAccessedStr, ","); 271 while (tokenizer.hasMoreTokens()) 272 { 273 servers.add(tokenizer.nextToken()); 274 } 275 serversAccessed = Collections.unmodifiableList(servers); 276 } 277 278 uncachedDataAccessed = getNamedValueAsBoolean("uncachedDataAccessed"); 279 280 281 final String localLevelStr = getNamedValue("localAssuranceLevel"); 282 if (localLevelStr == null) 283 { 284 assuredReplicationLocalLevel = null; 285 } 286 else 287 { 288 assuredReplicationLocalLevel = 289 AssuredReplicationLocalLevel.valueOf(localLevelStr); 290 } 291 292 final String remoteLevelStr = getNamedValue("remoteAssuranceLevel"); 293 if (remoteLevelStr == null) 294 { 295 assuredReplicationRemoteLevel = null; 296 } 297 else 298 { 299 assuredReplicationRemoteLevel = 300 AssuredReplicationRemoteLevel.valueOf(remoteLevelStr); 301 } 302 303 assuredReplicationTimeoutMillis = 304 getNamedValueAsLong("assuranceTimeoutMillis"); 305 responseDelayedByAssurance = 306 getNamedValueAsBoolean("responseDelayedByAssurance"); 307 308 final String usedPrivilegesStr = getNamedValue("usedPrivileges"); 309 if ((usedPrivilegesStr == null) || (usedPrivilegesStr.length() == 0)) 310 { 311 usedPrivileges = Collections.emptyList(); 312 } 313 else 314 { 315 final LinkedList<String> privileges = new LinkedList<String>(); 316 final StringTokenizer tokenizer = 317 new StringTokenizer(usedPrivilegesStr, ","); 318 while (tokenizer.hasMoreTokens()) 319 { 320 privileges.add(tokenizer.nextToken()); 321 } 322 usedPrivileges = Collections.unmodifiableList(privileges); 323 } 324 325 final String preAuthZUsedPrivilegesStr = 326 getNamedValue("preAuthZUsedPrivileges"); 327 if ((preAuthZUsedPrivilegesStr == null) || 328 (preAuthZUsedPrivilegesStr.length() == 0)) 329 { 330 preAuthZUsedPrivileges = Collections.emptyList(); 331 } 332 else 333 { 334 final LinkedList<String> privileges = new LinkedList<String>(); 335 final StringTokenizer tokenizer = 336 new StringTokenizer(preAuthZUsedPrivilegesStr, ","); 337 while (tokenizer.hasMoreTokens()) 338 { 339 privileges.add(tokenizer.nextToken()); 340 } 341 preAuthZUsedPrivileges = Collections.unmodifiableList(privileges); 342 } 343 344 final String missingPrivilegesStr = getNamedValue("missingPrivileges"); 345 if ((missingPrivilegesStr == null) || (missingPrivilegesStr.length() == 0)) 346 { 347 missingPrivileges = Collections.emptyList(); 348 } 349 else 350 { 351 final LinkedList<String> privileges = new LinkedList<String>(); 352 final StringTokenizer tokenizer = 353 new StringTokenizer(missingPrivilegesStr, ","); 354 while (tokenizer.hasMoreTokens()) 355 { 356 privileges.add(tokenizer.nextToken()); 357 } 358 missingPrivileges = Collections.unmodifiableList(privileges); 359 } 360 361 final String indexesNearLimitStr = 362 getNamedValue("indexesWithKeysAccessedNearEntryLimit"); 363 if ((indexesNearLimitStr == null) || (indexesNearLimitStr.length() == 0)) 364 { 365 indexesWithKeysAccessedNearEntryLimit = Collections.emptyList(); 366 } 367 else 368 { 369 final LinkedList<String> indexes = new LinkedList<String>(); 370 final StringTokenizer tokenizer = 371 new StringTokenizer(indexesNearLimitStr, ","); 372 while (tokenizer.hasMoreTokens()) 373 { 374 indexes.add(tokenizer.nextToken()); 375 } 376 indexesWithKeysAccessedNearEntryLimit = 377 Collections.unmodifiableList(indexes); 378 } 379 380 final String indexesOverLimitStr = 381 getNamedValue("indexesWithKeysAccessedExceedingEntryLimit"); 382 if ((indexesOverLimitStr == null) || (indexesOverLimitStr.length() == 0)) 383 { 384 indexesWithKeysAccessedOverEntryLimit = Collections.emptyList(); 385 } 386 else 387 { 388 final LinkedList<String> indexes = new LinkedList<String>(); 389 final StringTokenizer tokenizer = 390 new StringTokenizer(indexesOverLimitStr, ","); 391 while (tokenizer.hasMoreTokens()) 392 { 393 indexes.add(tokenizer.nextToken()); 394 } 395 indexesWithKeysAccessedOverEntryLimit = 396 Collections.unmodifiableList(indexes); 397 } 398 } 399 400 401 402 /** 403 * Retrieves the result code for the operation. 404 * 405 * @return The result code for the operation, or {@code null} if it is not 406 * included in the log message. 407 */ 408 public ResultCode getResultCode() 409 { 410 return resultCode; 411 } 412 413 414 415 /** 416 * Retrieves the diagnostic message for the operation. 417 * 418 * @return The diagnostic message for the operation, or {@code null} if it is 419 * not included in the log message. 420 */ 421 public String getDiagnosticMessage() 422 { 423 return diagnosticMessage; 424 } 425 426 427 428 /** 429 * Retrieves a message with additional information about the result of the 430 * operation. 431 * 432 * @return A message with additional information about the result of the 433 * operation, or {@code null} if it is not included in the log 434 * message. 435 */ 436 public String getAdditionalInformation() 437 { 438 return additionalInformation; 439 } 440 441 442 443 /** 444 * Retrieves the matched DN for the operation. 445 * 446 * @return The matched DN for the operation, or {@code null} if it is not 447 * included in the log message. 448 */ 449 public String getMatchedDN() 450 { 451 return matchedDN; 452 } 453 454 455 456 /** 457 * Retrieves the list of referral URLs for the operation. 458 * 459 * @return The list of referral URLs for the operation, or an empty list if 460 * it is not included in the log message. 461 */ 462 public List<String> getReferralURLs() 463 { 464 return referralURLs; 465 } 466 467 468 469 /** 470 * Retrieves the number of intermediate response messages returned in the 471 * course of processing the operation. 472 * 473 * @return The number of intermediate response messages returned to the 474 * client in the course of processing the operation, or {@code null} 475 * if it is not included in the log message. 476 */ 477 public Long getIntermediateResponsesReturned() 478 { 479 return intermediateResponsesReturned; 480 } 481 482 483 484 /** 485 * Retrieves the length of time in milliseconds required to process the 486 * operation. 487 * 488 * @return The length of time in milliseconds required to process the 489 * operation, or {@code null} if it is not included in the log 490 * message. 491 */ 492 public Double getProcessingTimeMillis() 493 { 494 return processingTime; 495 } 496 497 498 499 /** 500 * Retrieves the length of time in milliseconds the operation was required to 501 * wait on the work queue. 502 * 503 * @return The length of time in milliseconds the operation was required to 504 * wait on the work queue, or {@code null} if it is not included in 505 * the log message. 506 */ 507 public Double getQueueTimeMillis() 508 { 509 return queueTime; 510 } 511 512 513 514 /** 515 * Retrieves the OIDs of any response controls contained in the log message. 516 * 517 * @return The OIDs of any response controls contained in the log message, or 518 * an empty list if it is not included in the log message. 519 */ 520 public List<String> getResponseControlOIDs() 521 { 522 return responseControlOIDs; 523 } 524 525 526 527 /** 528 * Retrieves a list of the additional servers that were accessed in the course 529 * of processing the operation. For example, if the access log message is 530 * from a Directory Proxy Server instance, then this may contain a list of the 531 * backend servers used to process the operation. 532 * 533 * @return A list of the additional servers that were accessed in the course 534 * of processing the operation, or an empty list if it is not 535 * included in the log message. 536 */ 537 public List<String> getServersAccessed() 538 { 539 return serversAccessed; 540 } 541 542 543 544 /** 545 * Indicates whether the server accessed any uncached data in the course of 546 * processing the operation. 547 * 548 * @return {@code true} if the server was known to access uncached data in 549 * the course of processing the operation, {@code false} if the 550 * server was known not to access uncached data, or {@code null} if 551 * it is not included in the log message (and the server likely did 552 * not access uncached data). 553 */ 554 public Boolean getUncachedDataAccessed() 555 { 556 return uncachedDataAccessed; 557 } 558 559 560 561 /** 562 * Retrieves the content of the intermediate client result for the 563 * operation. 564 * 565 * @return The content of the intermediate client result for the operation, 566 * or {@code null} if it is not included in the log message. 567 */ 568 public String getIntermediateClientResult() 569 { 570 return intermediateClientResult; 571 } 572 573 574 575 /** 576 * Retrieves the alternate authorization DN for the operation. 577 * 578 * @return The alternate authorization DN for the operation, or {@code null} 579 * if it is not included in the log message. 580 */ 581 public String getAlternateAuthorizationDN() 582 { 583 return authzDN; 584 } 585 586 587 588 /** 589 * Retrieves the replication change ID for the operation, if available. 590 * 591 * @return The replication change ID for the operation, or {@code null} if it 592 * is not included in the log message. 593 */ 594 public String getReplicationChangeID() 595 { 596 return replicationChangeID; 597 } 598 599 600 601 /** 602 * Retrieves the DN of the soft-deleted entry that was created as a result of 603 * this operation, if it was a soft delete rather than a normal hard delete. 604 * 605 * @return The DN of the soft-deleted entry that was created as a result of 606 * this operation, or {@code null} if it is not included in the log 607 * message (e.g., because the operation was a hard delete rather than 608 * a soft delete). 609 */ 610 public String getSoftDeletedEntryDN() 611 { 612 return softDeletedEntryDN; 613 } 614 615 616 617 /** 618 * Indicates whether the delete operation targeted a soft-deleted entry. 619 * 620 * @return {@code true} if the delete operation was known to target a 621 * soft-deleted entry, {@code false} if it was known to target a 622 * non-soft-deleted entry, or {@code null} if it is not included in 623 * the log message (and likely did not target a soft-deleted entry). 624 */ 625 public Boolean getChangeToSoftDeletedEntry() 626 { 627 return changeToSoftDeletedEntry; 628 } 629 630 631 632 /** 633 * Retrieves the address of the backend server to which the request has been 634 * forwarded. 635 * 636 * @return The address of the backend server to which the request has been 637 * forwarded, or {@code null} if it is not included in the log 638 * message. 639 */ 640 public String getTargetHost() 641 { 642 return targetHost; 643 } 644 645 646 647 /** 648 * Retrieves the port of the backend server to which the request has been 649 * forwarded. 650 * 651 * @return The port of the backend server to which the request has been 652 * forwarded, or {@code null} if it is not included in the log 653 * message. 654 */ 655 public Integer getTargetPort() 656 { 657 return targetPort; 658 } 659 660 661 662 /** 663 * Retrieves the protocol used to forward the request to the backend server. 664 * 665 * @return The protocol used to forward the request to the backend server, or 666 * {@code null} if it is not included in the log message. 667 */ 668 public String getTargetProtocol() 669 { 670 return targetProtocol; 671 } 672 673 674 675 /** 676 * Retrieves the local level that will be used for assured replication 677 * processing, if available. 678 * 679 * @return The local level that will be used for assured replication 680 * processing, or {@code null} if this is not included in the log 681 * message (e.g., because assured replication will not be performed 682 * for the operation). 683 */ 684 public AssuredReplicationLocalLevel getAssuredReplicationLocalLevel() 685 { 686 return assuredReplicationLocalLevel; 687 } 688 689 690 691 /** 692 * Retrieves the remote level that will be used for assured replication 693 * processing, if available. 694 * 695 * @return The remote level that will be used for assured replication 696 * processing, or {@code null} if this is not included in the log 697 * message (e.g., because assured replication will not be performed 698 * for the operation). 699 */ 700 public AssuredReplicationRemoteLevel getAssuredReplicationRemoteLevel() 701 { 702 return assuredReplicationRemoteLevel; 703 } 704 705 706 707 /** 708 * Retrieves the maximum length of time in milliseconds that the server will 709 * delay the response to the client while waiting for the replication 710 * assurance requirement to be satisfied. 711 * 712 * @return The maximum length of time in milliseconds that the server will 713 * delay the response to the client while waiting for the replication 714 * assurance requirement to be satisfied, or {@code null} if this is 715 * not included in the log message (e.g., because assured replication 716 * will not be performed for the operation). 717 */ 718 public Long getAssuredReplicationTimeoutMillis() 719 { 720 return assuredReplicationTimeoutMillis; 721 } 722 723 724 725 /** 726 * Indicates whether the operation response to the client will be delayed 727 * until replication assurance has been satisfied or the timeout has occurred. 728 * 729 * @return {@code true} if the operation response to the client will be 730 * delayed until replication assurance has been satisfied, 731 * {@code false} if the response will not be delayed by assurance 732 * processing, or {@code null} if this was not included in the 733 * log message (e.g., because assured replication will not be 734 * performed for the operation) 735 */ 736 public Boolean getResponseDelayedByAssurance() 737 { 738 return responseDelayedByAssurance; 739 } 740 741 742 743 /** 744 * Retrieves the names of any privileges used during the course of processing 745 * the operation. 746 * 747 * @return The names of any privileges used during the course of processing 748 * the operation, or an empty list if no privileges were used or this 749 * is not included in the log message. 750 */ 751 public List<String> getUsedPrivileges() 752 { 753 return usedPrivileges; 754 } 755 756 757 758 /** 759 * Retrieves the names of any privileges used during the course of processing 760 * the operation before an alternate authorization identity was assigned. 761 * 762 * @return The names of any privileges used during the course of processing 763 * the operation before an alternate authorization identity was 764 * assigned, or an empty list if no privileges were used or this is 765 * not included in the log message. 766 */ 767 public List<String> getPreAuthorizationUsedPrivileges() 768 { 769 return preAuthZUsedPrivileges; 770 } 771 772 773 774 /** 775 * Retrieves the names of any privileges that would have been required for 776 * processing the operation but that the requester did not have. 777 * 778 * @return The names of any privileges that would have been required for 779 * processing the operation but that the requester did not have, or 780 * an empty list if there were no missing privileges or this is not 781 * included in the log message. 782 */ 783 public List<String> getMissingPrivileges() 784 { 785 return missingPrivileges; 786 } 787 788 789 790 /** 791 * Retrieves the names of any indexes for which one or more keys near 792 * (typically, within 80% of) the index entry limit were accessed while 793 * processing the operation. 794 * 795 * @return The names of any indexes for which one or more keys near the index 796 * entry limit were accessed while processing the operation, or an 797 * empty list if no such index keys were accessed, or if this is not 798 * included in the log message. 799 */ 800 public List<String> getIndexesWithKeysAccessedNearEntryLimit() 801 { 802 return indexesWithKeysAccessedNearEntryLimit; 803 } 804 805 806 807 /** 808 * Retrieves the names of any indexes for which one or more keys over the 809 * index entry limit were accessed while processing the operation. 810 * 811 * @return The names of any indexes for which one or more keys over the index 812 * entry limit were accessed while processing the operation, or an 813 * empty list if no such index keys were accessed, or if this is not 814 * included in the log message. 815 */ 816 public List<String> getIndexesWithKeysAccessedOverEntryLimit() 817 { 818 return indexesWithKeysAccessedOverEntryLimit; 819 } 820 821 822 823 /** 824 * {@inheritDoc} 825 */ 826 @Override() 827 public AccessLogMessageType getMessageType() 828 { 829 return AccessLogMessageType.RESULT; 830 } 831}