001/* 002 * Copyright 2008-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2008-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) 2008-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.List; 041 042import com.unboundid.asn1.ASN1OctetString; 043import com.unboundid.ldap.sdk.Control; 044import com.unboundid.ldap.sdk.DecodeableControl; 045import com.unboundid.ldap.sdk.JSONControlDecodeHelper; 046import com.unboundid.ldap.sdk.LDAPException; 047import com.unboundid.ldap.sdk.LDAPResult; 048import com.unboundid.ldap.sdk.ResultCode; 049import com.unboundid.ldap.sdk.SearchResultEntry; 050import com.unboundid.ldap.sdk.SearchResultReference; 051import com.unboundid.util.NotMutable; 052import com.unboundid.util.NotNull; 053import com.unboundid.util.Nullable; 054import com.unboundid.util.ThreadSafety; 055import com.unboundid.util.ThreadSafetyLevel; 056import com.unboundid.util.Validator; 057import com.unboundid.util.json.JSONField; 058import com.unboundid.util.json.JSONObject; 059 060import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*; 061 062 063 064/** 065 * This class provides a response control that may be used to provide the server 066 * ID of the Directory Server instance that processed the associated request. 067 * For search operations, each entry and reference returned will include the 068 * server ID of the server that provided that entry or reference. For all other 069 * types of operations, it will be in the {@code LDAPResult} (or appropriate 070 * subclass) returned for that operation. 071 * <BR> 072 * <BLOCKQUOTE> 073 * <B>NOTE:</B> This class, and other classes within the 074 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 075 * supported for use against Ping Identity, UnboundID, and 076 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 077 * for proprietary functionality or for external specifications that are not 078 * considered stable or mature enough to be guaranteed to work in an 079 * interoperable way with other types of LDAP servers. 080 * </BLOCKQUOTE> 081 * <BR> 082 * This control has an OID of 1.3.6.1.4.1.30221.2.5.15 and a criticality of 083 * false. This control must have a value, which will simply be the string 084 * representation of the server ID of the associated server. 085 */ 086@NotMutable() 087@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 088public final class GetServerIDResponseControl 089 extends Control 090 implements DecodeableControl 091{ 092 /** 093 * The OID (1.3.6.1.4.1.30221.2.5.15) for the get server ID response control. 094 */ 095 @NotNull public static final String GET_SERVER_ID_RESPONSE_OID = 096 "1.3.6.1.4.1.30221.2.5.15"; 097 098 099 100 /** 101 * The name of the field used to hold the server ID in the JSON representation 102 * of this control. 103 */ 104 @NotNull private static final String JSON_FIELD_SERVER_ID = "server-id"; 105 106 107 /** 108 * The serial version UID for this serializable class. 109 */ 110 private static final long serialVersionUID = 5271084342514677677L; 111 112 113 114 // The server ID of the server that processed the associated request. 115 @NotNull private final String serverID; 116 117 118 119 /** 120 * Creates a new empty control instance that is intended to be used only for 121 * decoding controls via the {@code DecodeableControl} interface. 122 */ 123 GetServerIDResponseControl() 124 { 125 serverID = null; 126 } 127 128 129 130 /** 131 * Creates a new get server ID response control with the provided server ID. 132 * 133 * @param serverID The server ID of the server that processed the associated 134 * request. It must not be {@code null}. 135 */ 136 public GetServerIDResponseControl(@NotNull final String serverID) 137 { 138 super(GET_SERVER_ID_RESPONSE_OID, false, new ASN1OctetString(serverID)); 139 140 Validator.ensureNotNull(serverID); 141 142 this.serverID = serverID; 143 } 144 145 146 147 /** 148 * Creates a new get server ID response control decoded from the given generic 149 * control contents. 150 * 151 * @param oid The OID for the control. 152 * @param isCritical Indicates whether this control should be marked 153 * critical. 154 * @param value The value for the control. It may be {@code null} if 155 * the control to decode does not have a value. 156 * 157 * @throws LDAPException If a problem occurs while attempting to decode the 158 * generic control as a get server ID response 159 * control. 160 */ 161 public GetServerIDResponseControl(@NotNull final String oid, 162 final boolean isCritical, 163 @Nullable final ASN1OctetString value) 164 throws LDAPException 165 { 166 super(oid, isCritical, value); 167 168 if (value == null) 169 { 170 throw new LDAPException(ResultCode.DECODING_ERROR, 171 ERR_GET_SERVER_ID_RESPONSE_MISSING_VALUE.get()); 172 } 173 174 serverID = value.stringValue(); 175 } 176 177 178 179 /** 180 * {@inheritDoc} 181 */ 182 @Override() 183 @NotNull() 184 public GetServerIDResponseControl decodeControl(@NotNull final String oid, 185 final boolean isCritical, 186 @Nullable final ASN1OctetString value) 187 throws LDAPException 188 { 189 return new GetServerIDResponseControl(oid, isCritical, value); 190 } 191 192 193 194 /** 195 * Extracts a get server ID response control from the provided result. 196 * 197 * @param result The result from which to retrieve the get server ID 198 * response control. 199 * 200 * @return The get server ID response control contained in the provided 201 * result, or {@code null} if the result did not contain a get server 202 * ID response control. 203 * 204 * @throws LDAPException If a problem is encountered while attempting to 205 * decode the get server ID response control contained 206 * in the provided result. 207 */ 208 @Nullable() 209 public static GetServerIDResponseControl get(@NotNull final LDAPResult result) 210 throws LDAPException 211 { 212 final Control c = result.getResponseControl(GET_SERVER_ID_RESPONSE_OID); 213 if (c == null) 214 { 215 return null; 216 } 217 218 if (c instanceof GetServerIDResponseControl) 219 { 220 return (GetServerIDResponseControl) c; 221 } 222 else 223 { 224 return new GetServerIDResponseControl(c.getOID(), c.isCritical(), 225 c.getValue()); 226 } 227 } 228 229 230 231 /** 232 * Extracts a get server ID response control from the provided search result 233 * entry. 234 * 235 * @param entry The search result entry from which to retrieve the get 236 * server ID response control. 237 * 238 * @return The get server ID response control contained in the provided 239 * search result entry, or {@code null} if the entry did not contain 240 * a get server ID response control. 241 * 242 * @throws LDAPException If a problem is encountered while attempting to 243 * decode the get server ID response control contained 244 * in the provided entry. 245 */ 246 @Nullable() 247 public static GetServerIDResponseControl get( 248 @NotNull final SearchResultEntry entry) 249 throws LDAPException 250 { 251 final Control c = entry.getControl(GET_SERVER_ID_RESPONSE_OID); 252 if (c == null) 253 { 254 return null; 255 } 256 257 if (c instanceof GetServerIDResponseControl) 258 { 259 return (GetServerIDResponseControl) c; 260 } 261 else 262 { 263 return new GetServerIDResponseControl(c.getOID(), c.isCritical(), 264 c.getValue()); 265 } 266 } 267 268 269 270 /** 271 * Extracts a get server ID response control from the provided search result 272 * reference. 273 * 274 * @param ref The search result reference from which to retrieve the get 275 * server ID response control. 276 * 277 * @return The get server ID response control contained in the provided 278 * search result reference, or {@code null} if the reference did not 279 * contain a get server ID response control. 280 * 281 * @throws LDAPException If a problem is encountered while attempting to 282 * decode the get server ID response control contained 283 * in the provided reference. 284 */ 285 @Nullable() 286 public static GetServerIDResponseControl get( 287 @NotNull final SearchResultReference ref) 288 throws LDAPException 289 { 290 final Control c = ref.getControl(GET_SERVER_ID_RESPONSE_OID); 291 if (c == null) 292 { 293 return null; 294 } 295 296 if (c instanceof GetServerIDResponseControl) 297 { 298 return (GetServerIDResponseControl) c; 299 } 300 else 301 { 302 return new GetServerIDResponseControl(c.getOID(), c.isCritical(), 303 c.getValue()); 304 } 305 } 306 307 308 309 /** 310 * Retrieves the server ID of the server that actually processed the 311 * associated request. 312 * 313 * @return The server ID of the server that actually processed the associated 314 * request. 315 */ 316 @NotNull() 317 public String getServerID() 318 { 319 return serverID; 320 } 321 322 323 324 /** 325 * {@inheritDoc} 326 */ 327 @Override() 328 @NotNull() 329 public String getControlName() 330 { 331 return INFO_CONTROL_NAME_GET_SERVER_ID_RESPONSE.get(); 332 } 333 334 335 336 /** 337 * Retrieves a representation of this get server ID response control as a JSON 338 * object. The JSON object uses the following fields: 339 * <UL> 340 * <LI> 341 * {@code oid} -- A mandatory string field whose value is the object 342 * identifier for this control. For the get server ID response control, 343 * the OID is "1.3.6.1.4.1.30221.2.5.15". 344 * </LI> 345 * <LI> 346 * {@code control-name} -- An optional string field whose value is a 347 * human-readable name for this control. This field is only intended for 348 * descriptive purposes, and when decoding a control, the {@code oid} 349 * field should be used to identify the type of control. 350 * </LI> 351 * <LI> 352 * {@code criticality} -- A mandatory Boolean field used to indicate 353 * whether this control is considered critical. 354 * </LI> 355 * <LI> 356 * {@code value-base64} -- An optional string field whose value is a 357 * base64-encoded representation of the raw value for this get server ID 358 * response control. Exactly one of the {@code value-base64} and 359 * {@code value-json} fields must be present. 360 * </LI> 361 * <LI> 362 * {@code value-json} -- An optional JSON object field whose value is a 363 * user-friendly representation of the value for this get server ID 364 * response control. Exactly one of the {@code value-base64} and 365 * {@code value-json} fields must be present, and if the 366 * {@code value-json} field is used, then it will use the following 367 * fields: 368 * <UL> 369 * <LI> 370 * {@code server-id} -- A string field whose value is the server ID 371 * for the server that processed the operation or returned the entry. 372 * </LI> 373 * </UL> 374 * </LI> 375 * </UL> 376 * 377 * @return A JSON object that contains a representation of this control. 378 */ 379 @Override() 380 @NotNull() 381 public JSONObject toJSONControl() 382 { 383 return new JSONObject( 384 new JSONField(JSONControlDecodeHelper.JSON_FIELD_OID, 385 GET_SERVER_ID_RESPONSE_OID), 386 new JSONField(JSONControlDecodeHelper.JSON_FIELD_CONTROL_NAME, 387 INFO_CONTROL_NAME_GET_SERVER_ID_RESPONSE.get()), 388 new JSONField(JSONControlDecodeHelper.JSON_FIELD_CRITICALITY, 389 isCritical()), 390 new JSONField(JSONControlDecodeHelper.JSON_FIELD_VALUE_JSON, 391 new JSONObject( 392 new JSONField(JSON_FIELD_SERVER_ID, serverID)))); 393 } 394 395 396 397 /** 398 * Attempts to decode the provided object as a JSON representation of a get 399 * server ID response control. 400 * 401 * @param controlObject The JSON object to be decoded. It must not be 402 * {@code null}. 403 * @param strict Indicates whether to use strict mode when decoding 404 * the provided JSON object. If this is {@code true}, 405 * then this method will throw an exception if the 406 * provided JSON object contains any unrecognized 407 * fields. If this is {@code false}, then unrecognized 408 * fields will be ignored. 409 * 410 * @return The get server ID response control that was decoded from the 411 * provided JSON object. 412 * 413 * @throws LDAPException If the provided JSON object cannot be parsed as a 414 * valid get server ID response control. 415 */ 416 @NotNull() 417 public static GetServerIDResponseControl decodeJSONControl( 418 @NotNull final JSONObject controlObject, 419 final boolean strict) 420 throws LDAPException 421 { 422 final JSONControlDecodeHelper jsonControl = new JSONControlDecodeHelper( 423 controlObject, strict, true, true); 424 425 final ASN1OctetString rawValue = jsonControl.getRawValue(); 426 if (rawValue != null) 427 { 428 return new GetServerIDResponseControl(jsonControl.getOID(), 429 jsonControl.getCriticality(), rawValue); 430 } 431 432 433 final JSONObject valueObject = jsonControl.getValueObject(); 434 435 final String serverID = valueObject.getFieldAsString(JSON_FIELD_SERVER_ID); 436 if (serverID == null) 437 { 438 throw new LDAPException(ResultCode.DECODING_ERROR, 439 ERR_GET_SERVER_ID_RESPONSE_JSON_MISSING_SERVER_ID.get( 440 controlObject.toSingleLineString(), JSON_FIELD_SERVER_ID)); 441 } 442 443 444 if (strict) 445 { 446 final List<String> unrecognizedFields = 447 JSONControlDecodeHelper.getControlObjectUnexpectedFields( 448 valueObject, JSON_FIELD_SERVER_ID); 449 if (! unrecognizedFields.isEmpty()) 450 { 451 throw new LDAPException(ResultCode.DECODING_ERROR, 452 ERR_GET_SERVER_ID_RESPONSE_JSON_UNRECOGNIZED_FIELD.get( 453 controlObject.toSingleLineString(), 454 unrecognizedFields.get(0))); 455 } 456 } 457 458 459 return new GetServerIDResponseControl(serverID); 460 } 461 462 463 464 /** 465 * {@inheritDoc} 466 */ 467 @Override() 468 public void toString(@NotNull final StringBuilder buffer) 469 { 470 buffer.append("GetServerIDResponseControl(serverID='"); 471 buffer.append(serverID); 472 buffer.append("')"); 473 } 474}