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