001/* 002 * Copyright 2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 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) 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.forgerockds.controls; 037 038 039 040import com.unboundid.asn1.ASN1OctetString; 041import com.unboundid.ldap.sdk.Control; 042import com.unboundid.ldap.sdk.LDAPException; 043import com.unboundid.ldap.sdk.ResultCode; 044import com.unboundid.util.NotMutable; 045import com.unboundid.util.NotNull; 046import com.unboundid.util.StaticUtils; 047import com.unboundid.util.ThreadSafety; 048import com.unboundid.util.ThreadSafetyLevel; 049 050import static com.unboundid.ldap.sdk.forgerockds.controls.ControlMessages.*; 051 052 053 054/** 055 * This class provides an implementation of a control that can be used to 056 * establish an affinity for one or more operations through a ForgeRock 057 * Directory Proxy Server. The server will attempt to route operations with 058 * the same affinity value to the same backend server. 059 * <BR> 060 * This request control has an OID of 1.3.6.1.4.1.36733.2.1.5.2, and its value 061 * is the desired affinity value (which may be an arbitrary string or set of 062 * bytes, and the LDAP SDK may automatically generate an affinity value if none 063 * is provided). The criticality may be either true or false. 064 */ 065@NotMutable() 066@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 067public final class AffinityRequestControl 068 extends Control 069{ 070 /** 071 * The OID (1.3.6.1.4.1.36733.2.1.5.2) for the affinity request control. 072 */ 073 @NotNull public static final String AFFINITY_REQUEST_OID = 074 "1.3.6.1.4.1.36733.2.1.5.2"; 075 076 077 078 /** 079 * The serial version UID for this serializable class. 080 */ 081 private static final long serialVersionUID = 7792760251213801179L; 082 083 084 085 // The affinity value to use for this control. 086 @NotNull private final ASN1OctetString affinityValue; 087 088 089 090 /** 091 * Creates a new affinity request control with the specified criticality and 092 * a randomly generated affinity value. 093 * 094 * @param isCritical Indicates whether the control should be marked 095 * critical. 096 */ 097 public AffinityRequestControl(final boolean isCritical) 098 { 099 this(isCritical, new ASN1OctetString(StaticUtils.randomBytes(5, true))); 100 } 101 102 103 104 /** 105 * Creates a new affinity request control with the specified criticality and 106 * the provided affinity value. 107 * 108 * @param isCritical Indicates whether the control should be marked 109 * critical. 110 * @param affinityValue The affinity value to use for the control. It must 111 * not be {@code null}. 112 */ 113 public AffinityRequestControl(final boolean isCritical, 114 @NotNull final String affinityValue) 115 { 116 this(isCritical, new ASN1OctetString(affinityValue)); 117 } 118 119 120 121 /** 122 * Creates a new affinity request control with the specified criticality and 123 * the provided affinity value. 124 * 125 * @param isCritical Indicates whether the control should be marked 126 * critical. 127 * @param affinityValue The affinity value to use for the control. It must 128 * not be {@code null}. 129 */ 130 public AffinityRequestControl(final boolean isCritical, 131 @NotNull final byte[] affinityValue) 132 { 133 this(isCritical, new ASN1OctetString(affinityValue)); 134 } 135 136 137 138 /** 139 * Creates a new affinity request control with the specified criticality and 140 * the provided affinity value. 141 * 142 * @param isCritical Indicates whether the control should be marked 143 * critical. 144 * @param affinityValue The affinity value to use for the control. It must 145 * not be {@code null}. 146 */ 147 public AffinityRequestControl(final boolean isCritical, 148 @NotNull final ASN1OctetString affinityValue) 149 { 150 super(AFFINITY_REQUEST_OID, isCritical, affinityValue); 151 152 this.affinityValue = affinityValue; 153 } 154 155 156 157 /** 158 * Creates a new affinity request control that is decoded from 159 * the provided generic control. 160 * 161 * @param control The generic control to be decoded as an affinity request 162 * control. 163 * 164 * @throws LDAPException If the provided control cannot be decoded as an 165 * affinity request control. 166 */ 167 public AffinityRequestControl(@NotNull final Control control) 168 throws LDAPException 169 { 170 super(control); 171 172 affinityValue = control.getValue(); 173 if (affinityValue == null) 174 { 175 throw new LDAPException(ResultCode.DECODING_ERROR, 176 ERR_AFFINITY_REQUEST_MISSING_VALUE.get()); 177 } 178 } 179 180 181 182 /** 183 * Retrieves the affinity value for this control. 184 * 185 * @return The affinity value for this control. 186 */ 187 @NotNull() 188 public ASN1OctetString getAffinityValue() 189 { 190 return affinityValue; 191 } 192 193 194 195 /** 196 * {@inheritDoc} 197 */ 198 @Override() 199 @NotNull() 200 public String getControlName() 201 { 202 return INFO_CONTROL_NAME_AFFINITY_REQUEST.get(); 203 } 204 205 206 207 /** 208 * {@inheritDoc} 209 */ 210 @Override() 211 public void toString(@NotNull final StringBuilder buffer) 212 { 213 buffer.append("AffinityRequestControl("); 214 215 final byte[] affinityValueBytes = affinityValue.getValue(); 216 if (StaticUtils.isLikelyDisplayableUTF8String(affinityValueBytes)) 217 { 218 buffer.append("affinityValueString='"); 219 buffer.append(affinityValue.stringValue()); 220 } 221 else 222 { 223 buffer.append("affinityValueBytes='"); 224 StaticUtils.toHex(affinityValueBytes, buffer); 225 } 226 227 buffer.append("')"); 228 } 229}