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;
041
042import com.unboundid.asn1.ASN1Boolean;
043import com.unboundid.asn1.ASN1Element;
044import com.unboundid.asn1.ASN1Enumerated;
045import com.unboundid.asn1.ASN1Long;
046import com.unboundid.asn1.ASN1OctetString;
047import com.unboundid.asn1.ASN1Sequence;
048import com.unboundid.ldap.sdk.Control;
049import com.unboundid.ldap.sdk.LDAPException;
050import com.unboundid.ldap.sdk.ResultCode;
051import com.unboundid.util.Debug;
052import com.unboundid.util.NotMutable;
053import com.unboundid.util.StaticUtils;
054import com.unboundid.util.ThreadSafety;
055import com.unboundid.util.ThreadSafetyLevel;
056
057import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;
058
059
060
061/**
062 * This class provides an implementation of an LDAP control that can be included
063 * in add, bind, modify, modify DN, and certain extended requests to indicate
064 * the level of replication assurance desired for the associated operation.
065 * <BR>
066 * <BLOCKQUOTE>
067 *   <B>NOTE:</B>  This class, and other classes within the
068 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
069 *   supported for use against Ping Identity, UnboundID, and
070 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
071 *   for proprietary functionality or for external specifications that are not
072 *   considered stable or mature enough to be guaranteed to work in an
073 *   interoperable way with other types of LDAP servers.
074 * </BLOCKQUOTE>
075 * <BR>
076 * The OID for this control is 1.3.6.1.4.1.30221.2.5.28, and it may have a
077 * criticality of either TRUE or FALSE.  It must have a value with the following
078 * encoding:
079 * <PRE>
080 *   AssuredReplicationRequest ::= SEQUENCE {
081 *        minimumLocalLevel           [0] LocalLevel OPTIONAL,
082 *        maximumLocalLevel           [1] LocalLevel OPTIONAL,
083 *        minimumRemoteLevel          [2] RemoteLevel OPTIONAL,
084 *        maximumRemoteLevel          [3] RemoteLevel OPTIONAL,
085 *        timeoutMillis               [4] INTEGER (1 .. 2147483647) OPTIONAL,
086 *        sendResponseImmediately     [5] BOOLEAN DEFAULT FALSE,
087 *        ... }
088 *
089 *   LocalLevel ::= ENUMERATED {
090 *        none                    (0),
091 *        receivedAnyServer       (1),
092 *        processedAllServers     (2),
093 *        ... }
094 *
095 *   RemoteLevel ::= ENUMERATED {
096 *        none                           (0),
097 *        receivedAnyRemoteLocation      (1),
098 *        receivedAllRemoteLocations     (2),
099 *        processedAllRemoteServers      (3),
100 *        ... }
101 * </PRE>
102 * <BR><BR>
103 * <H2>Example</H2>
104 * The following example demonstrates the use of the assured replication request
105 * control in conjunction with a delete operation to request that the server not
106 * return the delete result to the client until the delete has been applied to
107 * all available servers in the local data center and has also been replicated
108 * to at least one remote data center:
109 * <PRE>
110 * DeleteRequest deleteRequest = new DeleteRequest(
111 *      "uid=test.user,ou=People,dc=example,dc=com");
112 * deleteRequest.addControl(new AssuredReplicationRequestControl(
113 *      AssuredReplicationLocalLevel.PROCESSED_ALL_SERVERS,
114 *      AssuredReplicationRemoteLevel.RECEIVED_ANY_REMOTE_LOCATION,
115 *      5000L));
116 *  LDAPResult deleteResult = connection.delete(deleteRequest);
117 *
118 * if (deleteResult.getResultCode() == ResultCode.SUCCESS)
119 * {
120 *   AssuredReplicationResponseControl assuredReplicationResponse =
121 *        AssuredReplicationResponseControl.get(deleteResult);
122 *   if (assuredReplicationResponse == null)
123 *   {
124 *     // The entry was deleted, but its replication could not be confirmed in
125 *     // either the local or remote data centers.
126 *   }
127 *   else
128 *   {
129 *     if (assuredReplicationResponse.localAssuranceSatisfied())
130 *     {
131 *       if (assuredReplicationResponse.remoteAssuranceSatisfied())
132 *       {
133 *         // The entry was deleted.  The delete has been applied across all
134 *         // available local servers, and has been replicated to at least one
135 *         // remote data center.
136 *       }
137 *       else
138 *       {
139 *         // The entry was deleted.  The delete has been applied across all
140 *         // available local servers, but cannot be confirmed to have yet
141 *         // been replicated to any remote data centers.
142 *       }
143 *     }
144 *     else if (assuredReplicationResponse.remoteAssuranceSatisfied())
145 *     {
146 *       // The entry was deleted.  The delete has been confirmed to have been
147 *       // replicated to at least one remote data center, but cannot be
148 *       // confirmed to have yet been applied to all available local servers.
149 *     }
150 *     else
151 *     {
152 *       // The entry was deleted, but its replication could not be confirmed
153 *       // to either local servers or remote data centers.
154 *     }
155 *   }
156 * }
157 * else
158 * {
159 *   // The entry could not be deleted.
160 * }
161 * </PRE>
162 *
163 * @see  AssuredReplicationResponseControl
164 */
165@NotMutable()
166@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
167public final class AssuredReplicationRequestControl
168       extends Control
169{
170  /**
171   * The OID (1.3.6.1.4.1.30221.2.5.28) for the assured replication request
172   * control.
173   */
174  public static final String ASSURED_REPLICATION_REQUEST_OID =
175       "1.3.6.1.4.1.30221.2.5.28";
176
177
178  /**
179   * The BER type for the minimum local assurance level.
180   */
181  private static final byte TYPE_MIN_LOCAL_LEVEL = (byte) 0x80;
182
183
184  /**
185   * The BER type for the maximum local assurance level.
186   */
187  private static final byte TYPE_MAX_LOCAL_LEVEL = (byte) 0x81;
188
189
190  /**
191   * The BER type for the minimum remote assurance level.
192   */
193  private static final byte TYPE_MIN_REMOTE_LEVEL = (byte) 0x82;
194
195
196  /**
197   * The BER type for the maximum remote assurance level.
198   */
199  private static final byte TYPE_MAX_REMOTE_LEVEL = (byte) 0x83;
200
201
202  /**
203   * The BER type for the maximum remote assurance level.
204   */
205  private static final byte TYPE_SEND_RESPONSE_IMMEDIATELY = (byte) 0x84;
206
207
208  /**
209   * The BER type for the timeout.
210   */
211  private static final byte TYPE_TIMEOUT = (byte) 0x85;
212
213
214
215  /**
216   * The serial version UID for this serializable class.
217   */
218  private static final long serialVersionUID = -2013933506118879241L;
219
220
221
222  // The requested maximum local assurance level.
223  private final AssuredReplicationLocalLevel maximumLocalLevel;
224
225  // The requested minimum local assurance level.
226  private final AssuredReplicationLocalLevel minimumLocalLevel;
227
228  // The requested maximum remote assurance level.
229  private final AssuredReplicationRemoteLevel maximumRemoteLevel;
230
231  // The requested minimum remote assurance level.
232  private final AssuredReplicationRemoteLevel minimumRemoteLevel;
233
234  // Indicates whether the server should immediately send the operation response
235  // without waiting for assurance processing.
236  private final boolean sendResponseImmediately;
237
238  // The maximum length of time in milliseconds that the server should wait for
239  // the desired assurance level to be attained.
240  private final Long timeoutMillis;
241
242
243
244  /**
245   * Creates a new assured replication request control with the provided
246   * information.  It will not be critical.
247   *
248   * @param  minimumLocalLevel   The minimum replication assurance level desired
249   *                             for servers in the same location as the server
250   *                             receiving the change.  This may be overridden
251   *                             by the server if the associated operation
252   *                             matches an assured replication criteria with a
253   *                             higher local assurance level.  If this is
254   *                             {@code null}, then the server will determine
255   *                             minimum local assurance level for the
256   *                             operation.
257   * @param  minimumRemoteLevel  The minimum replication assurance level desired
258   *                             for servers in different locations from the
259   *                             server receiving the change.  This may be
260   *                             overridden by the server if the associated
261   *                             operation matches an assured replication
262   *                             criteria with a higher remote assurance level.
263   *                             If this is {@code null}, then the server will
264   *                             determine the remote assurance level for the
265   *                             operation.
266   * @param  timeoutMillis       The maximum length of time in milliseconds to
267   *                             wait for the desired assurance to be satisfied.
268   *                             If this is {@code null}, then the server will
269   *                             determine the timeout to use.
270   */
271  public AssuredReplicationRequestControl(
272       final AssuredReplicationLocalLevel minimumLocalLevel,
273       final AssuredReplicationRemoteLevel minimumRemoteLevel,
274       final Long timeoutMillis)
275  {
276    this(false, minimumLocalLevel, null, minimumRemoteLevel, null,
277         timeoutMillis, false);
278  }
279
280
281
282  /**
283   * Creates a new assured replication request control with the provided
284   * information.
285   *
286   * @param  isCritical               Indicates whether the control should be
287   *                                  marked critical.
288   * @param  minimumLocalLevel        The minimum replication assurance level
289   *                                  desired for servers in the same location
290   *                                  as the server receiving the change.  This
291   *                                  may be overridden by the server if the
292   *                                  associated operation matches an assured
293   *                                  replication criteria with a higher local
294   *                                  assurance level.  If this is {@code null},
295   *                                  then the server will determine the minimum
296   *                                  local assurance level for the operation.
297   * @param  maximumLocalLevel        The maximum replication assurance level
298   *                                  desired for servers in the same location
299   *                                  as the server receiving the change.  This
300   *                                  may override the server configuration if
301   *                                  the operation matches an assured
302   *                                  replication criteria that would have
303   *                                  otherwise used a higher local assurance
304   *                                  level.  If this is {@code null}, then the
305   *                                  server will determine the maximum local
306   *                                  assurance level for the operation.
307   * @param  minimumRemoteLevel       The minimum replication assurance level
308   *                                  desired for servers in different locations
309   *                                  from the server receiving the change.
310   *                                  This may be overridden by the server if
311   *                                  the associated operation matches an
312   *                                  assured replication criteria with a higher
313   *                                  remote assurance level.  If this is
314   *                                  {@code null}, then the server will
315   *                                  determine the minimum remote assurance
316   *                                  level for the operation.
317   * @param  maximumRemoteLevel       The maximum replication assurance level
318   *                                  desired for servers in different locations
319   *                                  from the server receiving the change.
320   *                                  This may override the server configuration
321   *                                  if the operation matches an assured
322   *                                  replication criteria that would have
323   *                                  otherwise used a higher remote assurance
324   *                                  level.  If this is {@code null}, then the
325   *                                  server will determine the maximum remote
326   *                                  assurance level for the operation.
327   * @param  timeoutMillis            The maximum length of time in milliseconds
328   *                                  to wait for the desired assurance to be
329   *                                  satisfied.  If this is {@code null}, then
330   *                                  the server will determine the timeout to
331   *                                  use.
332   * @param  sendResponseImmediately  Indicates whether the server should
333   *              send the response to the client immediately after the change
334   *              has been applied to the server receiving the change, without
335   *              waiting for the desired assurance to be satisfied.
336   */
337  public AssuredReplicationRequestControl(final boolean isCritical,
338              final AssuredReplicationLocalLevel minimumLocalLevel,
339              final AssuredReplicationLocalLevel maximumLocalLevel,
340              final AssuredReplicationRemoteLevel minimumRemoteLevel,
341              final AssuredReplicationRemoteLevel maximumRemoteLevel,
342              final Long timeoutMillis, final boolean sendResponseImmediately)
343  {
344    super(ASSURED_REPLICATION_REQUEST_OID, isCritical,
345         encodeValue(minimumLocalLevel, maximumLocalLevel, minimumRemoteLevel,
346              maximumRemoteLevel, sendResponseImmediately, timeoutMillis));
347
348    this.minimumLocalLevel       = minimumLocalLevel;
349    this.maximumLocalLevel       = maximumLocalLevel;
350    this.minimumRemoteLevel      = minimumRemoteLevel;
351    this.maximumRemoteLevel      = maximumRemoteLevel;
352    this.sendResponseImmediately = sendResponseImmediately;
353    this.timeoutMillis           = timeoutMillis;
354  }
355
356
357
358  /**
359   * Creates a new assured replication request control from the provided generic
360   * control.
361   *
362   * @param  c  The generic control to decode as an assured replication request
363   *            control.  It must not be {@code null}.
364   *
365   * @throws  LDAPException  If the provided generic control cannot be parsed as
366   *                         an assured replication request control.
367   */
368  public AssuredReplicationRequestControl(final Control c)
369         throws LDAPException
370  {
371    super(c);
372
373    final ASN1OctetString value = c.getValue();
374    if (value == null)
375    {
376      throw new LDAPException(ResultCode.DECODING_ERROR,
377           ERR_ASSURED_REPLICATION_REQUEST_NO_VALUE.get());
378    }
379
380    AssuredReplicationLocalLevel  maxLocalLevel   = null;
381    AssuredReplicationLocalLevel  minLocalLevel   = null;
382    AssuredReplicationRemoteLevel maxRemoteLevel  = null;
383    AssuredReplicationRemoteLevel minRemoteLevel  = null;
384    boolean                       sendImmediately = false;
385    Long                          timeout         = null;
386
387    try
388    {
389      for (final ASN1Element e :
390           ASN1Sequence.decodeAsSequence(value.getValue()).elements())
391      {
392        switch (e.getType())
393        {
394          case TYPE_MIN_LOCAL_LEVEL:
395            int intValue = ASN1Enumerated.decodeAsEnumerated(e).intValue();
396            minLocalLevel = AssuredReplicationLocalLevel.valueOf(intValue);
397            if (minLocalLevel == null)
398            {
399              throw new LDAPException(ResultCode.DECODING_ERROR,
400                   ERR_ASSURED_REPLICATION_REQUEST_INVALID_MIN_LOCAL_LEVEL.get(
401                        intValue));
402            }
403            break;
404
405          case TYPE_MAX_LOCAL_LEVEL:
406            intValue = ASN1Enumerated.decodeAsEnumerated(e).intValue();
407            maxLocalLevel = AssuredReplicationLocalLevel.valueOf(intValue);
408            if (maxLocalLevel == null)
409            {
410              throw new LDAPException(ResultCode.DECODING_ERROR,
411                   ERR_ASSURED_REPLICATION_REQUEST_INVALID_MAX_LOCAL_LEVEL.get(
412                        intValue));
413            }
414            break;
415
416          case TYPE_MIN_REMOTE_LEVEL:
417            intValue = ASN1Enumerated.decodeAsEnumerated(e).intValue();
418            minRemoteLevel = AssuredReplicationRemoteLevel.valueOf(intValue);
419            if (minRemoteLevel == null)
420            {
421              throw new LDAPException(ResultCode.DECODING_ERROR,
422                   ERR_ASSURED_REPLICATION_REQUEST_INVALID_MIN_REMOTE_LEVEL.get(
423                        intValue));
424            }
425            break;
426
427          case TYPE_MAX_REMOTE_LEVEL:
428            intValue = ASN1Enumerated.decodeAsEnumerated(e).intValue();
429            maxRemoteLevel = AssuredReplicationRemoteLevel.valueOf(intValue);
430            if (maxRemoteLevel == null)
431            {
432              throw new LDAPException(ResultCode.DECODING_ERROR,
433                   ERR_ASSURED_REPLICATION_REQUEST_INVALID_MAX_REMOTE_LEVEL.get(
434                        intValue));
435            }
436            break;
437
438          case TYPE_SEND_RESPONSE_IMMEDIATELY:
439            sendImmediately = ASN1Boolean.decodeAsBoolean(e).booleanValue();
440            break;
441
442          case TYPE_TIMEOUT:
443            timeout = ASN1Long.decodeAsLong(e).longValue();
444            break;
445
446          default:
447            throw new LDAPException(ResultCode.DECODING_ERROR,
448                 ERR_ASSURED_REPLICATION_REQUEST_UNEXPECTED_ELEMENT_TYPE.get(
449                      StaticUtils.toHex(e.getType())));
450        }
451      }
452    }
453    catch (final LDAPException le)
454    {
455      Debug.debugException(le);
456      throw le;
457    }
458    catch (final Exception e)
459    {
460      Debug.debugException(e);
461      throw new LDAPException(ResultCode.DECODING_ERROR,
462           ERR_ASSURED_REPLICATION_REQUEST_ERROR_DECODING_VALUE.get(
463                StaticUtils.getExceptionMessage(e)),
464           e);
465    }
466
467    minimumLocalLevel       = minLocalLevel;
468    maximumLocalLevel       = maxLocalLevel;
469    minimumRemoteLevel      = minRemoteLevel;
470    maximumRemoteLevel      = maxRemoteLevel;
471    sendResponseImmediately = sendImmediately;
472    timeoutMillis           = timeout;
473  }
474
475
476
477  /**
478   * Encodes the provided information as needed for use as the value of this
479   * control.
480   *
481   * @param  minimumLocalLevel        The minimum replication assurance level
482   *                                  desired for servers in the same location
483   *                                  as the server receiving the change.  This
484   *                                  may be overridden by the server if the
485   *                                  associated operation matches an assured
486   *                                  replication criteria with a higher local
487   *                                  assurance level.  If this is {@code null},
488   *                                  then the server will determine the minimum
489   *                                  local assurance level for the operation.
490   * @param  maximumLocalLevel        The maximum replication assurance level
491   *                                  desired for servers in the same location
492   *                                  as the server receiving the change.  This
493   *                                  may override the server configuration if
494   *                                  the operation matches an assured
495   *                                  replication criteria that would have
496   *                                  otherwise used a higher local assurance
497   *                                  level.  If this is {@code null}, then the
498   *                                  server will determine the maximum local
499   *                                  assurance level for the operation.
500   * @param  minimumRemoteLevel       The minimum replication assurance level
501   *                                  desired for servers in different locations
502   *                                  from the server receiving the change.
503   *                                  This may be overridden by the server if
504   *                                  the associated operation matches an
505   *                                  assured replication criteria with a higher
506   *                                  remote assurance level.  If this is
507   *                                  {@code null}, then the server will
508   *                                  determine the minimum remote assurance
509   *                                  level for the operation.
510   * @param  maximumRemoteLevel       The maximum replication assurance level
511   *                                  desired for servers in different locations
512   *                                  from the server receiving the change.
513   *                                  This may override the server configuration
514   *                                  if the operation matches an assured
515   *                                  replication criteria that would have
516   *                                  otherwise used a higher remote assurance
517   *                                  level.  If this is {@code null}, then the
518   *                                  server will determine the maximum remote
519   *                                  assurance level for the operation.
520   * @param  timeoutMillis            The maximum length of time in milliseconds
521   *                                  to wait for the desired assurance to be
522   *                                  satisfied.  If this is {@code null}, then
523   *                                  the server will determine the timeout to
524   *                                  use.
525   * @param  sendResponseImmediately  Indicates whether the server should
526   *              send the response to the client immediately after the change
527   *              has been applied to the server receiving the change, without
528   *              waiting for the desired assurance to be satisfied.
529   *
530   * @return  The ASN.1 octet string containing the encoded value.
531   */
532  private static ASN1OctetString encodeValue(
533                      final AssuredReplicationLocalLevel minimumLocalLevel,
534                      final AssuredReplicationLocalLevel maximumLocalLevel,
535                      final AssuredReplicationRemoteLevel minimumRemoteLevel,
536                      final AssuredReplicationRemoteLevel maximumRemoteLevel,
537                      final boolean sendResponseImmediately,
538                      final Long timeoutMillis)
539  {
540    final ArrayList<ASN1Element> elements = new ArrayList<>(6);
541
542    if (minimumLocalLevel != null)
543    {
544      elements.add(new ASN1Enumerated(TYPE_MIN_LOCAL_LEVEL,
545           minimumLocalLevel.intValue()));
546    }
547
548    if (maximumLocalLevel != null)
549    {
550      elements.add(new ASN1Enumerated(TYPE_MAX_LOCAL_LEVEL,
551           maximumLocalLevel.intValue()));
552    }
553
554    if (minimumRemoteLevel != null)
555    {
556      elements.add(new ASN1Enumerated(TYPE_MIN_REMOTE_LEVEL,
557           minimumRemoteLevel.intValue()));
558    }
559
560    if (maximumRemoteLevel != null)
561    {
562      elements.add(new ASN1Enumerated(TYPE_MAX_REMOTE_LEVEL,
563           maximumRemoteLevel.intValue()));
564    }
565
566    if (sendResponseImmediately)
567    {
568      elements.add(new ASN1Boolean(TYPE_SEND_RESPONSE_IMMEDIATELY, true));
569    }
570
571    if (timeoutMillis != null)
572    {
573      elements.add(new ASN1Long(TYPE_TIMEOUT, timeoutMillis));
574    }
575
576    return new ASN1OctetString(new ASN1Sequence(elements).encode());
577  }
578
579
580
581  /**
582   * Retrieves the minimum desired replication level of assurance for local
583   * servers (i.e., servers in the same location as the server that originally
584   * received the change), if defined.  This may be overridden by the server if
585   * the associated operation matches an assured replication criteria with a
586   * higher local assurance level.
587   *
588   * @return  The minimum desired replication level of assurance for local
589   *          servers, or {@code null} if the server should determine the
590   *          minimum local assurance level for the operation.
591   */
592  public AssuredReplicationLocalLevel getMinimumLocalLevel()
593  {
594    return minimumLocalLevel;
595  }
596
597
598
599  /**
600   * Retrieves the maximum desired replication level of assurance for local
601   * servers (i.e., servers in the same location as the server that originally
602   * received the change), if defined.  This may override the server
603   * configuration if the operation matches an assured replication criteria that
604   * would have otherwise used a higher local assurance level.
605   *
606   * @return  The maximum desired replication level of assurance for local
607   *          servers, or {@code null} if the server should determine the
608   *          maximum local assurance level for the operation.
609   */
610  public AssuredReplicationLocalLevel getMaximumLocalLevel()
611  {
612    return maximumLocalLevel;
613  }
614
615
616
617  /**
618   * Retrieves the minimum desired replication level of assurance for remote
619   * servers (i.e., servers in locations different from the server that
620   * originally received the change), if defined.  This may be overridden by the
621   * server if the associated operation matches an assured replication
622   * criteria with a higher remote assurance level.
623   *
624   * @return  The minimum desired replication level of assurance for remote
625   *          servers, or {@code null} if the server should determine the
626   *          minimum remote assurance level for the operation.
627   */
628  public AssuredReplicationRemoteLevel getMinimumRemoteLevel()
629  {
630    return minimumRemoteLevel;
631  }
632
633
634
635  /**
636   * Retrieves the maximum desired replication level of assurance for remote
637   * servers (i.e., servers in locations different from the server that
638   * originally received the change), if defined.  This may override the server
639   * configuration if the operation matches an assured replication criteria that
640   * would have otherwise used a higher remote assurance level.
641   *
642   * @return  The maximum desired replication level of assurance for remote
643   *          servers, or {@code null} if the server should determine the
644   *          maximum remote assurance level for the operation.
645   */
646  public AssuredReplicationRemoteLevel getMaximumRemoteLevel()
647  {
648    return maximumRemoteLevel;
649  }
650
651
652
653  /**
654   * Indicates whether the server that originally received the change should
655   * return the operation result immediately, without waiting for the requested
656   * assurance processing to complete.
657   *
658   * @return  {@code false} if the server should wait to return the operation
659   *          result until the desired assurance has been attained or a timeout
660   *          has occurred, or {@code true} if the server should return the
661   *          result immediately.
662   */
663  public boolean sendResponseImmediately()
664  {
665    return sendResponseImmediately;
666  }
667
668
669
670  /**
671   * Retrieves the maximum length of time in milliseconds that the operation
672   * response should be delayed while waiting for the desired level of
673   * assurance to be attained.
674   *
675   * @return  The maximum length of time in milliseconds that the operation
676   *          response should be delayed while waiting for the desired level of
677   *          assurance to be attained.
678   */
679  public Long getTimeoutMillis()
680  {
681    return timeoutMillis;
682  }
683
684
685
686  /**
687   * {@inheritDoc}
688   */
689  @Override()
690  public String getControlName()
691  {
692    return INFO_CONTROL_NAME_ASSURED_REPLICATION_REQUEST.get();
693  }
694
695
696
697  /**
698   * {@inheritDoc}
699   */
700  @Override()
701  public void toString(final StringBuilder buffer)
702  {
703    buffer.append("AssuredReplicationRequestControl(isCritical=");
704    buffer.append(isCritical());
705
706    if (minimumLocalLevel != null)
707    {
708      buffer.append(", minimumLocalLevel=");
709      buffer.append(minimumLocalLevel.name());
710    }
711
712    if (maximumLocalLevel != null)
713    {
714      buffer.append(", maximumLocalLevel=");
715      buffer.append(maximumLocalLevel.name());
716    }
717
718    if (minimumRemoteLevel != null)
719    {
720      buffer.append(", minimumRemoteLevel=");
721      buffer.append(minimumRemoteLevel.name());
722    }
723
724    if (maximumRemoteLevel != null)
725    {
726      buffer.append(", maximumRemoteLevel=");
727      buffer.append(maximumRemoteLevel.name());
728    }
729
730    buffer.append(", sendResponseImmediately=");
731    buffer.append(sendResponseImmediately);
732
733    if (timeoutMillis != null)
734    {
735      buffer.append(", timeoutMillis=");
736      buffer.append(timeoutMillis);
737    }
738
739    buffer.append(')');
740  }
741}