001/* 002 * Copyright 2009-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2009-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) 2009-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.logs; 037 038 039 040import java.io.BufferedReader; 041import java.io.Closeable; 042import java.io.File; 043import java.io.FileReader; 044import java.io.IOException; 045import java.io.Reader; 046 047import com.unboundid.util.NotMutable; 048import com.unboundid.util.NotNull; 049import com.unboundid.util.Nullable; 050import com.unboundid.util.ThreadSafety; 051import com.unboundid.util.ThreadSafetyLevel; 052 053import static com.unboundid.ldap.sdk.unboundidds.logs.LogMessages.*; 054 055 056 057/** 058 * This class provides a mechanism for reading messages from a Directory Server 059 * access log. 060 * <BR> 061 * <BLOCKQUOTE> 062 * <B>NOTE:</B> This class, and other classes within the 063 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 064 * supported for use against Ping Identity, UnboundID, and 065 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 066 * for proprietary functionality or for external specifications that are not 067 * considered stable or mature enough to be guaranteed to work in an 068 * interoperable way with other types of LDAP servers. 069 * </BLOCKQUOTE> 070 */ 071@NotMutable() 072@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 073public final class AccessLogReader 074 implements Closeable 075{ 076 // The reader used to read the contents of the log file. 077 @NotNull private final BufferedReader reader; 078 079 080 081 /** 082 * Creates a new access log reader that will read messages from the specified 083 * log file. 084 * 085 * @param path The path of the log file to read. 086 * 087 * @throws IOException If a problem occurs while opening the file for 088 * reading. 089 */ 090 public AccessLogReader(@NotNull final String path) 091 throws IOException 092 { 093 reader = new BufferedReader(new FileReader(path)); 094 } 095 096 097 098 /** 099 * Creates a new access log reader that will read messages from the specified 100 * log file. 101 * 102 * @param file The log file to read. 103 * 104 * @throws IOException If a problem occurs while opening the file for 105 * reading. 106 */ 107 public AccessLogReader(@NotNull final File file) 108 throws IOException 109 { 110 reader = new BufferedReader(new FileReader(file)); 111 } 112 113 114 115 /** 116 * Creates a new access log reader that will read messages using the provided 117 * {@code Reader} object. 118 * 119 * @param reader The reader to use to read log messages. 120 */ 121 public AccessLogReader(@NotNull final Reader reader) 122 { 123 if (reader instanceof BufferedReader) 124 { 125 this.reader = (BufferedReader) reader; 126 } 127 else 128 { 129 this.reader = new BufferedReader(reader); 130 } 131 } 132 133 134 135 /** 136 * Reads the next access log message from the log file. 137 * 138 * @return The access log message read from the log file, or {@code null} if 139 * there are no more messages to be read. 140 * 141 * @throws IOException If an error occurs while trying to read from the 142 * file. 143 * 144 * @throws LogException If an error occurs while trying to parse the log 145 * message. 146 */ 147 @Nullable() 148 public AccessLogMessage read() 149 throws IOException, LogException 150 { 151 while (true) 152 { 153 final String line = reader.readLine(); 154 if (line == null) 155 { 156 return null; 157 } 158 159 if (line.isEmpty() || (line.charAt(0) == '#')) 160 { 161 continue; 162 } 163 164 return parse(line); 165 } 166 } 167 168 169 170 /** 171 * Parses the provided string as an access log message. 172 * 173 * @param s The string to parse as an access log message. 174 * 175 * @return The parsed access log message. 176 * 177 * @throws LogException If an error occurs while trying to parse the log 178 * message. 179 */ 180 @NotNull() 181 public static AccessLogMessage parse(@NotNull final String s) 182 throws LogException 183 { 184 final LogMessage m = new LogMessage(s); 185 if (m.hasUnnamedValue(AccessLogMessageType.CONNECT.getLogIdentifier())) 186 { 187 return new ConnectAccessLogMessage(m); 188 } 189 else if (m.hasUnnamedValue(AccessLogMessageType.DISCONNECT. 190 getLogIdentifier())) 191 { 192 return new DisconnectAccessLogMessage(m); 193 } 194 else if (m.hasUnnamedValue(AccessLogMessageType.CLIENT_CERTIFICATE. 195 getLogIdentifier())) 196 { 197 return new ClientCertificateAccessLogMessage(m); 198 } 199 else if (m.hasUnnamedValue(AccessLogMessageType.SECURITY_NEGOTIATION. 200 getLogIdentifier())) 201 { 202 return new SecurityNegotiationAccessLogMessage(m); 203 } 204 else if (m.hasUnnamedValue(AccessLogMessageType.ENTRY_REBALANCING_REQUEST. 205 getLogIdentifier())) 206 { 207 return new EntryRebalancingRequestAccessLogMessage(m); 208 } 209 else if (m.hasUnnamedValue(AccessLogMessageType.ENTRY_REBALANCING_RESULT. 210 getLogIdentifier())) 211 { 212 return new EntryRebalancingResultAccessLogMessage(m); 213 } 214 else if (m.hasUnnamedValue(AccessLogMessageType.REQUEST. 215 getLogIdentifier())) 216 { 217 if (m.hasUnnamedValue(AccessLogOperationType.ABANDON. 218 getLogIdentifier())) 219 { 220 return new AbandonRequestAccessLogMessage(m); 221 } 222 else if (m.hasUnnamedValue(AccessLogOperationType.ADD. 223 getLogIdentifier())) 224 { 225 return new AddRequestAccessLogMessage(m); 226 } 227 else if (m.hasUnnamedValue(AccessLogOperationType.BIND. 228 getLogIdentifier())) 229 { 230 return new BindRequestAccessLogMessage(m); 231 } 232 else if (m.hasUnnamedValue(AccessLogOperationType.COMPARE. 233 getLogIdentifier())) 234 { 235 return new CompareRequestAccessLogMessage(m); 236 } 237 else if (m.hasUnnamedValue(AccessLogOperationType.DELETE. 238 getLogIdentifier())) 239 { 240 return new DeleteRequestAccessLogMessage(m); 241 } 242 else if (m.hasUnnamedValue(AccessLogOperationType.EXTENDED. 243 getLogIdentifier())) 244 { 245 return new ExtendedRequestAccessLogMessage(m); 246 } 247 else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY. 248 getLogIdentifier())) 249 { 250 return new ModifyRequestAccessLogMessage(m); 251 } 252 else if (m.hasUnnamedValue(AccessLogOperationType.MODDN. 253 getLogIdentifier())) 254 { 255 return new ModifyDNRequestAccessLogMessage(m); 256 } 257 else if (m.hasUnnamedValue(AccessLogOperationType.SEARCH. 258 getLogIdentifier())) 259 { 260 return new SearchRequestAccessLogMessage(m); 261 } 262 else if (m.hasUnnamedValue(AccessLogOperationType.UNBIND. 263 getLogIdentifier())) 264 { 265 return new UnbindRequestAccessLogMessage(m); 266 } 267 else 268 { 269 throw new LogException(s, 270 ERR_LOG_MESSAGE_INVALID_REQUEST_OPERATION_TYPE.get()); 271 } 272 } 273 else if (m.hasUnnamedValue(AccessLogMessageType.RESULT. 274 getLogIdentifier())) 275 { 276 if (m.hasUnnamedValue(AccessLogOperationType.ABANDON. 277 getLogIdentifier())) 278 { 279 return new AbandonResultAccessLogMessage(m); 280 } 281 else if (m.hasUnnamedValue(AccessLogOperationType.ADD. 282 getLogIdentifier())) 283 { 284 return new AddResultAccessLogMessage(m); 285 } 286 else if (m.hasUnnamedValue(AccessLogOperationType.BIND. 287 getLogIdentifier())) 288 { 289 return new BindResultAccessLogMessage(m); 290 } 291 else if (m.hasUnnamedValue(AccessLogOperationType.COMPARE. 292 getLogIdentifier())) 293 { 294 return new CompareResultAccessLogMessage(m); 295 } 296 else if (m.hasUnnamedValue(AccessLogOperationType.DELETE. 297 getLogIdentifier())) 298 { 299 return new DeleteResultAccessLogMessage(m); 300 } 301 else if (m.hasUnnamedValue(AccessLogOperationType.EXTENDED. 302 getLogIdentifier())) 303 { 304 return new ExtendedResultAccessLogMessage(m); 305 } 306 else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY. 307 getLogIdentifier())) 308 { 309 return new ModifyResultAccessLogMessage(m); 310 } 311 else if (m.hasUnnamedValue(AccessLogOperationType.MODDN. 312 getLogIdentifier())) 313 { 314 return new ModifyDNResultAccessLogMessage(m); 315 } 316 else if (m.hasUnnamedValue(AccessLogOperationType.SEARCH. 317 getLogIdentifier())) 318 { 319 return new SearchResultAccessLogMessage(m); 320 } 321 else 322 { 323 throw new LogException(s, 324 ERR_LOG_MESSAGE_INVALID_RESULT_OPERATION_TYPE.get()); 325 } 326 } 327 else if (m.hasUnnamedValue(AccessLogMessageType.FORWARD. 328 getLogIdentifier())) 329 { 330 if (m.hasUnnamedValue(AccessLogOperationType.ABANDON. 331 getLogIdentifier())) 332 { 333 return new AbandonForwardAccessLogMessage(m); 334 } 335 else if (m.hasUnnamedValue(AccessLogOperationType.ADD. 336 getLogIdentifier())) 337 { 338 return new AddForwardAccessLogMessage(m); 339 } 340 else if (m.hasUnnamedValue(AccessLogOperationType.BIND. 341 getLogIdentifier())) 342 { 343 return new BindForwardAccessLogMessage(m); 344 } 345 else if (m.hasUnnamedValue(AccessLogOperationType.COMPARE. 346 getLogIdentifier())) 347 { 348 return new CompareForwardAccessLogMessage(m); 349 } 350 else if (m.hasUnnamedValue(AccessLogOperationType.DELETE. 351 getLogIdentifier())) 352 { 353 return new DeleteForwardAccessLogMessage(m); 354 } 355 else if (m.hasUnnamedValue(AccessLogOperationType.EXTENDED. 356 getLogIdentifier())) 357 { 358 return new ExtendedForwardAccessLogMessage(m); 359 } 360 else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY. 361 getLogIdentifier())) 362 { 363 return new ModifyForwardAccessLogMessage(m); 364 } 365 else if (m.hasUnnamedValue(AccessLogOperationType.MODDN. 366 getLogIdentifier())) 367 { 368 return new ModifyDNForwardAccessLogMessage(m); 369 } 370 else if (m.hasUnnamedValue(AccessLogOperationType.SEARCH. 371 getLogIdentifier())) 372 { 373 return new SearchForwardAccessLogMessage(m); 374 } 375 else 376 { 377 throw new LogException(s, 378 ERR_LOG_MESSAGE_INVALID_FORWARD_OPERATION_TYPE.get()); 379 } 380 } 381 else if (m.hasUnnamedValue(AccessLogMessageType.FORWARD_FAILED. 382 getLogIdentifier())) 383 { 384 if (m.hasUnnamedValue(AccessLogOperationType.ADD.getLogIdentifier())) 385 { 386 return new AddForwardFailedAccessLogMessage(m); 387 } 388 else if (m.hasUnnamedValue(AccessLogOperationType.BIND. 389 getLogIdentifier())) 390 { 391 return new BindForwardFailedAccessLogMessage(m); 392 } 393 else if (m.hasUnnamedValue(AccessLogOperationType.COMPARE. 394 getLogIdentifier())) 395 { 396 return new CompareForwardFailedAccessLogMessage(m); 397 } 398 else if (m.hasUnnamedValue(AccessLogOperationType.DELETE. 399 getLogIdentifier())) 400 { 401 return new DeleteForwardFailedAccessLogMessage(m); 402 } 403 else if (m.hasUnnamedValue(AccessLogOperationType.EXTENDED. 404 getLogIdentifier())) 405 { 406 return new ExtendedForwardFailedAccessLogMessage(m); 407 } 408 else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY. 409 getLogIdentifier())) 410 { 411 return new ModifyForwardFailedAccessLogMessage(m); 412 } 413 else if (m.hasUnnamedValue(AccessLogOperationType.MODDN. 414 getLogIdentifier())) 415 { 416 return new ModifyDNForwardFailedAccessLogMessage(m); 417 } 418 else if (m.hasUnnamedValue(AccessLogOperationType.SEARCH. 419 getLogIdentifier())) 420 { 421 return new SearchForwardFailedAccessLogMessage(m); 422 } 423 else 424 { 425 throw new LogException(s, 426 ERR_LOG_MESSAGE_INVALID_FORWARD_FAILED_OPERATION_TYPE.get()); 427 } 428 } 429 else if (m.hasUnnamedValue(AccessLogMessageType.ASSURANCE_COMPLETE. 430 getLogIdentifier())) 431 { 432 if (m.hasUnnamedValue(AccessLogOperationType.ADD.getLogIdentifier())) 433 { 434 return new AddAssuranceCompletedAccessLogMessage(m); 435 } 436 else if (m.hasUnnamedValue(AccessLogOperationType.DELETE. 437 getLogIdentifier())) 438 { 439 return new DeleteAssuranceCompletedAccessLogMessage(m); 440 } 441 else if (m.hasUnnamedValue(AccessLogOperationType.MODIFY. 442 getLogIdentifier())) 443 { 444 return new ModifyAssuranceCompletedAccessLogMessage(m); 445 } 446 else if (m.hasUnnamedValue(AccessLogOperationType.MODDN. 447 getLogIdentifier())) 448 { 449 return new ModifyDNAssuranceCompletedAccessLogMessage(m); 450 } 451 else 452 { 453 throw new LogException(s, 454 ERR_LOG_MESSAGE_INVALID_ASSURANCE_COMPLETE_OPERATION_TYPE.get()); 455 } 456 } 457 else if (m.hasUnnamedValue(AccessLogMessageType.ENTRY.getLogIdentifier())) 458 { 459 return new SearchEntryAccessLogMessage(m); 460 } 461 else if (m.hasUnnamedValue(AccessLogMessageType.REFERENCE. 462 getLogIdentifier())) 463 { 464 return new SearchReferenceAccessLogMessage(m); 465 } 466 else if (m.hasUnnamedValue(AccessLogMessageType.INTERMEDIATE_RESPONSE. 467 getLogIdentifier())) 468 { 469 return new IntermediateResponseAccessLogMessage(m); 470 } 471 else 472 { 473 throw new LogException(s, 474 ERR_LOG_MESSAGE_INVALID_ACCESS_MESSAGE_TYPE.get()); 475 } 476 } 477 478 479 480 /** 481 * Closes this error log reader. 482 * 483 * @throws IOException If a problem occurs while closing the reader. 484 */ 485 @Override() 486 public void close() 487 throws IOException 488 { 489 reader.close(); 490 } 491}