001/* 002 * Copyright 2013-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2018 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk.unboundidds.controls; 022 023 024 025import java.io.Serializable; 026import java.util.ArrayList; 027 028import com.unboundid.asn1.ASN1Element; 029import com.unboundid.asn1.ASN1Enumerated; 030import com.unboundid.asn1.ASN1Integer; 031import com.unboundid.asn1.ASN1Sequence; 032import com.unboundid.ldap.sdk.LDAPException; 033import com.unboundid.ldap.sdk.ResultCode; 034import com.unboundid.util.Debug; 035import com.unboundid.util.NotMutable; 036import com.unboundid.util.StaticUtils; 037import com.unboundid.util.ThreadSafety; 038import com.unboundid.util.ThreadSafetyLevel; 039 040import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*; 041 042 043 044/** 045 * This class defines a data structure that provides information about the 046 * result of assured replication processing, either on a replication server (if 047 * that is all that is needed to satisfy the desired level of assurance) or 048 * on a directory server (if required by the desired level of assurance). 049 * <BR> 050 * <BLOCKQUOTE> 051 * <B>NOTE:</B> This class, and other classes within the 052 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 053 * supported for use against Ping Identity, UnboundID, and 054 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 055 * for proprietary functionality or for external specifications that are not 056 * considered stable or mature enough to be guaranteed to work in an 057 * interoperable way with other types of LDAP servers. 058 * </BLOCKQUOTE> 059 */ 060@NotMutable() 061@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 062public final class AssuredReplicationServerResult 063 implements Serializable 064{ 065 /** 066 * The BER type for the result code element. 067 */ 068 private static final byte TYPE_RESULT_CODE = (byte) 0x80; 069 070 071 /** 072 * The BER type for the server ID element. 073 */ 074 private static final byte TYPE_SERVER_ID = (byte) 0x81; 075 076 077 /** 078 * The BER type for the replica ID element. 079 */ 080 private static final byte TYPE_REPLICA_ID = (byte) 0x82; 081 082 083 084 /** 085 * The serial version UID for this serializable class. 086 */ 087 private static final long serialVersionUID = 3015162215769386343L; 088 089 090 091 // The result code for this server result. 092 private final AssuredReplicationServerResultCode resultCode; 093 094 // The replica ID of the associated directory server. 095 private final Short replicaID; 096 097 // The server ID of the associated replication server. 098 private final Short replicationServerID; 099 100 101 102 /** 103 * Creates a new assured replication server result with the provided 104 * information. 105 * 106 * @param resultCode The result code that indicates the state of 107 * assurance processing for the associated 108 * replication server and/or directory server. 109 * It must not be {@code null}. 110 * @param replicationServerID The server ID of the replication server from 111 * which this server result was obtained. It may 112 * be {@code null} if no replication server ID is 113 * available for this result. 114 * @param replicaID The replica ID of the directory server with 115 * which this result is associated. It may be 116 * {@code null} if no replica ID is available 117 * for this result. 118 */ 119 public AssuredReplicationServerResult( 120 final AssuredReplicationServerResultCode resultCode, 121 final Short replicationServerID, 122 final Short replicaID) 123 { 124 this.resultCode = resultCode; 125 this.replicationServerID = replicationServerID; 126 this.replicaID = replicaID; 127 } 128 129 130 131 /** 132 * Retrieves the result code that indicates the state of assurance processing 133 * for this server result. 134 * 135 * @return The result code for this server result. 136 */ 137 public AssuredReplicationServerResultCode getResultCode() 138 { 139 return resultCode; 140 } 141 142 143 144 /** 145 * Retrieves the server ID for the replication server from which this server 146 * result was obtained, if available. 147 * 148 * @return The server ID for the replication server from which this server 149 * result was obtained, or {@code null} if no replication server ID 150 * is available. 151 */ 152 public Short getReplicationServerID() 153 { 154 return replicationServerID; 155 } 156 157 158 159 /** 160 * Retrieves the replica ID for the directory server with which this server 161 * result is associated, if applicable. 162 * 163 * @return The replica ID for the directory server with which this server 164 * result is associated, or {@code null} if there is no associated 165 * directory server. 166 */ 167 public Short getReplicaID() 168 { 169 return replicaID; 170 } 171 172 173 174 /** 175 * Encodes this assured replication server result to an ASN.1 element suitable 176 * for use in a {@link AssuredReplicationResponseControl}. 177 * 178 * @return The encoded representation of this assured replication server 179 * result. 180 */ 181 ASN1Element encode() 182 { 183 final ArrayList<ASN1Element> elements = new ArrayList<>(3); 184 185 elements.add(new ASN1Enumerated(TYPE_RESULT_CODE, resultCode.intValue())); 186 187 if (replicationServerID != null) 188 { 189 elements.add(new ASN1Integer(TYPE_SERVER_ID, replicationServerID)); 190 } 191 192 if (replicaID != null) 193 { 194 elements.add(new ASN1Integer(TYPE_REPLICA_ID, replicaID)); 195 } 196 197 return new ASN1Sequence(elements); 198 } 199 200 201 202 /** 203 * Decodes the provided ASN.1 element as an assured replication server 204 * result. 205 * 206 * @param element The ASN.1 element to be decoded. It must not be 207 * {@code null}. 208 * 209 * @return The decoded assured replication server result. 210 * 211 * @throws LDAPException If a problem is encountered while attempting to 212 * decode the provided ASN.1 element as an assured 213 * replication server result. 214 */ 215 static AssuredReplicationServerResult decode(final ASN1Element element) 216 throws LDAPException 217 { 218 AssuredReplicationServerResultCode resultCode = null; 219 Short serverID = null; 220 Short replicaID = null; 221 222 try 223 { 224 for (final ASN1Element e : 225 ASN1Sequence.decodeAsSequence(element).elements()) 226 { 227 switch (e.getType()) 228 { 229 case TYPE_RESULT_CODE: 230 final int rcValue = ASN1Enumerated.decodeAsEnumerated(e).intValue(); 231 resultCode = AssuredReplicationServerResultCode.valueOf(rcValue); 232 if (resultCode == null) 233 { 234 throw new LDAPException(ResultCode.DECODING_ERROR, 235 ERR_ASSURED_REPLICATION_SERVER_RESULT_INVALID_RESULT_CODE. 236 get(rcValue)); 237 } 238 break; 239 240 case TYPE_SERVER_ID: 241 serverID = (short) ASN1Integer.decodeAsInteger(e).intValue(); 242 break; 243 244 case TYPE_REPLICA_ID: 245 replicaID = (short) ASN1Integer.decodeAsInteger(e).intValue(); 246 break; 247 248 default: 249 throw new LDAPException(ResultCode.DECODING_ERROR, 250 ERR_ASSURED_REPLICATION_SERVER_RESULT_UNEXPECTED_ELEMENT_TYPE. 251 get(StaticUtils.toHex(e.getType()))); 252 } 253 } 254 } 255 catch (final LDAPException le) 256 { 257 Debug.debugException(le); 258 throw le; 259 } 260 catch (final Exception e) 261 { 262 Debug.debugException(e); 263 throw new LDAPException(ResultCode.DECODING_ERROR, 264 ERR_ASSURED_REPLICATION_SERVER_RESULT_CANNOT_DECODE.get( 265 StaticUtils.getExceptionMessage(e)), 266 e); 267 } 268 269 if (resultCode == null) 270 { 271 throw new LDAPException(ResultCode.DECODING_ERROR, 272 ERR_ASSURED_REPLICATION_SERVER_RESULT_NO_RESULT_CODE.get()); 273 } 274 275 return new AssuredReplicationServerResult(resultCode, serverID, replicaID); 276 } 277 278 279 280 /** 281 * Retrieves a string representation of this assured replication server 282 * result. 283 * 284 * @return A string representation of this assured replication server 285 * result. 286 */ 287 @Override() 288 public String toString() 289 { 290 final StringBuilder buffer = new StringBuilder(); 291 toString(buffer); 292 return buffer.toString(); 293 } 294 295 296 297 /** 298 * Appends a string representation of this assured replication server result 299 * to the provided buffer. 300 * 301 * @param buffer The buffer to which the information should be appended. 302 */ 303 public void toString(final StringBuilder buffer) 304 { 305 buffer.append("AssuredReplicationServerResult(resultCode="); 306 buffer.append(resultCode.name()); 307 308 if (replicationServerID != null) 309 { 310 buffer.append(", replicationServerID="); 311 buffer.append(replicationServerID); 312 } 313 314 if (replicaID != null) 315 { 316 buffer.append(", replicaID="); 317 buffer.append(replicaID); 318 } 319 320 buffer.append(')'); 321 } 322}