propagate OpenTracing TraceIds from publisher to consumer using MassTransit.RabbitMQ - .net-core

Using MassTransit.RabbitMQ v5.3.2 and OpenTracing.Contrib.NetCore v0.5.0.
I'm able publish and consume events to RabbitMQ using MassTransit and I've got OpenTracing working with Jaeger, but I haven't managed to get my OpenTracing TraceIds propogated from my message publisher to my message consumer - The publisher and consumer traces have different TraceIds.
I've configured MassTransit with the following filter:
cfg.UseDiagnosticsActivity(new DiagnosticListener("test"));
I'm not actually sure what the listener name should be, hence "test". The documentation doesn't have an example for OpenTracing. Anyways, this adds a 'Publishing Message' span to the active trace on the publish side, and automatically sets up a 'Consuming Message' trace on the consumer side; however they're separate traces. How would I go about consolidating this into a single trace?
I could set a TraceId header using:
cfg.ConfigureSend(configurator => configurator.UseExecute(context => context.Headers.Set("TraceId", GlobalTracer.Instance.ActiveSpan.Context.TraceId)))
but then how would I configure my message consumer so that this is the root TraceId? Interested to see how I might do this, or if there's a different approach...
Thanks!

If anyone is interested; I ended up solving this by creating some publish and consume MassTransit middleware to do the trace propagation via trace injection and extraction respectively.
I've put the solution up on GitHub - https://github.com/yesmarket/MassTransit.OpenTracing
Still interested to hear if there's a better way of doing this...

Related

Is it possible to use message Pact for ActiveSupport::Notification messages?

Message Pact is non Http approach, see for more details:
https://docs.pact.io/getting_started/how_pact_works#non-http-testing-message-pact
ActiveSupport::Notification - is part of [Rails ActiveSupport][1], see for more details:
https://apidock.com/rails/ActiveSupport/Notifications
As I understand, ActiveSupport::Notification is using memory for a queue underneath, but not the external requests that are expected by Pact, so probably it can be done only via some other Message Queue, like Kafka, for example:
ActiveSupport::Notifications.subscribe("my_message") do |payload|
Kafka.produce(queue: 'test-queue', message: payload)
end
where Kafka.produce can be handled by Pact.
However, in this way, there is makes sense to remove ActiveSupport::Notifications and keep using only Kafka but this is the next step.

Could not create internal topics - Stream-thread exception

I am trying to execute a simple Wordcount stream application but I face the error "Could not create internal topics - Stream-thread exception"
I have seen a similar thread but that seems to be more of a network issue.
Here is no security enabled on the kafka broker.
Only one broker is configured and still this issue.
Can someone let me know how to fix this?
Clean your temporary kafka queues.
Run --list command on kafka to see all the queues starting with your names and ending with -changelog & -repartition and manually run delete on them.
This one worked for me.
Also, check your settings on delete.topic.enable for actual deletion happening. It was not the default setting until 1.0.0 - see https://issues.apache.org/jira/browse/KAFKA-5384
i have connected to kafka using kafka tool and delete them manually

How to dispatch message to several destination with apache camel?

My problematic seem to be simple, but I haven't find yet a way to solve it...
I have a legacy system which is working and a new system which will replace it. This is only rest webservices call, so I'm using simple bridge endpoint on http service.
To ensure the iso-functional run, I want to put them behind a camel route dispatching message to both system but returning only the response of the legacy one and log the response of both system to be sure there are running in same way...
I create this route :
from("servlet:proxy?matchOnUriPrefix=true")
.streamCaching()
.setHeader("CamelHttpMethod", header("CamelHttpMethod"))
.to("log:com.mylog?showAll=true&multiline=true&showStreams=true")
.multicast()
.to(urlServer1 + "?bridgeEndpoint=true")
.to(urlServer2 + "?bridgeEndpoint=true")
.to("log:com.mylog?showAll=true&multiline=true&showStreams=true")
;
It works to call each services and to log messages, but response are in a mess...
If the first server doesn't respond, the second is not call, if the second respond an error, only that error is send back to client...
Any Idea ?
You can check for some more details in multicast docs http://camel.apache.org/multicast.html
Default behaviour of multicast (your case) is:
parallelProcessing is false so routes are called one by one
To correctly implement your case you need probably:
add error handling for each external service call so exception will not stop correct processing
configure or implement some aggregator strategy and put it to the strategyRef so you can combine results from all calls to the single multicast result

Getting "Resource not found error" while using Azure File Sync

