001/* 002 * Copyright 2013-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2013-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) 2013-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.io.Serializable; 041import java.util.ArrayList; 042 043import com.unboundid.asn1.ASN1Element; 044import com.unboundid.asn1.ASN1Enumerated; 045import com.unboundid.asn1.ASN1Integer; 046import com.unboundid.asn1.ASN1Sequence; 047import com.unboundid.ldap.sdk.LDAPException; 048import com.unboundid.ldap.sdk.ResultCode; 049import com.unboundid.util.Debug; 050import com.unboundid.util.NotMutable; 051import com.unboundid.util.NotNull; 052import com.unboundid.util.Nullable; 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 defines a data structure that provides information about the 063 * result of assured replication processing, either on a replication server (if 064 * that is all that is needed to satisfy the desired level of assurance) or 065 * on a directory server (if required by the desired level of assurance). 066 * <BR> 067 * <BLOCKQUOTE> 068 * <B>NOTE:</B> This class, and other classes within the 069 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 070 * supported for use against Ping Identity, UnboundID, and 071 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 072 * for proprietary functionality or for external specifications that are not 073 * considered stable or mature enough to be guaranteed to work in an 074 * interoperable way with other types of LDAP servers. 075 * </BLOCKQUOTE> 076 */ 077@NotMutable() 078@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 079public final class AssuredReplicationServerResult 080 implements Serializable 081{ 082 /** 083 * The BER type for the result code element. 084 */ 085 private static final byte TYPE_RESULT_CODE = (byte) 0x80; 086 087 088 /** 089 * The BER type for the server ID element. 090 */ 091 private static final byte TYPE_SERVER_ID = (byte) 0x81; 092 093 094 /** 095 * The BER type for the replica ID element. 096 */ 097 private static final byte TYPE_REPLICA_ID = (byte) 0x82; 098 099 100 101 /** 102 * The serial version UID for this serializable class. 103 */ 104 private static final long serialVersionUID = 3015162215769386343L; 105 106 107 108 // The result code for this server result. 109 @NotNull private final AssuredReplicationServerResultCode resultCode; 110 111 // The replica ID of the associated directory server. 112 @Nullable private final Short replicaID; 113 114 // The server ID of the associated replication server. 115 @Nullable private final Short replicationServerID; 116 117 118 119 /** 120 * Creates a new assured replication server result with the provided 121 * information. 122 * 123 * @param resultCode The result code that indicates the state of 124 * assurance processing for the associated 125 * replication server and/or directory server. 126 * It must not be {@code null}. 127 * @param replicationServerID The server ID of the replication server from 128 * which this server result was obtained. It may 129 * be {@code null} if no replication server ID is 130 * available for this result. 131 * @param replicaID The replica ID of the directory server with 132 * which this result is associated. It may be 133 * {@code null} if no replica ID is available 134 * for this result. 135 */ 136 public AssuredReplicationServerResult( 137 @NotNull final AssuredReplicationServerResultCode resultCode, 138 @Nullable final Short replicationServerID, 139 @Nullable final Short replicaID) 140 { 141 this.resultCode = resultCode; 142 this.replicationServerID = replicationServerID; 143 this.replicaID = replicaID; 144 } 145 146 147 148 /** 149 * Retrieves the result code that indicates the state of assurance processing 150 * for this server result. 151 * 152 * @return The result code for this server result. 153 */ 154 @NotNull() 155 public AssuredReplicationServerResultCode getResultCode() 156 { 157 return resultCode; 158 } 159 160 161 162 /** 163 * Retrieves the server ID for the replication server from which this server 164 * result was obtained, if available. 165 * 166 * @return The server ID for the replication server from which this server 167 * result was obtained, or {@code null} if no replication server ID 168 * is available. 169 */ 170 @Nullable() 171 public Short getReplicationServerID() 172 { 173 return replicationServerID; 174 } 175 176 177 178 /** 179 * Retrieves the replica ID for the directory server with which this server 180 * result is associated, if applicable. 181 * 182 * @return The replica ID for the directory server with which this server 183 * result is associated, or {@code null} if there is no associated 184 * directory server. 185 */ 186 @Nullable() 187 public Short getReplicaID() 188 { 189 return replicaID; 190 } 191 192 193 194 /** 195 * Encodes this assured replication server result to an ASN.1 element suitable 196 * for use in a {@link AssuredReplicationResponseControl}. 197 * 198 * @return The encoded representation of this assured replication server 199 * result. 200 */ 201 @NotNull() 202 ASN1Element encode() 203 { 204 final ArrayList<ASN1Element> elements = new ArrayList<>(3); 205 206 elements.add(new ASN1Enumerated(TYPE_RESULT_CODE, resultCode.intValue())); 207 208 if (replicationServerID != null) 209 { 210 elements.add(new ASN1Integer(TYPE_SERVER_ID, replicationServerID)); 211 } 212 213 if (replicaID != null) 214 { 215 elements.add(new ASN1Integer(TYPE_REPLICA_ID, replicaID)); 216 } 217 218 return new ASN1Sequence(elements); 219 } 220 221 222 223 /** 224 * Decodes the provided ASN.1 element as an assured replication server 225 * result. 226 * 227 * @param element The ASN.1 element to be decoded. It must not be 228 * {@code null}. 229 * 230 * @return The decoded assured replication server result. 231 * 232 * @throws LDAPException If a problem is encountered while attempting to 233 * decode the provided ASN.1 element as an assured 234 * replication server result. 235 */ 236 @NotNull() 237 static AssuredReplicationServerResult decode( 238 @NotNull final ASN1Element element) 239 throws LDAPException 240 { 241 AssuredReplicationServerResultCode resultCode = null; 242 Short serverID = null; 243 Short replicaID = null; 244 245 try 246 { 247 for (final ASN1Element e : 248 ASN1Sequence.decodeAsSequence(element).elements()) 249 { 250 switch (e.getType()) 251 { 252 case TYPE_RESULT_CODE: 253 final int rcValue = ASN1Enumerated.decodeAsEnumerated(e).intValue(); 254 resultCode = AssuredReplicationServerResultCode.valueOf(rcValue); 255 if (resultCode == null) 256 { 257 throw new LDAPException(ResultCode.DECODING_ERROR, 258 ERR_ASSURED_REPLICATION_SERVER_RESULT_INVALID_RESULT_CODE. 259 get(rcValue)); 260 } 261 break; 262 263 case TYPE_SERVER_ID: 264 serverID = (short) ASN1Integer.decodeAsInteger(e).intValue(); 265 break; 266 267 case TYPE_REPLICA_ID: 268 replicaID = (short) ASN1Integer.decodeAsInteger(e).intValue(); 269 break; 270 271 default: 272 throw new LDAPException(ResultCode.DECODING_ERROR, 273 ERR_ASSURED_REPLICATION_SERVER_RESULT_UNEXPECTED_ELEMENT_TYPE. 274 get(StaticUtils.toHex(e.getType()))); 275 } 276 } 277 } 278 catch (final LDAPException le) 279 { 280 Debug.debugException(le); 281 throw le; 282 } 283 catch (final Exception e) 284 { 285 Debug.debugException(e); 286 throw new LDAPException(ResultCode.DECODING_ERROR, 287 ERR_ASSURED_REPLICATION_SERVER_RESULT_CANNOT_DECODE.get( 288 StaticUtils.getExceptionMessage(e)), 289 e); 290 } 291 292 if (resultCode == null) 293 { 294 throw new LDAPException(ResultCode.DECODING_ERROR, 295 ERR_ASSURED_REPLICATION_SERVER_RESULT_NO_RESULT_CODE.get()); 296 } 297 298 return new AssuredReplicationServerResult(resultCode, serverID, replicaID); 299 } 300 301 302 303 /** 304 * Retrieves a string representation of this assured replication server 305 * result. 306 * 307 * @return A string representation of this assured replication server 308 * result. 309 */ 310 @Override() 311 @NotNull() 312 public String toString() 313 { 314 final StringBuilder buffer = new StringBuilder(); 315 toString(buffer); 316 return buffer.toString(); 317 } 318 319 320 321 /** 322 * Appends a string representation of this assured replication server result 323 * to the provided buffer. 324 * 325 * @param buffer The buffer to which the information should be appended. 326 */ 327 public void toString(@NotNull final StringBuilder buffer) 328 { 329 buffer.append("AssuredReplicationServerResult(resultCode="); 330 buffer.append(resultCode.name()); 331 332 if (replicationServerID != null) 333 { 334 buffer.append(", replicationServerID="); 335 buffer.append(replicationServerID); 336 } 337 338 if (replicaID != null) 339 { 340 buffer.append(", replicaID="); 341 buffer.append(replicaID); 342 } 343 344 buffer.append(')'); 345 } 346}