Receiving empty bytes array for Imessage.content from Azure service bus - azure

I am currently using two different platforms to perform sync actions. So, when action happens on platform 1 (C# -visual studio), that same action then needs to happen on platform 2 (Java). To do that, I use SB (Azure service bus) for sharing the Json messages between two platforms.
Action 1: platform 1 ----> Service bus -----> platform 2 .
Works fine. The message is sent and received exactly as it should be.
Action 2: platform 2 ----> Service bus ----> platform 1.
Does not work. The message is sent correctly to SB, but when it's picked up, the content property only contains an empty array, when it should be an array of bytes (containing the message). The other message attributes like contentType, replyTo and so on are set correctly, so the message is getting picked up fine. It's just that there is no content or in other words message body.
Action 3: Azure SB/Send messages -----> Service bus -----> platform 1.
Works fine. Another option is to send the JSON message directly to the Service Bus using Azure Service Bus/Send messages and put the JSON message in there.
For actions 2 and 3 exactly the same message is sent to the service bus (when I view it). One is sent directly to service bus, another is generated by the platform 2. I think the actual message somehow seems to be different in the background, which is why the message body is empty in the action 2.
Threads and processes are being handled correctly.
To set up receiver:
IMessageReceiver receive r= null;
if (config.isSessionsEnabled()) {
receiver = ClientFactory.acceptSessionFromConnectionStringBuilder(new ConnectionStringBuilder(connString), config.getSessionID(), ReceiveMode.PEEKLOCK);
} else {
receiver = ClientFactory.createMessageReceiverFromConnectionStringBuilder(new ConnectionStringBuilder(connString), ReceiveMode.PEEKLOCK);
}
For receiving message:
try {
message = receiver.receive(Duration.ofSeconds(1)); //message.Content will be empty array
if(message != null){
//process message
}
} catch (Exception e) {
}
}
Is my understanding correct or perhaps there is another explanation to it!

Is my understanding correct or perhaps there is another explanation to it!
It is very odd that if you send the message from Java platform and the content of message is empty.
Based on my understanding, it seems that message content is empty when you send to ABS. I recommand that you could check the Java send message code before sending to ABS.
You alse could use Azure Service bus exploer to get the message information after it sent to ABS [Before received from .Net platform].

Related

Azure Service Bus - random deserialization issues

I've been recently having problems with my Service Bus queue. Random messages (one can pass and the other not) are placed on the deadletter queue with the error message saying:
"DeadLetterReason": "Moved because of Unable to get Message content There was an error deserializing the object of type System.String. The input source is not correctly formatted."
"DeadLetterErrorDescription": "Des"
This happens even before my consumer has the chance to receive the message from the queue.
The weird part is that when I requeue the message through Service Bus Explorer it passes and is successfully received and handled by my consumer.
I am using the same version of Service Bus either for sending and receiving the messages:
Azure.Messaging.ServiceBus, version: 7.2.1
My message is being sent like this:
await using var client = new ServiceBusClient(connString);
var sender = client.CreateSender(endpointName);
var message = new ServiceBusMessage(serializedMessage);
await sender.SendMessageAsync(message).ConfigureAwait(true);
So the solution I have for now for the described issue is that I implemented a retry policy for the messages that land on the dead-letter queue. The message is cloned from the DLQ and added again to the ServiceBus queue and for the second time there is no problems and the message completes successfully. I suppose that this happens because of some weird performance issues I might have in the Azure infrastructure. But this approach bought me some time to investigate further.

Why do my messages always get delivered to Dead Letter Queue in Azure Service Bus?

