Validación de Mensajes
Al trabajar con mensajes enviados entre máquinas separadas, incluso cuando se trabaja contra un esquema específico, a menudo pueden surgir problemas con la validez de los mensajes. Estos suelen deberse a bugs, errores de entrada de datos o desajustes de versión de esquema. Tanto los sending como los receiving connectors pueden configurarse opcionalmente para validar mensajes antes de enviar o después de recibir.
Send Connectors
Para agregar validación a un sending connector, debe proporcionarse una implementación de la interfaz Validator al construir el connector.
public interface Validator {
ValidationReport validate(TransportMessage transportMessage);
}
La biblioteca del connector proporciona dos validadores, uno para JSON Schema y otro para XML Schema. La validación se realiza contra un TransportMessage antes de que se envíe al transport.
Validación de XML Schema
La implementación de validación XML de Validator es XmlSchemaValidator.
Recibe un InputStream que representa el esquema a usar, contra el cual se validarán todos los mensajes que pasen por este validador.
String xmlSchema = "/validation/sample-schema.xsd";
InputStream xmlSchemaStream = getClass().getResourceAsStream(xmlSchema);
XmlSchemaValidator xmlValidator = new XmlSchemaValidator(xmlSchemaStream);
SendConnector<ExampleType, ExampleType> sendConnectorWithXmlValidator
= new SendConnector.Builder<ExampleType, ExampleType>(connectorName)
.withActorSystem(actorSystem)
.withConnectorTransport(transport)
.withCorrelationIdExtractor(correlationIdExtractor)
.withValidator(xmlValidator) (1)
.build();
| 1 | Agrega el validador de XML Schema al connector. |
En el ejemplo anterior, cargamos un documento de XML Schema desde el classpath como un input stream.
Este es el patrón de uso más común para XmlSchemaValidator.
Es posible configurarlo usando otros tipos de input stream, como un ByteArrayInputStream para cargar el esquema desde una cadena.
El validador XML implementa protección contra inyección de entidades externas (XXE) según la chuleta de OWASP sobre el tema.
Validación de JSON Schema
La implementación de validación JSON de Validator es JsonSchemaValidator.
Se configura de manera similar al validador XML, donde debemos pasar un InputStream que representa el esquema contra el cual validar los mensajes.
String jsonSchema = "/com/github/fge/jsonschema/examples/fstab.json";
InputStream jsonSchemaStream = getClass().getResourceAsStream(jsonSchema);
JsonSchemaValidator jsonValidator = new JsonSchemaValidator(jsonSchemaStream);
SendConnector<ExampleType, ExampleType> sendConnectorWithJsonValidator
= new SendConnector.Builder<ExampleType, ExampleType>(connectorName)
.withActorSystem(actorSystem)
.withConnectorTransport(transport)
.withCorrelationIdExtractor(correlationIdExtractor)
.withValidator(jsonValidator) (1)
.build();
| 1 | Agrega el validador de JSON Schema al connector. |
La versión predeterminada de JSON Schema es draft-04, que es el estándar de facto.
Receive Connectors
Para agregar validación a un sending connector, debe proporcionarse una implementación de la interfaz BeanValidator al construir el connector.
public interface BeanValidator<T> {
BeanValidationReport validate(T message);
BeanValidator<T> withConnectorName(String connectorName);
}
La biblioteca del connector proporciona un validador para validación de beans usando la implementación de Hibernate validator.
La validación se realiza sobre el mensaje una vez que ha sido transformado de un TransportMessage al tipo objetivo por la función proporcionada ReceiveTransportMessageConverter.
Bean Validator
Se espera que los mensajes estén anotados con anotaciones de jakarta.validation si van a ser validados con la implementación del bean validator.
La validación de beans está disponible con BeanValidatorImpl.
Opcionalmente recibe un jakarta.validation.Validator que representa el validador a usar, contra el cual se validarán todos los mensajes que pasen por este validador.
Si no se pasa un validador, se crea uno predeterminado.
public BeanValidatorImpl() {
this(Validation.buildDefaultValidatorFactory().getValidator());
}
public BeanValidatorImpl(jakarta.validation.Validator validator) {
this(null, validator);
}
BeanValidatorImpl(String connectorName, jakarta.validation.Validator validator) {
this.connectorName = connectorName;
this.validator = validator;
}
La validación es opcional y puede habilitarse proporcionando una implementación de BeanValidator al construir el connector.
receiveConnector = initiatingReceiveConnectorBuilder()
.withConnectorTransport(connectorTransport)
.withEventBus(eventBus)
.withBeanValidator(new BeanValidatorImpl<>()) (1)
.build();
| 1 | Agrega el bean validator al connector |