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