C# .NetCore 2.2 -
Azure Service Bus 3.4.0
I have 3 queues in Azure Service Bus with same properties. While sending messages to these queues, the messages in one of the queues always get delivered to Dead letter queues, while other 2 queues receive active messages.
I have tried playing with the properties - increase TTL, maximum delivery count etc. The properties of all 3 queues are same, the only difference is the name of the queues.
I have used this tutorial - https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues
queue properties image
static async Task SendMessagesAsync(int numberOfMessagesToSend)
{
try
{
for (var i = 0; i < numberOfMessagesToSend; i++)
{
// Create a new message to send to the queue.
string messageBody = $"Message {i}";
var message = new Message(Encoding.UTF8.GetBytes(messageBody));
Console.WriteLine($"Sending message: {messageBody}");
// Send the message to the queue.
await queueClient.SendAsync(message);
}
}
catch (Exception exception)
{
Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
}
}
How do I prevent messages from going to Dead Letter Queue? Why does it happen with only 1 queue, not the other 2?
When messages are dead-lettered, there is a reason user property gets added. Check that property to see the reason and troubleshoot accordingly. Specifically, check for DeadLetterReason and DeadLetterErrorDescription custom properties.
The common reasons for a message to be dead-lettered are
Maximum transfer hop count exceeded
Session Id Is Null
TTLExpiredException
HeaderSizeExceeded
The messages might also have got dead-lettered due to some errors while receiving the message from the Queue. As Sean Feldman mentioned, looking into the DeadLetterReason and DeadLetterDescription property will help you diagnose the error reason clearly.
Also try to increase or set the time to live of the message sent if the DeadLetterReason is TTLExpiredException. Because if you have set the time to live of the message to a lower value then it will override the time to live property of the Queue.
Check whether the Queue whether the queue where the messages are getting dead-lettered is a Session enabled queue and the message sent has the Session Id value set.
Without seeing your app / messages it's hard to help. But probably there's an error with the application that is trying to consume the message. As it could not be completed, the message goes to the dead letter queue.
Log the messages from this particular queue and see if there's any missing required properties. Sometimes you're trying to deserialize to an uncompatible type.
The purpose of the dead-letter queue is to hold messages that cannot
be delivered to any receiver, or messages that could not be processed.

Which Azure messaging service to choose to publish with different messages to different subscribers?

From last question about Azure messaging service by publishing one common message to multiply subscribers by using service bus topic. But we've encounter an issue that our message size is over-sized of the service buss limitation(256KB), so we changed our design by splitting the GIANT message into small piece of sub-message and send them to different subscribers, here is what I'd like to achieve:
Let's say we are saving an order object in azure function called SaveOrder and after order was saved successfully, we would like to send different messages(content) to 3 subscribers/consumers which is also implemented/triggered with azure functions,
subscriber/azure function 1 would be using for reporting - with message 1, e.g
{
'reportHeader':'Order Report for ID 012913',
'report_notes':'A few additional report notes...'
}
subscriber/azure function 2 would be using for logging(Sql Server) - with message 2, e.g
{
'logAction':'Order Saved Successfully',
'logTime':'08/12/2019 12:38:12 AM',
'logDescription': 'Order Id - 0139281',
'log_notes':'A few additional log notes...'
}
subscriber/azure function 3 would be using for continuing business logic. - with message 3, e.g
{
'action':'Prepare product accumulation',
'ProductList': {
'813891':3
'581231':1
},
'accumulation_notes':'A few additional accumulation notes...'
}
All of above azure functions subscriber will be working independently/isolated, and our azure function SaveOrder doesn't have to wait for any of these 3 functions, it should exit or terminate once the message publishes.
In this case, which of the messaging service should I choose in Azure for handling that? Would service bus still work here? As my understanding is that Service bus topic would send/publish "same/one" message content to multiply subscribers.
If message1 always only goes to function1, message2 only to function2, and so on, creating 3 Service Bus Queues would suffice. This simply transports the message from a sender to a receiver (function) (FIFO-style).
From SaveOrder, you'd send message1 to queue1, message2 to queue2 etc.
function1 receives messages from queue1.
function2 receives messages from queue2.
function3 receives messages from queue3.
Using topics and subscriptions will also work, by creating 3 topics with 1 subscription each:
From SaveOrder, you'd send message1 to topic1, message2 to topic2 etc.
function1 receives messages from subscription1.
function2 receives messages from subscription2.
function3 receives messages from subscription3.
The second scenario is more flexible, as it allows multiple receivers of the same (copy) message, by adding more subscriptions to the same topic.
Also, you can gzip the payloads of your messages to make transport more efficient.
You can have a separate topic or queue for each of multiple outbound streams. However you should probably publish a single message containing all necessary information to a topic and have three separate consumers do different things with the message.
For instance your function shouldn't be coded to generate an "email notification message" that's not its concern. It should publish an OrderSaved message, and if a service wants to subscribe to that and send emails, it can.