Facing a very strange issue.
Following this guide https://azure.microsoft.com/en-in/documentation/articles/app-service-mobile-xamarin-forms-blob-storage/ to implement File Sync in Xamarin Forms app.
The Get method in my service (GetUser, default get method in App service controller) is being called thrice & on the 3rd iteration it gives me a 404 resource not found error. First 2 iterations work fine.
This is the client call
await userTable.PullAsync(
null,
userTable.Where(x => x.Email == userEmail), false, new System.Threading.CancellationToken(), null);
If I remove the following line,
// Initialize file sync
this.client.InitializeFileSyncContext(new TodoItemFileSyncHandler(this), store);
then the code works just fine, without any errors.
I will need some time doing a sample project, meanwhile if anyone can shed some light, it will be of help.
Thanks
This won't be an answer, because there isn't enough information to go on. When you get a 404, it's because the backend returned a 404. The ideal situation is:
Turn on Diagnostic Logging in the Azure Portal for your backend
Use Fiddler to monitor the requests
When the request causes a 404, look at what is actually happening
If you are using an ASP.NET backend (and I'm assuming you are because all the File tutorials use ASP.NET), then you can set a breakpoint on the appropriate method in the backend and follow it through. You will need to deploy a debug version of your code.
this is sorted now, eventually I had to give it what it was asking for. I had to create a storage controller for User too, although I don't need one as I don't need to save any files in storage against the users.
I am testing the app further now to see if this sorts my problem completely or I need a storage controller for every entity I use in my app.
In which case it will be really odd as I don't intend to use the storage for all my entities.

BizTalk TPE continuations and uncompleted activities

Within my BizTalk 2010 solution I have the following orchestration that’s is started by the receipt of a courier update message. It them makes a couple of call to AX's WCF AIF via two solicit-response ports, a Find request and an Update request.
For this application we are meeting audit requirements through use of the tracking database to store the message body. We are able to link to this from references provided in BAM when we use the TPE. The result for the customer is nice, they get a web portal from which they can view BAM data of message timings etc. but they can also click a link to pull up a copy of the message payloads from the tracking db. Although this works well and makes use of out-of-box functionality for payload storage it has led to relatively complex jobs for the archiving of the tracking db (but that's another story!).
My problem relates to continuation. I have created the following Tracking Profile:
I have associated the first of the orchestration's two solicit response ports with the continuation RcvToOdx based on the interchange Id and this works, I get the following single record written to the Completed activity table:
So, in this case we can assume that an entry was first written on receipt in the inbound message, with the TimeReceivedIntoBts column populated by the physical file receive port. The FindRequestToAx column was then populated by the physical WCF send port. Because this was bound to the RcvToOdx continuation Id and used the same interchange Id and the previously mentioned file receive message, the update was made to the same activity. Notification of the resulting response was also updated to the same activity record - into the FindResponseFromAx column.
My problem is that I would also like BAM to record a timestamp for the subsequent UpdateRequestToAx. Because this request will have the same interchange Id as the previous messages I would expect to be able to solve this problem by simply binding the AxUpdate send port (both send and receive parts of it) to the same continuation id, as seen in the following screen grab:
I also map the UpdateRequestToAx milestone to the physical Ax_TrackAndTraceUpdate_SendPort (Send) and the OrchestrationCompleted milestone to Ax_TrackAndTraceUpdate_SendPort (Receive)
Unfortunately, when I try this I get the following result:
Two problems can be seen from the above db screen grab:
1. Date for the update send port was inserted into a new activity record
2. The record was never completed
I was surprised by this because I'd thought since they update port was enlisted to use the same continuation, and the single InterchangeId was being used by all ports for the continuation Id then all the data milestones would be applied to a single activity.
In looking for a solution to this problem I came across the following post on Stack Overflow suggesting that the continuation must be closed from the BAM API: BAM Continuation issue with TPE. So, I tried this by calling the following method from an expression shape in my orchestration:
public static void EndBAMContinuation(string continuationId)
{
OrchestrationEventStream.EndActivity(CARRIER_ORDER_ACTIVITY_NAME, continuationId);
}
I can be sure the method was called ok because I wrapped the call with a log entry from the CAT framework which I could see in debug view:
I checked the RcvToOdx{867… continuation Id against the non-closed activity and confirmed they matched:
This would suggest that perhaps the request to end the continuation is being processed before the milestone of the received message from the UpdateAx call?
When I query the Relationsips tables I get the following results:
Could anyone please advise why the UpdateToAx activity is not being completed?
I realise that I may be able to solve the problem using only the BAM API but I really want to exhaust any possibility of the TPE being fit for purpose first since the TPE is widely used in other BizTalk solutions of the organisation.
To solve this problem I created a 2nd continuation in the TPE.
"RcvToOdx" continuation for the Find and "OdxToUpdate" continuation for the update - source is InterchangeId on the initial receive port - UPS_TrackAndTrace (same as for other "RcvToOdx" continuation), dest Id is the InterchangeId mapped to update send port.

Resources