Skip to content

Commit

Permalink
Improve validation behaviour, improve javadoc, make ctor public
Browse files Browse the repository at this point in the history
  • Loading branch information
at055612 committed Jun 28, 2024
1 parent 017347b commit 0a7d13c
Show file tree
Hide file tree
Showing 24 changed files with 716 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,24 @@

/**
* A service for recording audit events.
* <p>The default implementation is {@link event.logging.base.impl.DefaultEventLoggingService}</p>
*/
public interface EventLoggingService {

/**
* System property key for setting the {@link event.logging.base.impl.LogReceiver} implementation
* to use. If not set {@link event.logging.base.impl.LoggerLogReceiver} will be used.
*/
String PROP_KEY_LOG_RECEIVER_CLASS = "event.logging.logreceiver";

/**
* System property key used by {@link event.logging.base.impl.DefaultEventLoggingService} to
* control whether the serialised {@link Event} XML is validated against the XML schema.
* A value of {@code true} for this property will enable validation.
* <p>See also {@link EventLoggingService#setValidate(Boolean)}</p>
*/
String PROP_KEY_VALIDATE = "event.logging.validate";

/**
* Creates an event that may have some common values set by default depending on the particular EventLoggingService
* implementation being used. If this method is not implemented it will return an empty event by default.
Expand Down Expand Up @@ -89,7 +104,7 @@ default Event createEvent(final String typeId,
}

/**
* Logs an event.
* Logs an event to the {@link event.logging.base.impl.LogReceiver}
*
* @param event The event to log.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ public interface LoggedWorkExceptionHandler<A extends EventAction> {
* A handler to provide a new {@link EventAction} based on the {@link Throwable}
* and the original {@link EventAction}, e.g. where you need to add more detail to
* the {@link EventAction} based on the work performed and the exception thrown.
* <p>
* This handler will not be called if the {@link Throwable} is a
* {@link event.logging.base.impl.ValidationException}, i.e. the event is malformed.
* </p>
* @param eventAction The original {@link EventAction} for the logged work.
* @param throwable The {@link Throwable} thrown by the logged work.
* @return A new {@link EventAction} for use in the logged event.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@

/**
* Should be implemented by classes providing a way to validate some XML.
* The default implementation is {@link event.logging.base.impl.DefaultXMLValidator}.
*/
public interface XMLValidator {

/**
* Validates the <b>XML</b> and optionally writes the result to a file or
* log.
*
*
* @param xml
* The XML to validate.
* @throws event.logging.base.impl.ValidationException if the implementation chooses
* to throw exceptions on validation failures.
*/
void validate(String xml);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import event.logging.base.XMLValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ErrorHandler;

import java.util.function.Supplier;

/**
* <p>This is the default implementation of {@link EventLoggingService} for logging events.
Expand All @@ -43,8 +44,6 @@ public class DefaultEventLoggingService implements EventLoggingService {

private static final String SCHEMA_LOCATION = SchemaLocator.getSchemaLocation();

private static final String VALIDATE = "event.logging.validate";

private final EventSerializer eventSerializer = new DefaultEventSerializer();
private final LogReceiverFactory logReceiverFactory = LogReceiverFactory.getInstance();
private final XMLValidator xmlValidator;
Expand All @@ -54,28 +53,60 @@ public class DefaultEventLoggingService implements EventLoggingService {
*/
private Boolean validate;

/**
* Uses {@link QuietErrorHandler} and {@link ValidationExceptionBehaviourMode#LOG} for validation (if enabled),
* i.e. it will attempt to validate as much of the event as possible, logging all validation messages in one
* ERROR/WARN SLF4J log message at the end of validation.
* <p>See {@link DefaultEventLoggingService#DefaultEventLoggingService(Supplier, ValidationExceptionBehaviourMode)}
* for more control of validation behaviour.</p>
*/
public DefaultEventLoggingService() {
xmlValidator = new event.logging.base.impl.DefaultXMLValidator(SCHEMA_LOCATION);
xmlValidator = new DefaultXMLValidator(SCHEMA_LOCATION);
}

public DefaultEventLoggingService(ErrorHandler schemaValidationErrorHandler) {
xmlValidator = new event.logging.base.impl.DefaultXMLValidator(SCHEMA_LOCATION, schemaValidationErrorHandler);
/**
* Uses the {@link ValidationErrorHandler} supplied by {@code validationErrorHandlerSupplier}
* and {@link ValidationExceptionBehaviourMode#LOG} for validation (if enabled),
* i.e. it will log all validation messages in one ERROR/WARN SLF4J log message at the end of validation.
* The implementation of the {@link ValidationErrorHandler} will determine whether only the first problem
* is logged or all are logged.
* <p>See {@link DefaultEventLoggingService#DefaultEventLoggingService(Supplier, ValidationExceptionBehaviourMode)}
* for more control of validation behaviour.</p>
*
* @param validationErrorHandlerSupplier Supplies a new instance of a {@link ValidationErrorHandler} to handle
* validation warnings/errors.
*/
public DefaultEventLoggingService(final Supplier<ValidationErrorHandler> validationErrorHandlerSupplier) {
xmlValidator = new DefaultXMLValidator(
SCHEMA_LOCATION,
validationErrorHandlerSupplier);
}

/**
* @param schemaValidationErrorHandler
* @param validationExceptionBehaviourMode Controls how the validator handles exceptions thrown by the schemaValidationExceptionHandler
* If you want this service to throw an exception if the event fails validation then we recommend passing
* a supplier of a {@link QuietErrorHandler} and {@link ValidationExceptionBehaviourMode#THROW}.
* <p>
* If you want this service to simply log validation messages to a {@link Logger} then we recommend using
* the no-args constructor {@link DefaultEventLoggingService#DefaultEventLoggingService()}.
* </p>
* @param validationErrorHandlerSupplier Supplies a new instance of a {@link ValidationErrorHandler} to handle
* validation warnings/errors.
* @param validationExceptionBehaviourMode Controls how the validator handles exceptions thrown by the
* {@link ValidationErrorHandler} as supplied by
* {@code validationErrorHandlerSupplier}.
*/
public DefaultEventLoggingService(ErrorHandler schemaValidationErrorHandler,
ValidationExceptionBehaviourMode validationExceptionBehaviourMode) {
public DefaultEventLoggingService(final Supplier<ValidationErrorHandler> validationErrorHandlerSupplier,
final ValidationExceptionBehaviourMode validationExceptionBehaviourMode) {

LOGGER.info("Using schema location " + SCHEMA_LOCATION);
xmlValidator = new DefaultXMLValidator(SCHEMA_LOCATION, schemaValidationErrorHandler,
xmlValidator = new DefaultXMLValidator(
SCHEMA_LOCATION,
validationErrorHandlerSupplier,
validationExceptionBehaviourMode);
}

/**
* Logs an event to the log.
* Logs an event to the {@link LogReceiver}.
*
* @param event The event to log.
*/
Expand All @@ -85,7 +116,7 @@ public void log(final Event event) {
final String trimmed = data.trim();
if (!trimmed.isEmpty()) {
// Validate data here if the configuration option is set.
if (checkValidating()) {
if (isValidationRequired()) {
xmlValidator.validate(trimmed);
}

Expand All @@ -101,14 +132,14 @@ public EventLoggerBuilder.TypeIdStep loggedWorkBuilder() {
return new EventLoggerBuilderImpl(this);
}

private boolean checkValidating() {
private boolean isValidationRequired() {
// Check the programmatic flag first.
if (validate != null) {
return validate;
}

// If we aren't setting validate on .
final String val = System.getProperty(VALIDATE);
final String val = System.getProperty(EventLoggingService.PROP_KEY_VALIDATE);
return Boolean.parseBoolean(val);
}

Expand All @@ -128,11 +159,13 @@ public void setValidate(final Boolean validate) {

/**
* Use to determine if the event logging service is set to validate data against the XML schema.
* Takes into account the value supplied by {@link DefaultEventLoggingService#setValidate(Boolean)}
* and the value of system property <code>event.logging.validate</code>.
*
* @return True if the validate flag is set.
*/
@Override
public boolean isValidate() {
return validate != null && validate;
return isValidationRequired();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

import java.io.StringWriter;

/**
*
*/
public class DefaultEventSerializer implements EventSerializer {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultEventSerializer.class);

Expand Down
Loading

0 comments on commit 0a7d13c

Please sign in to comment.