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