001/* 002 * Copyright 2020-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2020-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) 2020-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.extensions; 037 038 039 040import java.util.Date; 041 042import com.unboundid.asn1.ASN1Element; 043import com.unboundid.asn1.ASN1OctetString; 044import com.unboundid.asn1.ASN1Sequence; 045import com.unboundid.ldap.sdk.LDAPException; 046import com.unboundid.ldap.sdk.ResultCode; 047import com.unboundid.util.Debug; 048import com.unboundid.util.NotMutable; 049import com.unboundid.util.NotNull; 050import com.unboundid.util.Nullable; 051import com.unboundid.util.StaticUtils; 052import com.unboundid.util.ThreadSafety; 053import com.unboundid.util.ThreadSafetyLevel; 054import com.unboundid.util.Validator; 055 056import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 057 058 059 060/** 061 * This class provides a collect support data log capture window implementation 062 * that indicates that the tool should capture information for a specified 063 * window of time (between start and end times, inclusive) when processing a 064 * {@link CollectSupportDataExtendedRequest}. 065 * <BR> 066 * <BLOCKQUOTE> 067 * <B>NOTE:</B> This class, and other classes within the 068 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 069 * supported for use against Ping Identity, UnboundID, and 070 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 071 * for proprietary functionality or for external specifications that are not 072 * considered stable or mature enough to be guaranteed to work in an 073 * interoperable way with other types of LDAP servers. 074 * </BLOCKQUOTE> 075 * 076 * @see CollectSupportDataExtendedRequest 077 */ 078@NotMutable() 079@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 080public final class TimeWindowCollectSupportDataLogCaptureWindow 081 extends CollectSupportDataLogCaptureWindow 082{ 083 /** 084 * The serial version UID for this serializable class. 085 */ 086 private static final long serialVersionUID = -989944420134047411L; 087 088 089 090 // An ASN.1 element that provides an encoded representation of this time 091 // window collect support data log capture window. 092 @NotNull private final ASN1Element encodedWindow; 093 094 // The end time for the window. 095 @Nullable private final Long endTimeMillis; 096 097 // The start time for the window. 098 private final long startTimeMillis; 099 100 101 102 /** 103 * Creates a new instance of this collect support data log capture window 104 * object that will capture log content within the specified window of time. 105 * 106 * @param startTime The time of the oldest log messages to include in the 107 * support data archive. It must be non-{@code null}, and 108 * it must represent a time no earlier than midnight on 109 * January 1, 1970, UTC. 110 * @param endTime The time of the most recent log messages to include in 111 * the support data archive. This may be {@code null} if 112 * the end time should be set to the time the 113 * {@link CollectSupportDataExtendedRequest} was 114 * received by the server. If it is non-{@code null}, then 115 * it must represent a time no earlier than the provided 116 * start time. 117 */ 118 public TimeWindowCollectSupportDataLogCaptureWindow( 119 @NotNull final Date startTime, 120 @Nullable final Date endTime) 121 { 122 this(startTime.getTime(), (endTime == null ? null : endTime.getTime())); 123 } 124 125 126 127 /** 128 * Creates a new instance of this collect support data log capture window 129 * object that will capture log content within the specified window of time. 130 * 131 * @param startTimeMillis The time of the oldest log messages to include in 132 * the support data archive, represented as the 133 * number of milliseconds since midnight on January 134 * 1, 1970, UTC (i.e., the format used by 135 * {@code System.currentTimeMillis()} and 136 * {@code Date.getTime()}). 137 * @param endTimeMillis The time of the most recent log messages to 138 * include in the support data archive, represented 139 * as the number of milliseconds since midnight on 140 * January 1, 1970, UTC. This may be {@code null} if 141 * the end time should be set to the time the 142 * {@link CollectSupportDataExtendedRequest} was 143 * received by the server. If it is 144 * non-{@code null}, then it must be greater than or 145 * equal to the provided start time. 146 */ 147 public TimeWindowCollectSupportDataLogCaptureWindow( 148 final long startTimeMillis, @Nullable final Long endTimeMillis) 149 { 150 Validator.ensureTrue((startTimeMillis > 0), 151 "TimeWindowCollectSupportDataLogCaptureWindow.startTimeMillis must " + 152 "be greater than zero."); 153 if (endTimeMillis != null) 154 { 155 Validator.ensureTrue((endTimeMillis >= startTimeMillis), 156 "If it is provided, then" + 157 "TimeWindowCollectSupportDataLogCaptureWindow.endTime must " + 158 "greater than or equal to " + 159 "TimeWindowCollectSupportDataLogCaptureWindow.endTime."); 160 } 161 162 this.startTimeMillis = startTimeMillis; 163 this.endTimeMillis = endTimeMillis; 164 165 if (endTimeMillis == null) 166 { 167 encodedWindow = new ASN1Sequence(TYPE_TIME_WINDOW, 168 new ASN1OctetString(StaticUtils.encodeGeneralizedTime( 169 startTimeMillis))); 170 } 171 else 172 { 173 encodedWindow = new ASN1Sequence(TYPE_TIME_WINDOW, 174 new ASN1OctetString(StaticUtils.encodeGeneralizedTime( 175 startTimeMillis)), 176 new ASN1OctetString(StaticUtils.encodeGeneralizedTime( 177 endTimeMillis))); 178 } 179 } 180 181 182 183 /** 184 * Retrieves the time of the oldest log messages to include in the support 185 * data archive. 186 * 187 * @return The time of the oldest log messages to include in the support data 188 * archive. 189 */ 190 @NotNull() 191 public Date getStartTime() 192 { 193 return new Date(startTimeMillis); 194 } 195 196 197 198 /** 199 * Retrieves the time of the oldest log messages to include in the support 200 * data archive, represented as the number of milliseconds since midnight on 201 * January 1, 1970, UTC (i.e., the format used by 202 * {@code System.currentTimeMillis()} and {@code Date.getTime()}). 203 * 204 * @return The time of the oldest log messages to include in the support data 205 * archive, represented as the number of milliseconds since midnight 206 * on January 1, 1970, UTC. 207 */ 208 public long getStartTimeMillis() 209 { 210 return startTimeMillis; 211 } 212 213 214 215 /** 216 * Retrieves the time of the most recent log messages to include in the 217 * support data archive, if specified. 218 * 219 * @return The time of the most recent log messages to include in the 220 * support data archive, or {@code null} if the end time should be 221 * set to the time the {@link CollectSupportDataExtendedRequest} was 222 * received by the server. 223 */ 224 @Nullable() 225 public Date getEndTime() 226 { 227 if (endTimeMillis == null) 228 { 229 return null; 230 } 231 else 232 { 233 return new Date(endTimeMillis); 234 } 235 } 236 237 238 239 /** 240 * Retrieves the time of the most recent log messages to include in the 241 * support data archive, if specified. The value will represent the number of 242 * milliseconds since midnight on January 1, 1970, UTC (i.e., the format used 243 * by {@code System.currentTimeMillis()} and {@code Date.getTime()}). 244 * 245 * @return The time of the most recent log messages to include in the 246 * support data archive, or {@code null} if the end time should be 247 * set to the time the {@link CollectSupportDataExtendedRequest} was 248 * received by the server. 249 */ 250 @Nullable() 251 public Long getEndTimeMillis() 252 { 253 return endTimeMillis; 254 } 255 256 257 258 /** 259 * Decodes the provided ASN.1 element as a time window collect support data 260 * log capture window object. 261 * 262 * @param e The ASN.1 element to be decoded. It must not be {@code null}. 263 * 264 * @return The time window collect support data log capture window object 265 * that was decoded. 266 * 267 * @throws LDAPException If the provided ASN.1 element cannot be decoded as 268 * a valid time window collect support data log 269 * capture window object. 270 */ 271 @NotNull() 272 static TimeWindowCollectSupportDataLogCaptureWindow decodeInternal( 273 @NotNull final ASN1Element e) 274 throws LDAPException 275 { 276 try 277 { 278 final ASN1Element[] elements = 279 ASN1Sequence.decodeAsSequence(e).elements(); 280 if (elements.length == 1) 281 { 282 final long startTimeMillis = decodeGeneralizedTimeString(elements[0]); 283 return new TimeWindowCollectSupportDataLogCaptureWindow(startTimeMillis, 284 null); 285 } 286 else if (elements.length == 2) 287 { 288 final long startTimeMillis = decodeGeneralizedTimeString(elements[0]); 289 final long endTimeMillis = decodeGeneralizedTimeString(elements[1]); 290 return new TimeWindowCollectSupportDataLogCaptureWindow(startTimeMillis, 291 endTimeMillis); 292 } 293 else 294 { 295 throw new LDAPException(ResultCode.DECODING_ERROR, 296 ERR_TIME_WINDOW_CSD_LOG_WINDOW_INVALID_ELEMENT_COUNT.get( 297 elements.length)); 298 } 299 } 300 catch (final LDAPException le) 301 { 302 Debug.debugException(le); 303 throw le; 304 } 305 catch (final Exception ex) 306 { 307 Debug.debugException(ex); 308 throw new LDAPException(ResultCode.DECODING_ERROR, 309 ERR_TIME_WINDOW_CSD_LOG_WINDOW_CANNOT_DECODE.get( 310 StaticUtils.getExceptionMessage(ex)), 311 ex); 312 } 313 } 314 315 316 317 /** 318 * Decodes the provided ASN.1 element as an octet string whose value is the 319 * generalized time representation of a timestamp. 320 * 321 * @param e The element from which the timestamp should be extracted. 322 * 323 * @return The time (in milliseconds since the epoch) represented by the 324 * timestamp. 325 * 326 * @throws LDAPException If the element value cannot be parsed as a valid 327 * timestamp in the generalized time format. 328 */ 329 private static long decodeGeneralizedTimeString(@NotNull final ASN1Element e) 330 throws LDAPException 331 { 332 final String timestampString = 333 ASN1OctetString.decodeAsOctetString(e).stringValue(); 334 335 try 336 { 337 return StaticUtils.decodeGeneralizedTime(timestampString).getTime(); 338 } 339 catch (final Exception ex) 340 { 341 Debug.debugException(ex); 342 throw new LDAPException(ResultCode.DECODING_ERROR, 343 ERR_TIME_WINDOW_CSD_LOG_WINDOW_MALFORMED_GT.get(timestampString), 344 ex); 345 } 346 } 347 348 349 350 /** 351 * {@inheritDoc} 352 */ 353 @Override() 354 @NotNull() 355 public ASN1Element encode() 356 { 357 return encodedWindow; 358 } 359 360 361 362 /** 363 * {@inheritDoc} 364 */ 365 @Override() 366 public void toString(@NotNull final StringBuilder buffer) 367 { 368 buffer.append("TimeWindowCollectSupportDataLogCaptureWindow(startTime='"); 369 buffer.append(StaticUtils.encodeGeneralizedTime(startTimeMillis)); 370 buffer.append('\''); 371 372 if (endTimeMillis != null) 373 { 374 buffer.append(", endTime='"); 375 buffer.append(StaticUtils.encodeGeneralizedTime(endTimeMillis)); 376 buffer.append('\''); 377 } 378 379 buffer.append(')'); 380 } 381}