Failure to Reach Handler Analysis and Design
Analysis
The meaning of "Failed to Reach Handler" depends on the concrete adapter being used to deliver a message. The most meaningful example is a TEXT-TO-VOICE message that, even if delivered, it never reaches the recipient because he didn't answer the phone.
For this kind of scenario, the adapter itself has to support a way to confirm whether a message was actually received by the intended recipient or not. Currently, none of the supported adapters (CHAT, TEXT-TO-VOICE and SMS) support this feature. The first adapter that, apparently, could provide this feature is EMAIL.
Some of the challenges of how "Failed to Reach Handler" scenario is identified are:
1.- This is typically an asynchronous scenario. New processors has to be created to specifically deal with each adapter. I can imagine we will end up with a sub-flow similar to "Response Receiver".
2.- The delivery service has to support both: message received confirmation and message not received confirmation.
3.- Let's say we identify a "Failure to reach handler" situation for one of the recipients of a message. We can't do anything until we have a confirmation saying that all the other recipients have either received the message or not. How much time do we have to wait? What happens with adapters that don't provide a confirmation mechanism?
Design
The proposed design is similar to the design proposed for "Response Timeout":
- A collection of failing messages is hold by UCSControllerService.
- How new objects are added to this collection is not currently defined. UCSControllerService will have a new method to allow adding new elements.
- A new processor will be consuming the elements of this collection and processing them accordingly.
New Class: MessageWithUnreachableHandlers
This class identifies a Message that was identified to be in the "Failure to Reach Handler" situation. The class will contain a reference to the message itself, and a reason property.
MessageWithUnreachableHandlers:
- message -> The message.
- reason -> This could be represented as an enum with the following values: ALL_HANDLERS, SOME_HANDLERS.
UCSControllerService Interface Modifications
UCSControllerService interface has to support 2 new methods:
1.- public void notifyAboutMessageWithUnreachableHandlers(MessageWithUnreachableHandlers message)
2.- public Set<MessageWithUnreachableHandlers> consumeMessagesWithUnreachableHandlers()
UCSControllerService implementation will hold a synchronized collection (or Map) of MessageWithUnreachableHandlers objects. The first method will simply add elements into this collection and the second method will return a Set containing its current content. The second method will consume any MessageWithUnreachableHandlers present in the synchronized collection (removing them from the collection).
MessageWithUnreachableHandlers consumption
The consumption ofMessageWithUnreachableHandlers is, in some way, similar to the way we are consuming TimedOutMessage objects in "Response Timeout" design. A synchronized collection of MessageWithUnreachableHandlers objects is hold by UCSControllerService. A new processor that polls from that collection and yields needs to be created.
The new processor [UCSProcessMessagesWithUnreachableHandlers?] will process each MessageWithUnreachableHandlers in the following way:
1.- if the reason of the MessageWithUnreachableHandlers being processed is ALL_HANDLERS, the processor will create a new FlowFile for each Message in the original Message's onFailureToReachAll property. These FlowFiles are then transfered to REL_ALL_HANDLERS.
2.- if the reason of the MessageWithUnreachableHandlers being processed is SOME_HANDLERS, the processor will create a new FlowFile for each Message in the original Message's onFailureToReachAny property. These FlowFiles are then transfer to REL_SOME_HANDLERS.
3.- if the reason of the MessageWithUnreachableHandlers being processed is ALL_HANDLERS and the original Message's onFailureToReachAll is empty OR if its reason is SOME_HANDLERS and the original Message's onFailureToReachAny is empty, an empty FlowFile is created and transfered to REL_NO_ALTERNATIVE_MESSAGE.
At this point, any Message sent through REL_ALL_HANDLERS and/or REL_SOME_HANDLERS can be treated by UCS as a regular incoming Message. This new processor can be then connected to the existing UCSValidateMessage processor in UCS workflow.