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