001/* 002 * Copyright 2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2020 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) 2020 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.extensions; 037 038 039 040import com.unboundid.asn1.ASN1Element; 041import com.unboundid.asn1.ASN1Enumerated; 042import com.unboundid.asn1.ASN1OctetString; 043import com.unboundid.asn1.ASN1Sequence; 044import com.unboundid.ldap.sdk.Control; 045import com.unboundid.ldap.sdk.IntermediateResponse; 046import com.unboundid.ldap.sdk.LDAPException; 047import com.unboundid.ldap.sdk.ResultCode; 048import com.unboundid.util.Debug; 049import com.unboundid.util.NotMutable; 050import com.unboundid.util.StaticUtils; 051import com.unboundid.util.ThreadSafety; 052import com.unboundid.util.ThreadSafetyLevel; 053 054import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 055 056 057 058/** 059 * This class provides an implementation of an intermediate response that can 060 * provide the client with output from the collect-support-data tool in 061 * response to a {@link CollectSupportDataExtendedRequest}. 062 * <BR> 063 * <BLOCKQUOTE> 064 * <B>NOTE:</B> This class, and other classes within the 065 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 066 * supported for use against Ping Identity, UnboundID, and 067 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 068 * for proprietary functionality or for external specifications that are not 069 * considered stable or mature enough to be guaranteed to work in an 070 * interoperable way with other types of LDAP servers. 071 * </BLOCKQUOTE> 072 * <BR> 073 * The collect support data output intermediate response has an OID of 074 * 1.3.6.1.4.1.30221.2.6.65 and a value with the following encoding: 075 * <BR> 076 * <PRE> 077 * CollectSupportDataOutputIntermediateResponse ::= SEQUENCE { 078 * outputStream [0] ENUMERATED { 079 * standardOutput (0), 080 * standardError (1), 081 * ... }, 082 * outputMessage [1] OCTET STRING, 083 * ... } 084 * </PRE> 085 * 086 * @see CollectSupportDataExtendedRequest 087 * @see CollectSupportDataExtendedResult 088 * @see CollectSupportDataArchiveFragmentIntermediateResponse 089 */ 090@NotMutable() 091@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 092public final class CollectSupportDataOutputIntermediateResponse 093 extends IntermediateResponse 094{ 095 /** 096 * The OID (1.3.6.1.4.1.30221.2.6.65) for the collect support data output 097 * intermediate response. 098 */ 099 public static final String 100 COLLECT_SUPPORT_DATA_OUTPUT_INTERMEDIATE_RESPONSE_OID = 101 "1.3.6.1.4.1.30221.2.6.65"; 102 103 104 105 /** 106 * The BER type for the value element that specifies the output stream. 107 */ 108 private static final byte TYPE_OUTPUT_STREAM = (byte) 0x80; 109 110 111 112 /** 113 * The BER type for the value element that specifies the output message. 114 */ 115 private static final byte TYPE_OUTPUT_MESSAGE = (byte) 0x81; 116 117 118 119 /** 120 * The serial version UID for this serializable class. 121 */ 122 private static final long serialVersionUID = -2844901273280769861L; 123 124 125 126 // The output stream to which the message was written. 127 private final CollectSupportDataOutputStream outputStream; 128 129 // The output message that was written. 130 private final String outputMessage; 131 132 133 134 /** 135 * Creates a new collect support data output intermediate response with the 136 * provided information. 137 * 138 * @param outputStream The output stream to which the message was written. 139 * It must not be {@code null}. 140 * @param outputMessage The output message that was written by the tool. It 141 * must not be {@code null}. 142 * @param controls The set of controls to include in this intermediate 143 * response. It may be {@code null} or empty if no 144 * controls are needed. 145 */ 146 public CollectSupportDataOutputIntermediateResponse( 147 final CollectSupportDataOutputStream outputStream, 148 final String outputMessage, final Control... controls) 149 { 150 super(COLLECT_SUPPORT_DATA_OUTPUT_INTERMEDIATE_RESPONSE_OID, 151 encodeValue(outputStream, outputMessage), controls); 152 153 this.outputStream = outputStream; 154 this.outputMessage = outputMessage; 155 } 156 157 158 159 /** 160 * Constructs an ASN.1 octet string suitable for use as the value of this 161 * collect support data output intermediate response. 162 * 163 * @param outputStream The output stream to which the message was written. 164 * It must not be {@code null}. 165 * @param outputMessage The output message that was written by the tool. It 166 * must not be {@code null}. 167 * 168 * @return The ASN.1 octet string containing the encoded value. 169 */ 170 private static ASN1OctetString encodeValue( 171 final CollectSupportDataOutputStream outputStream, 172 final String outputMessage) 173 { 174 final ASN1Sequence valueSequence = new ASN1Sequence( 175 new ASN1Enumerated(TYPE_OUTPUT_STREAM, outputStream.getIntValue()), 176 new ASN1OctetString(TYPE_OUTPUT_MESSAGE, outputMessage)); 177 178 return new ASN1OctetString(valueSequence.encode()); 179 } 180 181 182 183 /** 184 * Creates a new collect support data output intermediate response that is 185 * decoded from the provided generic intermediate response. 186 * 187 * @param intermediateResponse The generic intermediate response to be 188 * decoded as a collect support data output 189 * intermediate response. It must not be 190 * {@code null}. 191 * 192 * @throws LDAPException If the provided intermediate response object cannot 193 * be decoded as a collect support data output 194 * intermediate response. 195 */ 196 public CollectSupportDataOutputIntermediateResponse( 197 final IntermediateResponse intermediateResponse) 198 throws LDAPException 199 { 200 super(intermediateResponse); 201 202 final ASN1OctetString value = intermediateResponse.getValue(); 203 if (value == null) 204 { 205 throw new LDAPException(ResultCode.DECODING_ERROR, 206 ERR_CSD_OUTPUT_IR_DECODE_NO_VALUE.get()); 207 } 208 209 try 210 { 211 final ASN1Sequence valueSequence = 212 ASN1Sequence.decodeAsSequence(value.getValue()); 213 final ASN1Element[] elements = valueSequence.elements(); 214 215 final int outputStreamIntValue = 216 ASN1Enumerated.decodeAsEnumerated(elements[0]).intValue(); 217 outputStream = CollectSupportDataOutputStream.forIntValue( 218 outputStreamIntValue); 219 if (outputStream == null) 220 { 221 throw new LDAPException(ResultCode.DECODING_ERROR, 222 ERR_CSD_OUTPUT_IR_DECODE_UNRECOGNIZED_OUTPUT_STREAM.get( 223 outputStreamIntValue)); 224 } 225 226 outputMessage = 227 ASN1OctetString.decodeAsOctetString(elements[1]).stringValue(); 228 } 229 catch (final LDAPException e) 230 { 231 Debug.debugException(e); 232 throw e; 233 } 234 catch (final Exception e) 235 { 236 Debug.debugException(e); 237 throw new LDAPException(ResultCode.DECODING_ERROR, 238 ERR_CSD_OUTPUT_IR_DECODE_ERROR.get( 239 StaticUtils.getExceptionMessage(e)), 240 e); 241 } 242 } 243 244 245 246 /** 247 * Retrieves the output stream to which the output message was written. 248 * 249 * @return The output stream to which the output was written. 250 */ 251 public CollectSupportDataOutputStream getOutputStream() 252 { 253 return outputStream; 254 } 255 256 257 258 /** 259 * Retrieves the output message that was written. 260 * 261 * @return The output message that was written. 262 */ 263 public String getOutputMessage() 264 { 265 return outputMessage; 266 } 267 268 269 270 /** 271 * {@inheritDoc} 272 */ 273 @Override() 274 public String getIntermediateResponseName() 275 { 276 return INFO_COLLECT_SUPPORT_DATA_OUTPUT_IR_NAME.get(); 277 } 278 279 280 281 /** 282 * {@inheritDoc} 283 */ 284 @Override() 285 public String valueToString() 286 { 287 final StringBuilder buffer = new StringBuilder(); 288 289 buffer.append("outputStream='"); 290 buffer.append(outputStream.getName()); 291 buffer.append("' outputMessage='"); 292 buffer.append(outputMessage); 293 buffer.append('\''); 294 295 return buffer.toString(); 296 } 297 298 299 300 /** 301 * {@inheritDoc} 302 */ 303 @Override() 304 public void toString(final StringBuilder buffer) 305 { 306 buffer.append("CollectSupportDataOutputIntermediateResponse(oid='"); 307 buffer.append(getOID()); 308 buffer.append("', outputStream='"); 309 buffer.append(outputStream.getName()); 310 buffer.append("', outputMessage='"); 311 buffer.append(outputMessage); 312 buffer.append('\''); 313 314 final Control[] controls = getControls(); 315 if (controls.length > 0) 316 { 317 buffer.append(", controls={"); 318 for (int i=0; i < controls.length; i++) 319 { 320 if (i > 0) 321 { 322 buffer.append(", "); 323 } 324 325 buffer.append(controls[i]); 326 } 327 buffer.append('}'); 328 } 329 330 buffer.append(')'); 331 } 332}