001/* 002 * Copyright 2014-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2014-2024 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) 2014-2024 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.ASN1Integer; 046import com.unboundid.asn1.ASN1Long; 047import com.unboundid.asn1.ASN1OctetString; 048import com.unboundid.asn1.ASN1Sequence; 049import com.unboundid.ldap.sdk.Control; 050import com.unboundid.ldap.sdk.LDAPException; 051import com.unboundid.ldap.sdk.ResultCode; 052import com.unboundid.util.Debug; 053import com.unboundid.util.NotMutable; 054import com.unboundid.util.NotNull; 055import com.unboundid.util.Nullable; 056import com.unboundid.util.StaticUtils; 057import com.unboundid.util.ThreadSafety; 058import com.unboundid.util.ThreadSafetyLevel; 059import com.unboundid.util.Validator; 060 061import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*; 062 063 064 065/** 066 * This class provides a request control that can be used to specify a number of 067 * settings used for any database transaction that may be associated with the 068 * associated request. It may be included in an end transaction extended 069 * request or an atomic multi-update extended request (it is not supported for 070 * use in non-atomic multi-update requests). 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 * This control has an OID of 1.3.6.1.4.1.30221.2.5.38. It may have a 083 * criticality of either {@code true} (in which case the server will reject the 084 * associated operation if this control is not recognized) or {@code false} (in 085 * which case the server will ignore this control if it is not recognized). It 086 * must have a value with the following encoding: 087 * <PRE> 088 * TransactionSettingsRequestValue ::= SEQUENCE { 089 * transactionName [0] OCTET STRING OPTIONAL, 090 * commitDurability [1] ENUMERATED { 091 * nonSynchronous (0), 092 * partiallySynchronous (1), 093 * fullySynchronous (2), 094 * ... } OPTIONAL, 095 * backendLockBehavior [2] ENUMERATED { 096 * doNotAcquire (0), 097 * acquireAfterRetries (1), 098 * acquireBeforeRetries (2), 099 * acquireBeforeInitialAttempt (3), 100 * ... } OPTIONAL, 101 * backendLockTimeoutMillis [3] INTEGER OPTIONAL, 102 * retryAttempts [4] INTEGER OPTIONAL, 103 * txnLockTimeout [5] SEQUENCE { 104 * minTimeoutMillis INTEGER, 105 * maxTimeoutMillis INTEGER, 106 * ... } OPTIONAL, 107 * returnResponseControl [6] BOOLEAN DEFAULT FALSE, 108 * ... } 109 * </PRE> 110 */ 111@NotMutable() 112@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 113public final class TransactionSettingsRequestControl 114 extends Control 115{ 116 /** 117 * The OID (1.3.6.1.4.1.30221.2.5.38) for the undelete request control. 118 */ 119 @NotNull public static final String TRANSACTION_SETTINGS_REQUEST_OID = 120 "1.3.6.1.4.1.30221.2.5.38"; 121 122 123 124 /** 125 * The BER type for the value sequence element that specifies the name to use 126 * for the transaction. 127 */ 128 private static final byte TYPE_TXN_NAME = (byte) 0x80; 129 130 131 132 /** 133 * The BER type for the value sequence element that specifies the commit 134 * durability to use. 135 */ 136 private static final byte TYPE_COMMIT_DURABILITY = (byte) 0x81; 137 138 139 140 /** 141 * The BER type for the value sequence element that specifies the behavior 142 * to use with regard to acquiring the exclusive backend lock. 143 */ 144 private static final byte TYPE_BACKEND_LOCK_BEHAVIOR = (byte) 0x82; 145 146 147 148 /** 149 * The BER type for the value sequence element that specifies the exclusive 150 * backend lock timeout. 151 */ 152 private static final byte TYPE_BACKEND_LOCK_TIMEOUT = (byte) 0x83; 153 154 155 156 /** 157 * The BER type for the value sequence element that specifies the number of 158 * retry attempts. 159 */ 160 private static final byte TYPE_RETRY_ATTEMPTS = (byte) 0x84; 161 162 163 164 /** 165 * The BER type for the value sequence element that specifies the minimum and 166 * maximum database lock timeout values. 167 */ 168 private static final byte TYPE_TXN_LOCK_TIMEOUT = (byte) 0xA5; 169 170 171 172 /** 173 * The BER type for the value sequence element that indicates whether to 174 * return a response control with transaction-related information about the 175 * processing of the associated operation. 176 */ 177 private static final byte TYPE_RETURN_RESPONSE_CONTROL = (byte) 0x86; 178 179 180 181 /** 182 * The serial version UID for this serializable class. 183 */ 184 private static final long serialVersionUID = -4749344077745581287L; 185 186 187 188 // Indicates whether to return a response control. 189 private final boolean returnResponseControl; 190 191 // The number of times to retry if a lock conflict exception is encountered. 192 @Nullable private final Integer retryAttempts; 193 194 // The backend lock timeout, in milliseconds. 195 @Nullable private final Long backendLockTimeoutMillis; 196 197 // The maximum transaction lock timeout, in milliseconds. 198 @Nullable private final Long maxTxnLockTimeoutMillis; 199 200 // The minimum transaction lock timeout, in milliseconds. 201 @Nullable private final Long minTxnLockTimeoutMillis; 202 203 // The requested transaction name. 204 @Nullable private final String transactionName; 205 206 // The requested commit durability setting. 207 @Nullable private final TransactionSettingsBackendLockBehavior 208 backendLockBehavior; 209 210 // The requested commit durability setting. 211 @Nullable private final TransactionSettingsCommitDurability commitDurability; 212 213 214 215 /** 216 * Creates a new transaction settings request control with the provided 217 * information. 218 * 219 * @param isCritical Indicates whether the control should be 220 * considered critical. 221 * @param transactionName The name to use for the transaction. It 222 * may be {@code null} if no 223 * client-specified transaction name is 224 * needed. If a transaction name is 225 * provided, it will be used purely for 226 * informational and/or troubleshooting 227 * purposes. 228 * @param commitDurability The durability level that should be used 229 * when committing the associated 230 * transaction. It may be {@code null} if 231 * the server-default durability level 232 * should be used. 233 * @param backendLockBehavior The behavior that should be used with 234 * regard to acquiring an exclusive lock for 235 * processing in the target backend. It may 236 * be {@code null} if the server-default 237 * backend lock behavior should be used. 238 * @param backendLockTimeoutMillis The maximum length of time in 239 * milliseconds to spend attempting to 240 * acquire an exclusive backend lock if it 241 * is needed during any part of the 242 * processing. A value that of zero 243 * indicates that no timeout should be 244 * enforced. It may be {@code null} if the 245 * server will determine the backend lock 246 * timeout that should be used. 247 * @param retryAttempts The number of times to retry the 248 * associated operations in a new 249 * transaction if the initial attempt fails. 250 * If this is {@code null}, then the server 251 * will determine the number of retry 252 * attempts to make. Note that depending on 253 * the backend lock behavior, the server may 254 * make one additional retry attempt if 255 * necessary after acquiring an exclusive 256 * backend lock. 257 * @param minTxnLockTimeoutMillis The minimum database lock timeout that 258 * should be used for the associated 259 * transaction. If this is specified, then 260 * the first attempt will use this lock 261 * timeout, and subsequent attempts will use 262 * a timeout value between this and the 263 * maximum database lock timeout (which must 264 * also be specified). If this is 265 * {@code null}, then the server will 266 * determine the database lock timeout 267 * settings to use. 268 * @param maxTxnLockTimeoutMillis The maximum database lock timeout that 269 * should be used for the associated 270 * transaction. If this is specified, then 271 * the minimum database lock timeout must 272 * also be specified, and this value must be 273 * greater than or equal to the minimum lock 274 * timeout. If this is {@code null}, then 275 * the server will determine the database 276 * lock timeout settings to use. 277 */ 278 public TransactionSettingsRequestControl(final boolean isCritical, 279 @Nullable final String transactionName, 280 @Nullable final TransactionSettingsCommitDurability commitDurability, 281 @Nullable final TransactionSettingsBackendLockBehavior 282 backendLockBehavior, 283 @Nullable final Long backendLockTimeoutMillis, 284 @Nullable final Integer retryAttempts, 285 @Nullable final Long minTxnLockTimeoutMillis, 286 @Nullable final Long maxTxnLockTimeoutMillis) 287 { 288 this(isCritical, transactionName, commitDurability, backendLockBehavior, 289 backendLockTimeoutMillis, retryAttempts, minTxnLockTimeoutMillis, 290 maxTxnLockTimeoutMillis, false); 291 } 292 293 294 295 /** 296 * Creates a new transaction settings request control with the provided 297 * information. 298 * 299 * @param isCritical Indicates whether the control should be 300 * considered critical. 301 * @param transactionName The name to use for the transaction. It 302 * may be {@code null} if no 303 * client-specified transaction name is 304 * needed. If a transaction name is 305 * provided, it will be used purely for 306 * informational and/or troubleshooting 307 * purposes. 308 * @param commitDurability The durability level that should be used 309 * when committing the associated 310 * transaction. It may be {@code null} if 311 * the server-default durability level 312 * should be used. 313 * @param backendLockBehavior The behavior that should be used with 314 * regard to acquiring an exclusive lock for 315 * processing in the target backend. It may 316 * be {@code null} if the server-default 317 * backend lock behavior should be used. 318 * @param backendLockTimeoutMillis The maximum length of time in 319 * milliseconds to spend attempting to 320 * acquire an exclusive backend lock if it 321 * is needed during any part of the 322 * processing. A value that of zero 323 * indicates that no timeout should be 324 * enforced. It may be {@code null} if the 325 * server will determine the backend lock 326 * timeout that should be used. 327 * @param retryAttempts The number of times to retry the 328 * associated operations in a new 329 * transaction if the initial attempt fails. 330 * If this is {@code null}, then the server 331 * will determine the number of retry 332 * attempts to make. Note that depending on 333 * the backend lock behavior, the server may 334 * make one additional retry attempt if 335 * necessary after acquiring an exclusive 336 * backend lock. 337 * @param minTxnLockTimeoutMillis The minimum database lock timeout that 338 * should be used for the associated 339 * transaction. If this is specified, then 340 * the first attempt will use this lock 341 * timeout, and subsequent attempts will use 342 * a timeout value between this and the 343 * maximum database lock timeout (which must 344 * also be specified). If this is 345 * {@code null}, then the server will 346 * determine the database lock timeout 347 * settings to use. 348 * @param maxTxnLockTimeoutMillis The maximum database lock timeout that 349 * should be used for the associated 350 * transaction. If this is specified, then 351 * the minimum database lock timeout must 352 * also be specified, and this value must be 353 * greater than or equal to the minimum lock 354 * timeout. If this is {@code null}, then 355 * the server will determine the database 356 * lock timeout settings to use. 357 * @param returnResponseControl Indicates whether to return a response 358 * control with transaction-related 359 * information collected over the course of 360 * processing the associated operation. 361 */ 362 public TransactionSettingsRequestControl(final boolean isCritical, 363 @Nullable final String transactionName, 364 @Nullable final TransactionSettingsCommitDurability commitDurability, 365 @Nullable final TransactionSettingsBackendLockBehavior 366 backendLockBehavior, 367 @Nullable final Long backendLockTimeoutMillis, 368 @Nullable final Integer retryAttempts, 369 @Nullable final Long minTxnLockTimeoutMillis, 370 @Nullable final Long maxTxnLockTimeoutMillis, 371 final boolean returnResponseControl) 372 { 373 super(TRANSACTION_SETTINGS_REQUEST_OID, isCritical, 374 encodeValue(transactionName, commitDurability, backendLockBehavior, 375 backendLockTimeoutMillis, retryAttempts, minTxnLockTimeoutMillis, 376 maxTxnLockTimeoutMillis, returnResponseControl)); 377 378 this.transactionName = transactionName; 379 this.commitDurability = commitDurability; 380 this.backendLockBehavior = backendLockBehavior; 381 this.backendLockTimeoutMillis = backendLockTimeoutMillis; 382 this.minTxnLockTimeoutMillis = minTxnLockTimeoutMillis; 383 this.maxTxnLockTimeoutMillis = maxTxnLockTimeoutMillis; 384 this.retryAttempts = retryAttempts; 385 this.returnResponseControl = returnResponseControl; 386 } 387 388 389 390 /** 391 * Creates a new transaction settings request control that is decoded from the 392 * provided generic control. 393 * 394 * @param c The generic control to decode as a transaction settings request 395 * control. 396 * 397 * @throws LDAPException If a problem is encountered while attempting to 398 * decode the provided control as a transaction 399 * settings request control. 400 */ 401 public TransactionSettingsRequestControl(@NotNull final Control c) 402 throws LDAPException 403 { 404 super(c); 405 406 final ASN1OctetString value = c.getValue(); 407 if (value == null) 408 { 409 throw new LDAPException(ResultCode.DECODING_ERROR, 410 ERR_TXN_SETTINGS_REQUEST_MISSING_VALUE.get()); 411 } 412 413 try 414 { 415 boolean responseControl = false; 416 Integer numRetries = null; 417 Long backendTimeout = null; 418 Long maxTxnLockTimeout = null; 419 Long minTxnLockTimeout = null; 420 String txnName = null; 421 TransactionSettingsCommitDurability durability = null; 422 TransactionSettingsBackendLockBehavior lockBehavior = null; 423 424 for (final ASN1Element e : 425 ASN1Sequence.decodeAsSequence(value.getValue()).elements()) 426 { 427 switch (e.getType()) 428 { 429 case TYPE_TXN_NAME: 430 txnName = ASN1OctetString.decodeAsOctetString(e).stringValue(); 431 break; 432 433 case TYPE_COMMIT_DURABILITY: 434 durability = TransactionSettingsCommitDurability.valueOf( 435 ASN1Enumerated.decodeAsEnumerated(e).intValue()); 436 if (durability == null) 437 { 438 throw new LDAPException(ResultCode.DECODING_ERROR, 439 ERR_TXN_SETTINGS_REQUEST_UNKNOWN_DURABILITY.get( 440 ASN1Enumerated.decodeAsEnumerated(e).intValue())); 441 } 442 break; 443 444 case TYPE_BACKEND_LOCK_BEHAVIOR: 445 lockBehavior = TransactionSettingsBackendLockBehavior.valueOf( 446 ASN1Enumerated.decodeAsEnumerated(e).intValue()); 447 if (lockBehavior == null) 448 { 449 throw new LDAPException(ResultCode.DECODING_ERROR, 450 ERR_TXN_SETTINGS_REQUEST_UNKNOWN_LOCK_BEHAVIOR.get( 451 ASN1Enumerated.decodeAsEnumerated(e).intValue())); 452 } 453 break; 454 455 case TYPE_BACKEND_LOCK_TIMEOUT: 456 backendTimeout = ASN1Long.decodeAsLong(e).longValue(); 457 if (backendTimeout < 0L) 458 { 459 throw new LDAPException(ResultCode.DECODING_ERROR, 460 ERR_TXN_SETTINGS_REQUEST_INVALID_BACKEND_LOCK_TIMEOUT.get( 461 backendTimeout)); 462 } 463 break; 464 465 case TYPE_RETRY_ATTEMPTS: 466 numRetries = ASN1Integer.decodeAsInteger(e).intValue(); 467 if (numRetries < 0) 468 { 469 throw new LDAPException(ResultCode.DECODING_ERROR, 470 ERR_TXN_SETTINGS_REQUEST_INVALID_RETRY_ATTEMPTS.get( 471 numRetries)); 472 } 473 break; 474 475 case TYPE_TXN_LOCK_TIMEOUT: 476 final ASN1Element[] timeoutElements = 477 ASN1Sequence.decodeAsSequence(e).elements(); 478 minTxnLockTimeout = 479 ASN1Long.decodeAsLong(timeoutElements[0]).longValue(); 480 maxTxnLockTimeout = 481 ASN1Long.decodeAsLong(timeoutElements[1]).longValue(); 482 if (minTxnLockTimeout < 0) 483 { 484 throw new LDAPException(ResultCode.DECODING_ERROR, 485 ERR_TXN_SETTINGS_REQUEST_INVALID_MIN_TXN_LOCK_TIMEOUT.get( 486 minTxnLockTimeout)); 487 } 488 if (maxTxnLockTimeout < minTxnLockTimeout) 489 { 490 throw new LDAPException(ResultCode.DECODING_ERROR, 491 ERR_TXN_SETTINGS_REQUEST_INVALID_MAX_TXN_LOCK_TIMEOUT.get( 492 maxTxnLockTimeout, minTxnLockTimeout)); 493 } 494 break; 495 496 case TYPE_RETURN_RESPONSE_CONTROL: 497 responseControl = ASN1Boolean.decodeAsBoolean(e).booleanValue(); 498 break; 499 500 default: 501 throw new LDAPException(ResultCode.DECODING_ERROR, 502 ERR_TXN_SETTINGS_REQUEST_UNRECOGNIZED_ELEMENT_TYPE.get( 503 StaticUtils.toHex(e.getType()))); 504 } 505 } 506 507 transactionName = txnName; 508 commitDurability = durability; 509 backendLockBehavior = lockBehavior; 510 backendLockTimeoutMillis = backendTimeout; 511 minTxnLockTimeoutMillis = minTxnLockTimeout; 512 maxTxnLockTimeoutMillis = maxTxnLockTimeout; 513 retryAttempts = numRetries; 514 returnResponseControl = responseControl; 515 } 516 catch (final LDAPException le) 517 { 518 Debug.debugException(le); 519 throw le; 520 } 521 catch (final Exception e) 522 { 523 Debug.debugException(e); 524 throw new LDAPException(ResultCode.DECODING_ERROR, 525 ERR_TXN_SETTINGS_REQUEST_ERROR_DECODING_VALUE.get( 526 StaticUtils.getExceptionMessage(e)), 527 e); 528 } 529 } 530 531 532 533 /** 534 * Encodes the provided information into a form suitable for use as the value 535 * of this ASN.1 element. 536 * 537 * @param transactionName The name to use for the transaction. It 538 * may be {@code null} if no 539 * client-specified transaction name is 540 * needed. If a transaction name is 541 * provided, it will be used purely for 542 * informational and/or troubleshooting 543 * purposes. 544 * @param commitDurability The durability level that should be used 545 * when committing the associated 546 * transaction. It may be {@code null} if 547 * the server-default durability level 548 * should be used. 549 * @param backendLockBehavior The behavior that should be used with 550 * regard to acquiring an exclusive lock for 551 * processing in the target backend. It may 552 * be {@code null} if the server-default 553 * backend lock behavior should be used. 554 * @param backendLockTimeoutMillis The maximum length of time in 555 * milliseconds to spend attempting to 556 * acquire an exclusive backend lock if it 557 * is needed during any part of the 558 * processing. A value that of zero 559 * indicates that no timeout should be 560 * enforced. It may be {@code null} if the 561 * server will determine the backend lock 562 * timeout that should be used. 563 * @param retryAttempts The number of times to retry the 564 * associated operations in a new 565 * transaction if the initial attempt fails. 566 * If this is {@code null}, then the server 567 * will determine the number of retry 568 * attempts to make. Note that depending on 569 * the backend lock behavior, the server may 570 * make one additional retry attempt if 571 * necessary after acquiring an exclusive 572 * backend lock. 573 * @param minTxnLockTimeoutMillis The minimum database lock timeout that 574 * should be used for the associated 575 * transaction. If this is specified, then 576 * the first attempt will use this lock 577 * timeout, and subsequent attempts will use 578 * a timeout value between this and the 579 * maximum database lock timeout (which must 580 * also be specified). If this is 581 * {@code null}, then the server will 582 * determine the database lock timeout 583 * settings to use. 584 * @param maxTxnLockTimeoutMillis The maximum database lock timeout that 585 * should be used for the associated 586 * transaction. If this is specified, then 587 * the minimum database lock timeout must 588 * also be specified, and this value must be 589 * greater than or equal to the minimum lock 590 * timeout. If this is {@code null}, then 591 * the server will determine the database 592 * lock timeout settings to use. 593 * @param returnResponseControl Indicates whether to return a response 594 * control with transaction-related 595 * information collected over the course of 596 * processing the associated operation. 597 * 598 * @return The encoded value to use for the control. 599 */ 600 @NotNull() 601 private static ASN1OctetString encodeValue( 602 @Nullable final String transactionName, 603 @Nullable final TransactionSettingsCommitDurability commitDurability, 604 @Nullable final TransactionSettingsBackendLockBehavior 605 backendLockBehavior, 606 @Nullable final Long backendLockTimeoutMillis, 607 @Nullable final Integer retryAttempts, 608 @Nullable final Long minTxnLockTimeoutMillis, 609 @Nullable final Long maxTxnLockTimeoutMillis, 610 final boolean returnResponseControl) 611 { 612 final ArrayList<ASN1Element> elements = new ArrayList<>(7); 613 614 if (transactionName != null) 615 { 616 elements.add(new ASN1OctetString(TYPE_TXN_NAME, transactionName)); 617 } 618 619 if (commitDurability != null) 620 { 621 elements.add(new ASN1Enumerated(TYPE_COMMIT_DURABILITY, 622 commitDurability.intValue())); 623 } 624 625 if (backendLockBehavior != null) 626 { 627 elements.add(new ASN1Enumerated(TYPE_BACKEND_LOCK_BEHAVIOR, 628 backendLockBehavior.intValue())); 629 } 630 631 if (backendLockTimeoutMillis != null) 632 { 633 Validator.ensureTrue((backendLockTimeoutMillis >= 0L), 634 "If a backend lock timeout is specified, then it must be greater " + 635 "than or equal to zero."); 636 elements.add(new ASN1Long(TYPE_BACKEND_LOCK_TIMEOUT, 637 backendLockTimeoutMillis)); 638 } 639 640 if (retryAttempts != null) 641 { 642 Validator.ensureTrue((retryAttempts >= 0), 643 "If specified, the number of retry attempts must be greater than " + 644 "or equal to zero."); 645 646 elements.add(new ASN1Integer(TYPE_RETRY_ATTEMPTS, retryAttempts)); 647 } 648 649 if (minTxnLockTimeoutMillis != null) 650 { 651 Validator.ensureTrue((maxTxnLockTimeoutMillis != null), 652 "If a minimum transaction lock timeout is specified, then a " + 653 "maximum transaction lock timeout must also be specified."); 654 Validator.ensureTrue((minTxnLockTimeoutMillis > 0), 655 "If a minimum transaction lock timeout is specified, then it must " + 656 "be greater than zero."); 657 Validator.ensureTrue((maxTxnLockTimeoutMillis >= minTxnLockTimeoutMillis), 658 "If a minimum transaction lock timeout is specified, then it must " + 659 "be less than or equal to the minimum transaction lock " + 660 "timeout."); 661 elements.add(new ASN1Sequence(TYPE_TXN_LOCK_TIMEOUT, 662 new ASN1Long(minTxnLockTimeoutMillis), 663 new ASN1Long(maxTxnLockTimeoutMillis))); 664 } 665 else 666 { 667 Validator.ensureTrue((maxTxnLockTimeoutMillis == null), 668 "If a maximum transaction lock timeout is specified, then a " + 669 "minimum transaction lock timeout must also be specified."); 670 } 671 672 if (returnResponseControl) 673 { 674 elements.add(new ASN1Boolean(TYPE_RETURN_RESPONSE_CONTROL, true)); 675 } 676 677 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 678 } 679 680 681 682 /** 683 * Retrieves the name to assign to the associated transaction, if specified. 684 * 685 * @return The name to assign to the associated transaction, or {@code null} 686 * if none has been specified. 687 */ 688 @Nullable() 689 public String getTransactionName() 690 { 691 return transactionName; 692 } 693 694 695 696 /** 697 * Retrieves the commit durability that should be used for the associated 698 * transaction, if specified. 699 * 700 * @return The commit durability that should be used for the associated 701 * transaction, or {@code null} if none has been specified and the 702 * server should determine the commit durability. 703 */ 704 @Nullable() 705 public TransactionSettingsCommitDurability getCommitDurability() 706 { 707 return commitDurability; 708 } 709 710 711 712 /** 713 * Retrieves the backend lock behavior that should be used for the associated 714 * transaction, if specified. 715 * 716 * @return The backend lock behavior that should be used for the associated 717 * transaction, or {@code null} if none has been specified and the 718 * server should determine the backend lock behavior. 719 */ 720 @Nullable() 721 public TransactionSettingsBackendLockBehavior getBackendLockBehavior() 722 { 723 return backendLockBehavior; 724 } 725 726 727 728 /** 729 * Retrieves the backend lock timeout (in milliseconds) that should be used 730 * for the associated transaction, if specified. 731 * 732 * @return The backend lock timeout (in milliseconds) that should be used for 733 * the associated transaction, or {@code null} if none has been 734 * specified and the server should determine the backend lock 735 * timeout. 736 */ 737 @Nullable() 738 public Long getBackendLockTimeoutMillis() 739 { 740 return backendLockTimeoutMillis; 741 } 742 743 744 745 /** 746 * Retrieves the maximum number of times that the transaction may be retried 747 * if the initial attempt fails due to a lock conflict, if specified. 748 * 749 * @return The maximum number of times that the transaction may be retried if 750 * the initial attempt fails due to a lock conflict, or {@code null} 751 * if none has been specified and the server should determine the 752 * number of retry attempts. 753 */ 754 @Nullable() 755 public Integer getRetryAttempts() 756 { 757 return retryAttempts; 758 } 759 760 761 762 /** 763 * Retrieves the minimum transaction lock timeout (in milliseconds) that 764 * should be used for the associated transaction, if specified. This is the 765 * timeout value that will be used for the first attempt. Any subsequent 766 * attempts will have a lock timeout that is between the minimum and maximum 767 * timeout value. 768 * 769 * @return The minimum lock timeout (in milliseconds) that should 770 * be used for the associated transaction, or {@code null} if none 771 * has been specified and the server should determine the minimum 772 * transaction lock timeout. 773 */ 774 @Nullable() 775 public Long getMinTxnLockTimeoutMillis() 776 { 777 return minTxnLockTimeoutMillis; 778 } 779 780 781 782 /** 783 * Retrieves the maximum transaction lock timeout (in milliseconds) that 784 * should be used for the associated transaction, if specified. The timeout 785 * to be used for any retries will be between the minimum and maximum lock 786 * timeout values. 787 * 788 * @return The maximum lock timeout (in milliseconds) that should 789 * be used for the associated transaction, or {@code null} if none 790 * has been specified and the server should determine the maximum 791 * transaction lock timeout. 792 */ 793 @Nullable() 794 public Long getMaxTxnLockTimeoutMillis() 795 { 796 return maxTxnLockTimeoutMillis; 797 } 798 799 800 801 /** 802 * Indicates whether to return a response control with transaction-related 803 * information collected over the course of processing the associated 804 * operation. 805 * 806 * @return {@code true} if the server should return a response control with 807 * transaction-related information, or {@code false} if not. 808 */ 809 public boolean returnResponseControl() 810 { 811 return returnResponseControl; 812 } 813 814 815 816 /** 817 * {@inheritDoc} 818 */ 819 @Override() 820 @NotNull() 821 public String getControlName() 822 { 823 return INFO_CONTROL_NAME_TXN_SETTINGS_REQUEST.get(); 824 } 825 826 827 828 /** 829 * {@inheritDoc} 830 */ 831 @Override() 832 public void toString(@NotNull final StringBuilder buffer) 833 { 834 buffer.append("TransactionSettingsRequestControl(isCritical="); 835 buffer.append(isCritical()); 836 837 if (transactionName != null) 838 { 839 buffer.append(", transactionName='"); 840 buffer.append(transactionName); 841 buffer.append('\''); 842 } 843 844 if (commitDurability != null) 845 { 846 buffer.append(", commitDurability='"); 847 buffer.append(commitDurability.name()); 848 buffer.append('\''); 849 } 850 851 if (backendLockBehavior != null) 852 { 853 buffer.append(", backendLockBehavior='"); 854 buffer.append(backendLockBehavior.name()); 855 buffer.append('\''); 856 } 857 858 if (backendLockTimeoutMillis != null) 859 { 860 buffer.append(", backendLockTimeoutMillis="); 861 buffer.append(backendLockTimeoutMillis); 862 } 863 864 if (retryAttempts != null) 865 { 866 buffer.append(", retryAttempts="); 867 buffer.append(retryAttempts); 868 } 869 870 if (minTxnLockTimeoutMillis != null) 871 { 872 buffer.append(", minTxnLockTimeoutMillis="); 873 buffer.append(minTxnLockTimeoutMillis); 874 } 875 876 if (maxTxnLockTimeoutMillis != null) 877 { 878 buffer.append(", maxTxnLockTimeoutMillis="); 879 buffer.append(maxTxnLockTimeoutMillis); 880 } 881 882 buffer.append(", returnResponseControl="); 883 buffer.append(returnResponseControl); 884 885 buffer.append(')'); 886 } 887}