I have a web service which receives xml events from another system, process them using specific workflow and sends a list of potentials errors back as HTTP response.
Event processing workflow consists of several handlers (let's say: Preprocessor, Persister and Validator) implemented using Guava's EventBus. Handlers send events to each other. Something like this:
public class RequestHandler {
@RequestMapping
public Errors handleRequest(String xmlData) {
eventBus.post(new XmlReceivedEvent(xmlData));
...
return errors; // how to get errors object from the last handler in chain ?
}
}
public class Preprocessor {
@Subscribe
public void onXmlReceived(XmlReceivedEvent event) {
// do some pre-processing
...
eventBus.post(new PreprocessingCompleteEvent(preprocessingResult));
}
}
public class Persister {
@Subscribe
public void onPreprocessingComplete(PreprocessingCompleteEvent event) {
// do some persistence stuff
...
eventBus.post(new PersistenceCompleteEvent(persistenceResult));
}
}
public class Validator {
@Subscribe
public void onPersistenceComplete(PersistenceCompleteEvent event) {
// do validation
...
eventBus.post(new ValidationCompleteEvent(errors)); // errors object created, should be returned back to the RequestHandler
}
}
The problem is: how to return the processing result deeply from Validator handler back to the starting point (RequestHandler), so user can receive HTTP response ?
I consider two options:
Set errors object to the initial XmlReceivedEvent and retrieve it after processing complete:
public class RequestHandler {
@RequestMapping
public Errors handleRequest(String xmlData) {
XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
eventBus.post(event);
...
return event.getErrors();
}
}
However, in that case I will have to pass errors object to each event in the chain to make it available for Validator to fill it with real data.
Subscribe RequestHandler to ValidationCompleteEvent from Validator with populated errors object inside.
public class RequestHandler {
private Errors errors;
@RequestMapping
public Errors handleRequest(String xmlData) {
XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
eventBus.post(event);
...
return this.errors; // ???
}
@Subscribe
public void onValidationComplete(ValidationCompleteEvent event) {
this.errors = event.getErrors();
}
}
But, unfortunately, RequestHandler is a Spring stateless service (singleton), so I would like to avoid saving any data in class fields.
Appreciate any ideas.
If you want a workflow like that, you shouldn't be using a Guava EventBus
for it. EventBus
is specifically intended to allow events to be posted to subscribers without the event poster knowing or caring about what those subscribers are... as such, you can't return results to the poster of an event from subscribers.
It sounds to me like you should be doing something much more straightforward here, like injecting your preprocessor, persister and validator and calling their methods directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With