001/* 002 * Copyright 2013-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2013-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.controls; 037 038 039 040import java.util.ArrayList; 041import java.util.Collection; 042import java.util.Collections; 043import java.util.Iterator; 044import java.util.List; 045 046import com.unboundid.asn1.ASN1Boolean; 047import com.unboundid.asn1.ASN1Element; 048import com.unboundid.asn1.ASN1Enumerated; 049import com.unboundid.asn1.ASN1OctetString; 050import com.unboundid.asn1.ASN1Sequence; 051import com.unboundid.ldap.sdk.Control; 052import com.unboundid.ldap.sdk.DecodeableControl; 053import com.unboundid.ldap.sdk.LDAPException; 054import com.unboundid.ldap.sdk.LDAPResult; 055import com.unboundid.ldap.sdk.ResultCode; 056import com.unboundid.util.Debug; 057import com.unboundid.util.NotMutable; 058import com.unboundid.util.StaticUtils; 059import com.unboundid.util.ThreadSafety; 060import com.unboundid.util.ThreadSafetyLevel; 061 062import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*; 063 064 065 066/** 067 * This class provides an implementation of an LDAP control that can be included 068 * in add, bind, modify, modify DN, and certain extended responses to provide 069 * information about the result of replication assurance processing for that 070 * operation. 071 * <BR> 072 * <BLOCKQUOTE> 073 * <B>NOTE:</B> This class, and other classes within the 074 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 075 * supported for use against Ping Identity, UnboundID, and 076 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 077 * for proprietary functionality or for external specifications that are not 078 * considered stable or mature enough to be guaranteed to work in an 079 * interoperable way with other types of LDAP servers. 080 * </BLOCKQUOTE> 081 * <BR> 082 * The OID for this control is 1.3.6.1.4.1.30221.2.5.29. It will have a 083 * criticality of FALSE, and will have a value with the following encoding: 084 * <PRE> 085 * AssuredReplicationResponse ::= SEQUENCE { 086 * localLevel [0] LocalLevel OPTIONAL, 087 * localAssuranceSatisfied [1] BOOLEAN, 088 * localAssuranceMessage [2] OCTET STRING OPTIONAL, 089 * remoteLevel [3] RemoteLevel OPTIONAL, 090 * remoteAssuranceSatisfied [4] BOOLEAN, 091 * remoteAssuranceMessage [5] OCTET STRING OPTIONAL, 092 * csn [6] OCTET STRING OPTIONAL, 093 * serverResults [7] SEQUENCE OF ServerResult OPTIONAL, 094 * ... } 095 * 096 * ServerResult ::= SEQUENCE { 097 * resultCode [0] ENUMERATED { 098 * complete (0), 099 * timeout (1), 100 * conflict (2), 101 * serverShutdown (3), 102 * unavailable (4), 103 * duplicate (5), 104 * ... }, 105 * replicationServerID [1] INTEGER OPTIONAL, 106 * replicaID [2] INTEGER OPTIONAL, 107 * ... } 108 * </PRE> 109 * 110 * @see AssuredReplicationRequestControl 111 */ 112@NotMutable() 113@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 114public final class AssuredReplicationResponseControl 115 extends Control 116 implements DecodeableControl 117{ 118 /** 119 * The OID (1.3.6.1.4.1.30221.2.5.29) for the assured replication response 120 * control. 121 */ 122 public static final String ASSURED_REPLICATION_RESPONSE_OID = 123 "1.3.6.1.4.1.30221.2.5.29"; 124 125 126 /** 127 * The BER type for the local level element. 128 */ 129 private static final byte TYPE_LOCAL_LEVEL = (byte) 0x80; 130 131 132 /** 133 * The BER type for the local assurance satisfied element. 134 */ 135 private static final byte TYPE_LOCAL_SATISFIED = (byte) 0x81; 136 137 138 /** 139 * The BER type for the local message element. 140 */ 141 private static final byte TYPE_LOCAL_MESSAGE = (byte) 0x82; 142 143 144 /** 145 * The BER type for the remote level element. 146 */ 147 private static final byte TYPE_REMOTE_LEVEL = (byte) 0x83; 148 149 150 /** 151 * The BER type for the remote assurance satisfied element. 152 */ 153 private static final byte TYPE_REMOTE_SATISFIED = (byte) 0x84; 154 155 156 /** 157 * The BER type for the remote message element. 158 */ 159 private static final byte TYPE_REMOTE_MESSAGE = (byte) 0x85; 160 161 162 /** 163 * The BER type for the CSN element. 164 */ 165 private static final byte TYPE_CSN = (byte) 0x86; 166 167 168 /** 169 * The BER type for the server results element. 170 */ 171 private static final byte TYPE_SERVER_RESULTS = (byte) 0xA7; 172 173 174 175 /** 176 * The serial version UID for this serializable class. 177 */ 178 private static final long serialVersionUID = -4521456074629871607L; 179 180 181 182 // The assurance level for local processing. 183 private final AssuredReplicationLocalLevel localLevel; 184 185 // The assurance level for remote processing. 186 private final AssuredReplicationRemoteLevel remoteLevel; 187 188 // Indicates whether the desired local assurance has been satisfied. 189 private final boolean localAssuranceSatisfied; 190 191 // Indicates whether the desired remote assurance has been satisfied. 192 private final boolean remoteAssuranceSatisfied; 193 194 // The results from individual replication and/or directory servers. 195 private final List<AssuredReplicationServerResult> serverResults; 196 197 // The replication change sequence number for the associated operation. 198 private final String csn; 199 200 // An optional message with additional information about local assurance 201 // processing. 202 private final String localAssuranceMessage; 203 204 // An optional message with additional information about local assurance 205 // processing. 206 private final String remoteAssuranceMessage; 207 208 209 210 /** 211 * Creates a new empty control instance that is intended to be used only for 212 * decoding controls via the {@code DecodeableControl} interface. 213 */ 214 AssuredReplicationResponseControl() 215 { 216 localLevel = null; 217 localAssuranceSatisfied = false; 218 localAssuranceMessage = null; 219 remoteLevel = null; 220 remoteAssuranceSatisfied = false; 221 remoteAssuranceMessage = null; 222 csn = null; 223 serverResults = null; 224 } 225 226 227 228 /** 229 * Creates a new assured replication response control with the provided 230 * information. 231 * 232 * @param localLevel The local assurance level selected by the 233 * server for the associated operation. It 234 * may be {@code null} if this is not 235 * available. 236 * @param localAssuranceSatisfied Indicates whether the desired local level 237 * of assurance is known to have been 238 * satisfied. 239 * @param localAssuranceMessage An optional message providing additional 240 * information about local assurance 241 * processing. This may be {@code null} if 242 * no additional message is needed. 243 * @param remoteLevel The remote assurance level selected by 244 * the server for the associated operation. 245 * It may be {@code null} if this is not 246 * available. 247 * @param remoteAssuranceSatisfied Indicates whether the desired remote 248 * level of assurance is known to have been 249 * satisfied. 250 * @param remoteAssuranceMessage An optional message providing additional 251 * information about remote assurance 252 * processing. This may be {@code null} if 253 * no additional message is needed. 254 * @param csn The change sequence number (CSN) that has 255 * been assigned to the associated 256 * operation. It may be {@code null} if no 257 * CSN is available. 258 * @param serverResults The set of individual results from the 259 * local and/or remote replication servers 260 * and/or directory servers used in 261 * assurance processing. This may be 262 * {@code null} or empty if no server 263 * results are available. 264 */ 265 public AssuredReplicationResponseControl( 266 final AssuredReplicationLocalLevel localLevel, 267 final boolean localAssuranceSatisfied, 268 final String localAssuranceMessage, 269 final AssuredReplicationRemoteLevel remoteLevel, 270 final boolean remoteAssuranceSatisfied, 271 final String remoteAssuranceMessage, final String csn, 272 final Collection<AssuredReplicationServerResult> serverResults) 273 { 274 super(ASSURED_REPLICATION_RESPONSE_OID, false, 275 encodeValue(localLevel, localAssuranceSatisfied, 276 localAssuranceMessage, remoteLevel, remoteAssuranceSatisfied, 277 remoteAssuranceMessage, csn, serverResults)); 278 279 this.localLevel = localLevel; 280 this.localAssuranceSatisfied = localAssuranceSatisfied; 281 this.localAssuranceMessage = localAssuranceMessage; 282 this.remoteLevel = remoteLevel; 283 this.remoteAssuranceSatisfied = remoteAssuranceSatisfied; 284 this.remoteAssuranceMessage = remoteAssuranceMessage; 285 this.csn = csn; 286 287 if (serverResults == null) 288 { 289 this.serverResults = Collections.emptyList(); 290 } 291 else 292 { 293 this.serverResults = Collections.unmodifiableList( 294 new ArrayList<>(serverResults)); 295 } 296 } 297 298 299 300 /** 301 * Creates a new assured replication response control with the provided 302 * information. 303 * 304 * @param oid The OID for the control. 305 * @param isCritical Indicates whether the control should be marked 306 * critical. 307 * @param value The encoded value for the control. This may be 308 * {@code null} if no value was provided. 309 * 310 * @throws LDAPException If the provided control cannot be decoded as an 311 * assured replication response control. 312 */ 313 public AssuredReplicationResponseControl(final String oid, 314 final boolean isCritical, 315 final ASN1OctetString value) 316 throws LDAPException 317 { 318 super(oid, isCritical, value); 319 320 if (value == null) 321 { 322 throw new LDAPException(ResultCode.DECODING_ERROR, 323 ERR_ASSURED_REPLICATION_RESPONSE_NO_VALUE.get()); 324 } 325 326 AssuredReplicationLocalLevel lLevel = null; 327 Boolean lSatisfied = null; 328 String lMessage = null; 329 AssuredReplicationRemoteLevel rLevel = null; 330 Boolean rSatisfied = null; 331 String rMessage = null; 332 String seqNum = null; 333 List<AssuredReplicationServerResult> sResults = Collections.emptyList(); 334 335 try 336 { 337 for (final ASN1Element e : 338 ASN1Sequence.decodeAsSequence(value.getValue()).elements()) 339 { 340 switch (e.getType()) 341 { 342 case TYPE_LOCAL_LEVEL: 343 int intValue = ASN1Enumerated.decodeAsEnumerated(e).intValue(); 344 lLevel = AssuredReplicationLocalLevel.valueOf(intValue); 345 if (lLevel == null) 346 { 347 throw new LDAPException(ResultCode.DECODING_ERROR, 348 ERR_ASSURED_REPLICATION_RESPONSE_INVALID_LOCAL_LEVEL.get( 349 intValue)); 350 } 351 break; 352 353 case TYPE_LOCAL_SATISFIED: 354 lSatisfied = ASN1Boolean.decodeAsBoolean(e).booleanValue(); 355 break; 356 357 case TYPE_LOCAL_MESSAGE: 358 lMessage = ASN1OctetString.decodeAsOctetString(e).stringValue(); 359 break; 360 361 case TYPE_REMOTE_LEVEL: 362 intValue = ASN1Enumerated.decodeAsEnumerated(e).intValue(); 363 rLevel = AssuredReplicationRemoteLevel.valueOf(intValue); 364 if (lLevel == null) 365 { 366 throw new LDAPException(ResultCode.DECODING_ERROR, 367 ERR_ASSURED_REPLICATION_RESPONSE_INVALID_REMOTE_LEVEL.get( 368 intValue)); 369 } 370 break; 371 372 case TYPE_REMOTE_SATISFIED: 373 rSatisfied = ASN1Boolean.decodeAsBoolean(e).booleanValue(); 374 break; 375 376 case TYPE_REMOTE_MESSAGE: 377 rMessage = ASN1OctetString.decodeAsOctetString(e).stringValue(); 378 break; 379 380 case TYPE_CSN: 381 seqNum = ASN1OctetString.decodeAsOctetString(e).stringValue(); 382 break; 383 384 case TYPE_SERVER_RESULTS: 385 final ASN1Element[] srElements = 386 ASN1Sequence.decodeAsSequence(e).elements(); 387 final ArrayList<AssuredReplicationServerResult> srList = 388 new ArrayList<>(srElements.length); 389 for (final ASN1Element srElement : srElements) 390 { 391 try 392 { 393 srList.add(AssuredReplicationServerResult.decode(srElement)); 394 } 395 catch (final Exception ex) 396 { 397 Debug.debugException(ex); 398 throw new LDAPException(ResultCode.DECODING_ERROR, 399 ERR_ASSURED_REPLICATION_RESPONSE_ERROR_DECODING_SR.get( 400 StaticUtils.getExceptionMessage(ex)), 401 ex); 402 } 403 } 404 sResults = Collections.unmodifiableList(srList); 405 break; 406 407 default: 408 throw new LDAPException(ResultCode.DECODING_ERROR, 409 ERR_ASSURED_REPLICATION_RESPONSE_UNEXPECTED_ELEMENT_TYPE.get( 410 StaticUtils.toHex(e.getType()))); 411 } 412 } 413 } 414 catch (final LDAPException le) 415 { 416 Debug.debugException(le); 417 throw le; 418 } 419 catch (final Exception e) 420 { 421 Debug.debugException(e); 422 throw new LDAPException(ResultCode.DECODING_ERROR, 423 ERR_ASSURED_REPLICATION_RESPONSE_ERROR_DECODING_VALUE.get( 424 StaticUtils.getExceptionMessage(e)), 425 e); 426 } 427 428 if (lSatisfied == null) 429 { 430 throw new LDAPException(ResultCode.DECODING_ERROR, 431 ERR_ASSURED_REPLICATION_RESPONSE_NO_LOCAL_SATISFIED.get()); 432 } 433 434 if (rSatisfied == null) 435 { 436 throw new LDAPException(ResultCode.DECODING_ERROR, 437 ERR_ASSURED_REPLICATION_RESPONSE_NO_REMOTE_SATISFIED.get()); 438 } 439 440 localLevel = lLevel; 441 localAssuranceSatisfied = lSatisfied; 442 localAssuranceMessage = lMessage; 443 remoteLevel = rLevel; 444 remoteAssuranceSatisfied = rSatisfied; 445 remoteAssuranceMessage = rMessage; 446 csn = seqNum; 447 serverResults = sResults; 448 } 449 450 451 452 /** 453 * Encodes the provided information to an ASN.1 octet string suitable for 454 * use as an assured replication response control value. 455 * 456 * @param localLevel The local assurance level selected by the 457 * server for the associated operation. It 458 * may be {@code null} if this is not 459 * available. 460 * @param localAssuranceSatisfied Indicates whether the desired local level 461 * of assurance is known to have been 462 * satisfied. 463 * @param localAssuranceMessage An optional message providing additional 464 * information about local assurance 465 * processing. This may be {@code null} if 466 * no additional message is needed. 467 * @param remoteLevel The remote assurance level selected by 468 * the server for the associated operation. 469 * It may be {@code null} if this is not 470 * available. 471 * @param remoteAssuranceSatisfied Indicates whether the desired remote 472 * level of assurance is known to have been 473 * satisfied. 474 * @param remoteAssuranceMessage An optional message providing additional 475 * information about remote assurance 476 * processing. This may be {@code null} if 477 * no additional message is needed. 478 * @param csn The change sequence number (CSN) that has 479 * been assigned to the associated 480 * operation. It may be {@code null} if no 481 * CSN is available. 482 * @param serverResults The set of individual results from the 483 * local and/or remote replication servers 484 * and/or directory servers used in 485 * assurance processing. This may be 486 * {@code null} or empty if no server 487 * results are available. 488 * 489 * @return The ASN.1 octet string containing the encoded value. 490 */ 491 private static ASN1OctetString encodeValue( 492 final AssuredReplicationLocalLevel localLevel, 493 final boolean localAssuranceSatisfied, 494 final String localAssuranceMessage, 495 final AssuredReplicationRemoteLevel remoteLevel, 496 final boolean remoteAssuranceSatisfied, 497 final String remoteAssuranceMessage, final String csn, 498 final Collection<AssuredReplicationServerResult> serverResults) 499 { 500 final ArrayList<ASN1Element> elements = new ArrayList<>(8); 501 502 if (localLevel != null) 503 { 504 elements.add(new ASN1Enumerated(TYPE_LOCAL_LEVEL, localLevel.intValue())); 505 } 506 507 elements.add(new ASN1Boolean(TYPE_LOCAL_SATISFIED, 508 localAssuranceSatisfied)); 509 510 if (localAssuranceMessage != null) 511 { 512 elements.add(new ASN1OctetString(TYPE_LOCAL_MESSAGE, 513 localAssuranceMessage)); 514 } 515 516 if (remoteLevel != null) 517 { 518 elements.add(new ASN1Enumerated(TYPE_REMOTE_LEVEL, 519 remoteLevel.intValue())); 520 } 521 522 elements.add(new ASN1Boolean(TYPE_REMOTE_SATISFIED, 523 remoteAssuranceSatisfied)); 524 525 if (remoteAssuranceMessage != null) 526 { 527 elements.add(new ASN1OctetString(TYPE_REMOTE_MESSAGE, 528 remoteAssuranceMessage)); 529 } 530 531 if (csn != null) 532 { 533 elements.add(new ASN1OctetString(TYPE_CSN, csn)); 534 } 535 536 if ((serverResults != null) && (! serverResults.isEmpty())) 537 { 538 final ArrayList<ASN1Element> srElements = 539 new ArrayList<>(serverResults.size()); 540 for (final AssuredReplicationServerResult r : serverResults) 541 { 542 srElements.add(r.encode()); 543 } 544 elements.add(new ASN1Sequence(TYPE_SERVER_RESULTS, srElements)); 545 } 546 547 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 548 } 549 550 551 552 /** 553 * {@inheritDoc} 554 */ 555 @Override() 556 public AssuredReplicationResponseControl decodeControl(final String oid, 557 final boolean isCritical, 558 final ASN1OctetString value) 559 throws LDAPException 560 { 561 return new AssuredReplicationResponseControl(oid, isCritical, value); 562 } 563 564 565 566 /** 567 * Extracts an assured replication response control from the provided LDAP 568 * result. If there are multiple assured replication response controls 569 * included in the result, then only the first will be returned. 570 * 571 * @param result The LDAP result from which to retrieve the assured 572 * replication response control. 573 * 574 * @return The assured replication response control contained in the provided 575 * LDAP result, or {@code null} if the result did not contain an 576 * assured replication response control. 577 * 578 * @throws LDAPException If a problem is encountered while attempting to 579 * decode the assured replication response control 580 * contained in the provided result. 581 */ 582 public static AssuredReplicationResponseControl get(final LDAPResult result) 583 throws LDAPException 584 { 585 final Control c = 586 result.getResponseControl(ASSURED_REPLICATION_RESPONSE_OID); 587 if (c == null) 588 { 589 return null; 590 } 591 592 if (c instanceof AssuredReplicationResponseControl) 593 { 594 return (AssuredReplicationResponseControl) c; 595 } 596 else 597 { 598 return new AssuredReplicationResponseControl(c.getOID(), c.isCritical(), 599 c.getValue()); 600 } 601 } 602 603 604 605 /** 606 * Extracts all assured replication response controls from the provided LDAP 607 * result. 608 * 609 * @param result The LDAP result from which to retrieve the assured 610 * replication response controls. 611 * 612 * @return A list containing the assured replication response controls 613 * contained in the provided LDAP result, or an empty list if the 614 * result did not contain any assured replication response control. 615 * 616 * @throws LDAPException If a problem is encountered while attempting to 617 * decode any assured replication response control 618 * contained in the provided result. 619 */ 620 public static List<AssuredReplicationResponseControl> getAll( 621 final LDAPResult result) 622 throws LDAPException 623 { 624 final Control[] controls = result.getResponseControls(); 625 final ArrayList<AssuredReplicationResponseControl> decodedControls = 626 new ArrayList<>(controls.length); 627 for (final Control c : controls) 628 { 629 if (c.getOID().equals(ASSURED_REPLICATION_RESPONSE_OID)) 630 { 631 if (c instanceof AssuredReplicationResponseControl) 632 { 633 decodedControls.add((AssuredReplicationResponseControl) c); 634 } 635 else 636 { 637 decodedControls.add(new AssuredReplicationResponseControl(c.getOID(), 638 c.isCritical(), c.getValue())); 639 } 640 } 641 } 642 643 return Collections.unmodifiableList(decodedControls); 644 } 645 646 647 648 /** 649 * Retrieves the local assurance level selected by the server for the 650 * associated operation, if available. 651 * 652 * @return The local assurance level selected by the server for the 653 * associated operation, or {@code null} if this is not available. 654 */ 655 public AssuredReplicationLocalLevel getLocalLevel() 656 { 657 return localLevel; 658 } 659 660 661 662 /** 663 * Indicates whether the desired local level of assurance is known to have 664 * been satisfied. 665 * 666 * @return {@code true} if the desired local level of assurance is known to 667 * have been satisfied, or {@code false} if not. 668 */ 669 public boolean localAssuranceSatisfied() 670 { 671 return localAssuranceSatisfied; 672 } 673 674 675 676 /** 677 * Retrieves a message with additional information about local assurance 678 * processing, if available. 679 * 680 * @return A message with additional information about local assurance 681 * processing, or {@code null} if none is available. 682 */ 683 public String getLocalAssuranceMessage() 684 { 685 return localAssuranceMessage; 686 } 687 688 689 690 /** 691 * Retrieves the remote assurance level selected by the server for the 692 * associated operation, if available. 693 * 694 * @return The remote assurance level selected by the server for the 695 * associated operation, or {@code null} if the remote assurance 696 * level is not available. 697 */ 698 public AssuredReplicationRemoteLevel getRemoteLevel() 699 { 700 return remoteLevel; 701 } 702 703 704 705 /** 706 * Indicates whether the desired remote level of assurance is known to have 707 * been satisfied. 708 * 709 * @return {@code true} if the desired remote level of assurance is known to 710 * have been satisfied, or {@code false} if not. 711 */ 712 public boolean remoteAssuranceSatisfied() 713 { 714 return remoteAssuranceSatisfied; 715 } 716 717 718 719 /** 720 * Retrieves a message with additional information about remote assurance 721 * processing, if available. 722 * 723 * @return A message with additional information about remote assurance 724 * processing, or {@code null} if none is available. 725 */ 726 public String getRemoteAssuranceMessage() 727 { 728 return remoteAssuranceMessage; 729 } 730 731 732 733 /** 734 * Retrieves the replication change sequence number (CSN) assigned to the 735 * associated operation, if available. 736 * 737 * @return The replication CSN assigned to the associated operation, or 738 * {@code null} if the CSN is not available. 739 */ 740 public String getCSN() 741 { 742 return csn; 743 } 744 745 746 747 /** 748 * Retrieves a list of the results from individual replication servers and/or 749 * directory servers used in assurance processing. It may be empty if no 750 * server results are available. 751 * 752 * @return A list of the results from individual replication servers and/or 753 * directory servers used in assurance processing. 754 */ 755 public List<AssuredReplicationServerResult> getServerResults() 756 { 757 return serverResults; 758 } 759 760 761 762 /** 763 * {@inheritDoc} 764 */ 765 @Override() 766 public String getControlName() 767 { 768 return INFO_CONTROL_NAME_ASSURED_REPLICATION_RESPONSE.get(); 769 } 770 771 772 773 /** 774 * {@inheritDoc} 775 */ 776 @Override() 777 public void toString(final StringBuilder buffer) 778 { 779 buffer.append("AssuredReplicationResponseControl(isCritical="); 780 buffer.append(isCritical()); 781 782 if (localLevel != null) 783 { 784 buffer.append(", localLevel="); 785 buffer.append(localLevel.name()); 786 } 787 788 buffer.append(", localAssuranceSatisfied="); 789 buffer.append(localAssuranceSatisfied); 790 791 if (localAssuranceMessage != null) 792 { 793 buffer.append(", localMessage='"); 794 buffer.append(localAssuranceMessage); 795 buffer.append('\''); 796 } 797 798 if (remoteLevel != null) 799 { 800 buffer.append(", remoteLevel="); 801 buffer.append(remoteLevel.name()); 802 } 803 804 buffer.append(", remoteAssuranceSatisfied="); 805 buffer.append(remoteAssuranceSatisfied); 806 807 if (remoteAssuranceMessage != null) 808 { 809 buffer.append(", remoteMessage='"); 810 buffer.append(remoteAssuranceMessage); 811 buffer.append('\''); 812 } 813 814 if (csn != null) 815 { 816 buffer.append(", csn='"); 817 buffer.append(csn); 818 buffer.append('\''); 819 } 820 821 if ((serverResults != null) && (! serverResults.isEmpty())) 822 { 823 buffer.append(", serverResults={"); 824 825 final Iterator<AssuredReplicationServerResult> iterator = 826 serverResults.iterator(); 827 while (iterator.hasNext()) 828 { 829 if (iterator.hasNext()) 830 { 831 iterator.next().toString(buffer); 832 buffer.append(", "); 833 } 834 } 835 836 buffer.append('}'); 837 } 838 839 buffer.append(')'); 840 } 841}