How to catch errors raised in Azure Device SDK?

I am using the Azure Device SDK for .NET Core in order to connect my devices to Azure IoT Hub. From time to time the server rejects some messages (like twin updates or telemetry messages) from the devices and responds with status code 400. As a result there are exceptions thrown on client side but due to its asynchronous nature they are swallowed somewhere inside the Azure SDK and never thrown at my code.
How can I actually be notified about these errors so I can handle and display them?
I can also see from the Azure Device SDK code that it uses some kind of logging (EventSource) but this is never enabled in the code:
From Logging.Common.cs:
Log.IsEnabled() // always returns false
Can you point me to some way where I can 1) actually enable logging in the Azure Device SDK and 2) find the content that was actually logged?
Update: Details regarding exception that is swallowed somewhere
// Fired here after I send twin reported properties to server:
AmqpTransportHandler.VerifyResponseMessage:
if (status >= 400)
{
throw new InvalidOperationException("Service rejected the message with status: " + status);
}
// Then becomes caught and re-fired here:
AmqpTransportHandler.SendTwinPatchAsync:
throw AmqpClientHelper.ToIotHubClientContract(exception);
// Then it disappears somewhere in the "dance" of the async tasks
You can capture traces: https://github.com/Azure/azure-iot-sdk-csharp/tree/master/tools/CaptureLogs
Our sample demonstrates best practice regarding exception catching, for example: https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/samples/DeviceClientMqttSample/Program.cs

Azure Push Notification Works Randomliy

I have mobile application which uses a backend services to register to Azure push notification. Things were working fine until 4 days ago where the most notifications are not delivered to the application.
I'm using Service Bus Queue and WebJob to send the notification and I can see things executed successfully for Android but the notifications most of the time doesn't deliver to the app and the notification State equals Enqueued and Success equals 0 and Failure equals 0
I updated Microsoft.ServiceBus to the latest version but that didn't resolve the issue.
Last thing, Apple notifications used to work successfully but now they are throwing exception "The remote server returned an error: (400) Bad Request. The supplied notification payload is invalid"
Does anyone face similar issues?
I have experienced the same issue when pushing notifications to iOS devices via Azure's Notification Hubs. I received the same error message when calling the "SendAppleNativeNotificationAsync" method on the hub.
I made sure that I had no illegal characters in my message by replacing "\" and "'". After reading a few posts regarding issues with max limit on notifications, we decided to limit our message size to 150 characters (a magic number, we didn't do any research to find out exactly how big a push notification message is allowed to be).
I also changed how the JSON payload was created, and I'm now using Newtonsoft.Json.Linq to create a JSON object with my payload. I previously created a simple json string for the payload, something like this :
var apnsMessage = "{\"aps\":{\"alert\":"+message+", \"sound\" : \"default\", \"badge\" : 1}}";
Now, my JSON object is created as so:
var jsonPayload = JObject.FromObject(new
{
aps = new { alert = message.Replace("\"", "").Replace("'", "") },
sound = "default",
badge = 1
});
and I send the notification like this:
await Hub.SendAppleNativeNotificationAsync(jsonPayload.ToString());
Hope this helps you (or anyone else with the same issue) :)
EDIT:
Here is a simple helper for trimming/truncating strings :)
private static string GetTrimmedAndTruncatedString(string source, int length)
{
return source.Length > length ? source.Substring(0, length) + "..." : source;
}
/Isa

Resources