Request channel is a scatter channel. Sending request to 3 micro services(outbound gateways) . I was expecting different span for different services to track properly. I am using spring sleuth. Used DefaultHeaderMapper to map header.
My questions are:
1. How span id is generated, where server/client side? Any reference document to study.
2. How to resolve the issue of duplicate span in spring integration?
The span is generated on the client side when the message is sent. Then it gets propagated when the message arrives. If a message arrived and there were no messaging headers then the span will be created. Everything is written in the documentation (http://cloud.spring.io/spring-cloud-sleuth/spring-cloud-sleuth.html) so just read the docs. As for the resolution of duplicate spans I have no idea what you are talking about so I guess you need to provide a more detailed description or a sample to replicate the problem.
Related
Summary
I am using the Bot Framework REST API to create and update Microsoft Teams posts.
I have found that I can only update the last two posts of a conversation, but cannot find documentation that describes this restriction.
It is not possible to identify the failed updates from the API response, as the HTTP response code and body is always the same, regardless of whether the update works or not (200 with the id of the "updated" activity). I would expect the response to indicate the failure, and so this appears to be a Teams bug.
Detail
I can create conversations and create replies to conversations using the Bot Framework REST API without issue (using the create conversation and send to conversation endpoints). My problem arises if I try to update these messages.
Given a conversation that looks like this:
parent_message
|_ child_message_1
|_ child_message_2
|_ child_message_3
If I attempt to use the update activty endpoint to update each one of these messages, I observe that:
I can always update parent_message.
I can update child_message_3 and child_message_2, but not child_message_1. In each case the HTTP response is a successful HTTP response (200 response code, with a JSON body that contains the id of the updated message), regardless of whether the update succeeds or not.
If I add another message, child_message_4, then this will be updatable, but child_message_2 will no longer be updatable. I assume this is because now child_message_2 is no longer one of the last two messages.
I see the same behavior if another user adds messages to the conversation, ie. if a user were to make two posts to the conversation I would no longer be able to update any of my own child messages as they are no longer one of the last two messages.
My questions are:
Does anyone know if this restriction is by design? If so, can you point to some documentation on this?
Is it possible to determine when an update fails? As mentioned, the HTTP response always reports success so I'm unable to find a way to do this. Is this a bug in Teams?
Thanks for reporting this. We are able to repro this at our end and we are tracking it here: MicrosoftDocs/msteams-docs#2011
Please follow this issue for updates/progress/questions.
Updates: This is fixed.
This appears to be a bug, but I think the bug is different from what you think it is. Go ahead and "refresh" the conversation and you should see the updates in effect. If you're using the web app then you can refresh the page, but since you're probably using the desktop or mobile app then you could try switching to another conversation and back, or you might have to sign out and sign in again.
Let suppose the following simple UC based on a CQRS architecture:
We have a backend managing a Business Object, let says a Movie.
This backend is composed of 2 Microservices: a CommandManager (Create/Update/Delete Movie) and a QueryManager (Query Movie)
We have a frontend that offer a web page for creating a new Movie and this action lead automatically to another web page describing the Movie.
A simple way to do that is:
A web page collect movie information using a form and send them to the frontend.
The frontend make a POST request to the CommandManager
The CommandManager write the new movies to the datastore and return the movie key
The frontend make a GET using this key to the QueryManager
The QueryManager looks for the Movie in the Datastore using the key and return it.
The frontend deliver the page with the Movie Information.
Ok, now I want to transform this UC in a more Event Driven way. Here is the new flow:
A web page collect movie information using a form and send them to the frontend.
The frontend write a Message in the BUS with the new movie information
The CommandManager listen the BUS and create the new movies in the datastore. Eventually, it publish a new message in the BUS specifying that a new Movie has been created.
At this point, the frontend is no more waiting for a response due to the fact that this kind of flow is asynchronous. How could we complete this flow in order to forward the user to the Movie Information Web page? We should wait that the creation process is done before querying the QueryManager.
In a more general term, in a asynchronous architecture based on bus/event, how to execute Query used to provide information in a web page?
In addition to #VoiceOfUnreason's answer,
If the two microservices are RESTFul, the CommandManager could return a 202 Accepted with a link pointing to the resource that will be created in the future. The client could then poll that resource until the server responds with a 200 OK.
Another solution would be that the CommandManager would return a 202 Accepted with a link pointing to a command/status endpoint. The client would poll that endpoint until the status is command-processed (including the URL to the the actual resource) or command-failed (including a descriptive message for the failure).
These solutions could be augmented by sending the status of all processed commands using Server Sent Events. In this way, the client gets notified without polling.
If the client is not aware that the architecture is asynchronous, a solution is to use an API gateway that blocks the client's request until the upstream microservice processes the command and then to respond with the complete resource's data.
At this point, the frontend is no more waiting for a response due to the fact that this kind of flow is asynchronous. How could we complete this flow in order to forward the user to the Movie Information Web page? We should wait that the creation process is done before querying the QueryManager.
Short answer: make the protocol explicit.
Longer answer: a good place to look for inspiration here is HTTP.
The front end makes a POST to the origin server; as a result the origin server places a message on the queue and sends a response back.
The representation sent with this response ought to describe the request's current status and point to (or embed) a status monitor that can provide the user with an estimate of when the request will be fulfilled.
The client can then poll the endpoint to find out what progress has been made.
For instance, the endpoint might be a query into the data store, that looks for evidence that the command manager has processed the original command; or it might be an endpoint that is watching the bus for the MovieCreated message, and changes its answer based on whether or not it has seen that.
It may help clarify things to look into idempotent request handling; when the Command Manager pulls a message off of its queue, how does it know if it has previously processed a copy of that message? Your polling endpoint should be able to use the same information to let the consumer know that the message has been successfully processed.
In addition to #Constantin Galbenu's answer, I would like to put in my two cents.
I would strongly advise you to look at a microservices pattern called "BFF" (Backend-For-Frontend) pattern. Instead of having a thick API gateway doing all the work, you can have an API per use-case. For Example: In your case, you can an API called "CreateMovieBFFHandler" which would receive the POST request from front-end and then this guy would coordinate with other things in the system like message queues, events etc. to track the status of the submitted request. UI might have a protocol with this BFFhandler that if the response doesn't come back in X seconds, then the front-end would consider it as failure and if this handler is able to get a successfully processed messaged from message queue or "MovieCreated" event for this key, then it could send a 200 OK back and then you can redirect the page to call write side and then populate the UI.
Useful Link: https://samnewman.io/patterns/architectural/bff/
I m implementing Pub/Sub model using JMS. I send a message from Pub to all Subscribers. I want that subscribers should get filtered messages based on some string in actual message body.
For example a subscriber subscribe to a topic 'sports' and should receive only those posts which has keyword 'cricket' in it in the message text body.
p.s. I dont want to use message selectors.
How can I implement this.
Thanks and Regards.
Take a look at apache camel. It provides a means of routing and filtering messages and has excellent integration with Active MQ.
You can use no mechanism for filtering messages on a topic based on the Message Body contents. Usually a JMS Selector is used for filtering messages but even this does not work for Body Contents:
From The Java EE 6 Tutorial:
A
message selector cannot select messages on the basis of the content of the message body..
The issue here is that you have to first receive (that is consume) the message and then extract its contents which precludes the case of any kind of Body filtering.
You cannot do that with JMS itself.
What you typically do is to make the sending application use different queues depending on message type (orders, customer prospects, invoices, status reports or whatnot). If you don't want to use separate queues, you can at least make the sending application mark the message with some property that you can filter on using a selector.
In some cases, where you still need to do routing and/or filtering based on the actual content of a message, there are tailor made software for that kind of thing. Apache Camel and Mule ESB are two options.
I m implementing Pub/Sub model using JMS. I send a message from Pub to all Subscribers. I want that subscribers should get filtered messages based on some string in actual message body.
For example a subscriber subscribe to a topic 'sports' and should receive only those posts which has keyword 'cricket' in it in the message text body.
p.s. I dont want to use message selectors.
How can I implement this.
Thanks and Regards.
Take a look at apache camel. It provides a means of routing and filtering messages and has excellent integration with Active MQ.
You can use no mechanism for filtering messages on a topic based on the Message Body contents. Usually a JMS Selector is used for filtering messages but even this does not work for Body Contents:
From The Java EE 6 Tutorial:
A
message selector cannot select messages on the basis of the content of the message body..
The issue here is that you have to first receive (that is consume) the message and then extract its contents which precludes the case of any kind of Body filtering.
You cannot do that with JMS itself.
What you typically do is to make the sending application use different queues depending on message type (orders, customer prospects, invoices, status reports or whatnot). If you don't want to use separate queues, you can at least make the sending application mark the message with some property that you can filter on using a selector.
In some cases, where you still need to do routing and/or filtering based on the actual content of a message, there are tailor made software for that kind of thing. Apache Camel and Mule ESB are two options.
I am trying to write an HL7 message parser that will send a specified acknowledgment back to a messaging engine so that my applicaiton may receive the next message in line.
The interface engine that is sending the messages is call VISTA (has anyone ever worked with it?) I have been told that it expects to receive an 'Ackknowledgement ACK' if there is a value in MSH field 15. In all of the messages that I am currently receiving, I am getting a value of 'AL'.
I have basically set up my application to send a TCP message to a hostname/ip:portnumber that can be set before the applicaiton is started.
If possible, could someone provide a sample ACK message (without sensitive data of course) AND the non-whitspace characters that wrap the message?
I would like to make sure that I know what I need to send back to the sending application.
After some further research of my own, and the help of responses to this post, I have found that the following items are required to be included for the sending applicaiton to accept my ACK and move onto the next message.
The ACK must contain the following:
MSH|^~\&|Receiving App|Receiving App ID|Sending App|Sending App ID|DateTime of Message||"ACK"|Message Control ID|Processing ID|Version ID
MSA|AE <or> AR <or> AA|Message Control ID (MSH 9 from the sent message)
ERR| This particular segment is not required by the sending application
The problem I was experiencing pertained to my Sending and Receiving App IDs and Names were swapped.
Thanks for the help!
I haven't worked with VISTA, and my only current setup is returning an error ACK due to some application issue that I won't be able to debug right now, but in case it's helpful here's the error ACK:
MSH|^~\&|||||20100630130105.496-0500||ACK|20||2.3
MSA|AE|H20091222063637.9834
ERR|^^^207&Application Internal Error&HL70357
Note that this is HL7 v2.3 - the format may be different for other versions.