Conversation API Analysis and Design

Analysis

 

From specification:
"The conversation interfaces allows clients to establish communication channels for conducting
dialogs."

Open Questions:
(grey lightbulb) What is a ConversationRequestMessage used for?
(grey lightbulb) What is ConversationChannel used for?

Conversation operations

Create Conversation

"This operation is used to create a conversation.".

Until now, our NIFI-UCS (NUCS) implementation doesn't deal with conversations in an active way. Conversations are implicitly "created" when a Message with a relatedConversationId arrives into NUCS. NUCS is not currently keeping track nor validating any conversation. When a response comes back from an adapter, the generated message will contain the relatedConversationId of the original message in its relatedConversationId field.

NUCS will now fail if an incoming message has a relatedConversationId that is not known. NUCS will still support messages with an empty (null) relatedConversationId though.

(grey lightbulb) Does creating a conversation also includes an implicit "connect conversation" operation?

Connect Conversation

"This operation is used allow a client to connect to an existing conversation. The full semantic meaning of establishing a connection is dependent on the nature of the dialog and the communications modality. For example connecting to a VoIP call might complete the setup of a voice call."
"The exact meaning of connecting to a conversation is highly dependent on the communications modality. For example connecting to a chat room might add one to a chat group, while connecting to a VoIP call might provide the information needed for a software VoIP client to connect to the physical VoIP channel"

NUCS doesn't discriminate clients (and as far as I understand, UCS doesn't either). When a client connects to a conversation, there is no User Information provided.
(grey lightbulb) Who is then connecting to the conversation then? what channel is being used?

There is a potential conflict between the channels a Conversation defines (via Conversation.participants) and the channels really used by the messages (MessageHeader.recipientsList.deliveryAddress).
(grey lightbulb) Is there any relationship between these 2 fields?
(grey lightbulb) Is the conversation limiting in some way the valid recipients of the messages it contains?

In some scenarios, the connection of a conversation could require a specific action to be taken by NUCS. For example, in a dynamic 1->N CHAT message, the connect conversation could join the new participant (this is supposing we know which participant we are talking about) into the created chat room. Note that this operation is currently performed the first time a CHAT Message is sent to a recipient.


NUCS needs to provide a mechanism to for adapters that require some configuration for when a new participant is involved.

Disconnect Conversation

"This operation disconnects an active conversation (e.g., VoIP, Chatroom, etc.)."

It is clear that the meaning of "disconnection" depends on the specific channels being used by the conversation. Most of the currently supported channels in NUCS are stateless in the sense that there is no setup steps involved when the channel is used and in the sense that the channel is independent of the communication. The only exception so far is the 1->1 and 1->N (dynamic) CHAT channel. These channels create an ad-hoc chat room to host the messages. After the conversation is finished, these rooms should be removed.

(grey lightbulb) This operations should be the opposite of "create conversation" instead of "connect conversation". 

Query Conversations

"Search for existing conversations. This search may include active and discontinued conversations depending on the nature of the query."

(grey lightbulb) The specification is too vague on the definition of a query. ConversationIntf.queryConversions() takes two parameters: a String (query) and a List<QueryFilter> (filters). The exact syntax of the query or the meaning of a QueryFilter is not defined in the specification.

Retrieve Conversation

"This operation retrieves a conversation and references to the messages relating to it."

NUCS has to retrieve the corresponding Conversation along with all the messages that reference it.

Update Conversation

"Nurse Tanaka discovered that by oversight Dr. Jones was not a part of the Hygiene discussion. He updates the conversation to include Dr. Jones as a participant."

(grey lightbulb) Just like with Alerting.updateAlert() the parameters for update conversation is too coarse grained. The update conversation operation takes a full Conversation object as parameter.
For the scenario described in the specification, a connect conversation operation seems more suitable.

Design

MessageStoreController modifications

The following methods needs to be added to MessageStoreController interface:

  • void saveConversation(Conversation c): This method will persist a new conversation. If the id of conversation being saved conflicts with the id of a known conversation, this method will fail.
  • void disconnectConversation(String id): This method will be used to mark a Conversation as "disconnected". The Conversation class currently doesn't have any Status field we can use to mark a Conversation as disconnected. MessageStoreController implementations will have to take care of this.
  • Optional<Conversation> getConversationById(String id): This method returns a conversation given its id.
  • List<Message> listMessagesByConversationId(String id): This method lists all the messages whose relatedConversationId is equal to the id being passed.
  • List<Message> listMessagesByConversationId(String id, long from, long total): same as listMessagesByConversationId(String id) but with pagination parameters.
  • List<Conversation> queryConversations(String query, List<QueryFilter> filters): the implementation of this method is still not clear.

UCSControllerService modifications

UCSControllerService will need to expose the methods added in MessageStoreController.

Communication Interface Workflow

Just like we did for Client and Alerting interfaces, a new workflow has to be created for the Communication interface implementation.
This new workflow will contain 1 specific processor for each of the operations the Communication interface defines.

UCSValidateMessage processor modifications

This processor now has to validate whether the relatedConversationId of an incoming message belongs to an existing conversation or not.
A message with a null relatedConversationId is still treated as valid.

New Processors

UCSCreateConversation

This new processor will take a serialized Conversation as input, it will validate it and store it into UCSControllerService.
This processor returns no result.

  • Input: Serialized Conversation
  • Output Relationships:
    • REL_FAILURE
    • REL_SUCCESS: the incoming flow file is routed through it.

UCSConnectConversation

The details of this processor will have to wait until we define the expected behavior of "Connect Conversation" operation.

  • Input: Conversation Id (According to specification)
  • Output Relationships:
    • REL_FAILURE
    • ???

UCSDisconnectConversation

The details of this processor will have to wait until we define the expected behavior of "Disconnect Conversation" operation.

  • Input: Conversation Id (According to specification)
  • Output Relationships:
    • REL_FAILURE
    • ???

UCSQueryConversation

This processor will wrap UCSControllerService.queryConversations(). The result of this processor will be a serialized list of Conversation objects.
Given that the input of this processor is a query and a list of QueryFilter objects, a new class (i.e. ConversationQuery) must be implemented to hold this information.

  • Input: Serialized ConversationQuery
  • Output Relationships:
    • REL_FAILURE
    • REL_SUCCESS: a serialized list of Conversation objects is routed through it.

 

UCSRetrieveConversation

This processor will wrap UCSControllerService.getConversationById(). The result of this processor will be a serialized Conversation object.

  • Input: Conversation Id
  • Output Relationships:
    • REL_FAILURE
    • REL_SUCCESS: a serialized Conversation object is routed through it.

UCSUpdateConversation