Programmatically Update Azure Service Bus Topic - azure

Is it possible to update a Topic programmatically on Azure ServiceBus?
I've tried something along the lines of the following:
var topicName = "myTopic";
var nsManager = NamespaceManager.Create();
var topic = nsManager.TopicExists(topicName)
? nsManager.GetTopic(topicName)
: nsManager.CreateTopic(topicName);
topic.RequiresDuplicateDetection = true;
nsManager.UpdateTopic(topic);
However this fails with ArgumentException and message containing '(400) Bad Request.'
It appears that UpdateTopic can only be used for altering the status of the topic, is this correct? Is there anyway for me to change the Dupe Detection settings without using the Dashboard?

Short answer is: NO, you'll need to recreate the topic. Refer to this Stackoverflow question that deals with ServiceBus queues but essentially applies to your question just as well:
How to change the properties of a service bus queue?

Related

Service Bus SQL Filter apparently not working in Azure Functions v3

I created a topic "Messages" in my service bus instance, and added a new subscription to it. I can send messages to this topic and the Azure Function v3 trigger is activated just fine. The message is received and displayed in an instant.
When I add an sql filter to filter messages for a subscription it is not working anymore.
What I did so far.
Created an sql filter in the azure portal:
sys.Label = "Test" -> Not working as no messages are received anymore, even though I verified that the Label attribute is set.
sys.Label != "Test" Not working as no messages are received anymore, even though I verified that the Label attribute is set and not matching "Test"
sys.To = "Test" -> Not working, no messages are received. Verified that the messages contain the To member.
sys.Label is not Null -> This is strangely working.
What am I doing wrong here?
As stated in the comment, the solution to this question can be found in the Microsoft Q&A.
To prevent a loss of this solution I am going to post it here too:
The SQL filter value should be in single quotes 'test'
Example : sys.To = 'test'
Make sure that you are defining the message system properties while
sending the message to topic.
Source
If someone is caught off guard by the red single quotes. They are just red, but don't indicate that something is wrong with it. It will just work fine.

Azure Service Bus Queue: Can I manage/cancel scheduled messages?

If I schedule a message in the future using something like this:
d = datetime.utcnow() + timedelta(minutes=5)
task = {"some": "object"}
sbs.send_queue_message(
qn,
Message(
task,
broker_properties={'ScheduledEnqueueTimeUtc': d}
)
)
Then is there a way that I can view/delete messages that have been scheduled? send_queue_message doesn't return anything, and receive_queue_message understandably doesn't return items that are scheduled to be queued later - so I can't get hold of it to pass to delete_queue_message for example.
The Azure team seem aware of the usecase because Storage Queues seem to have something like this feature: https://azure.microsoft.com/en-gb/blog/azure-storage-queues-new-feature-pop-receipt-on-add-message/
Basically I need to be able to schedule a message to be queued later, but have this cancelable. Ideally I'd like to be able to also view all future scheduled tasks, but being able to just store an id that can be used to later delete the queued message would be sufficient.
The Azure UI shows the count of active/scheduled messages too, which seems to suggest there should be some way to see those scheduled ones!
Would queue storage be better for this? Or does service bus have some approach that might work? ScheduledEnqueueTimeUtc seems more flexible than the visibility timeout in queue storage so it'd be nice to stick with it if I can.
Yes, it's possible.
Don't know if NodeJS client has support for it or not, but with C# client there's an alternative to ScheduledEnqueueTimeUtc approach I've described here. Using QueueClient.ScheduleMessageAsync() you can send a scheduled message and get the SequenceNumber. Which then can be used to cancel the message at any point in time using QueueClient.CancelScheduledMessageAsync(sequenceNumber).
You can use "Microsoft.ServiceBus.Messaging" and purge messages by en-queue time. Receive the messages, filter by ScheduledEnqueueTime and perform purge when the message has been en-queued at the specific time.
Microsoft.ServiceBus.Messaging;
MessagingFactory messagingFactory = MessagingFactory.CreateFromConnectionString(connectionString);
var queueClient = messagingFactory.CreateQueueClient(resourceName, ReceiveMode.PeekLock);
var client = messagingFactory.CreateMessageReceiver(resourceName, ReceiveMode.PeekLock);
BrokeredMessage message = client.Receive();
if (message.EnqueuedTimeUtc < MessageEnqueuedDateTime)
{
message.Complete();
}
For completeness, this can be done using the storage queue service Python SDK:
from azure.storage.queue import QueueService
account_name = '<snip>'
account_key = '<snip>'
queue_service = QueueService(account_name=account_name, account_key=account_key)
a = queue_service.put_message('queue_name', u'Hello World (delete)', visibility_timeout=30)
print(a.id) # id
print(a.pop_receipt) # pop_receipt
Then in another Python instance before the visibility timeout expires:
queue_service.delete_message('queue_name', id, pop_receipt)

Fastest way to know if a BrokeredMessage from Topic will be received by a subscription receiver

I work with azure Topics/Subscriptions for a project.
And i want to find the fastest solution to know if a BrokeredMessage will be received by 1 subscription at least.
I found a basic solution :
Before to send the message, i call GetRules method to iterate throught sql filters :
var rules = NamespaceMgr.GetRules("topict1", s.Name);
foreach (var ruleDescription in rules)
{
Console.Write(ruleDescription.Name);
var filter = ruleDescription.Filter as SqlFilter;
if(filter != null)
{
expressions.Add(filter.SqlExpression);
}
//...examine exisitngs expressions to know if the message will be handled by a subscription receiver
}
Is there a faster way ?
For example, is there a way to send the message instataneously the message in another queue if he didn't find a receiver to go ?
What you are doing is wrong. Topics are created to decouple publishers and subscribers. Your publisher should not be concerned about the fact if subscribers exist or not. Events are broadcasted, so if no listeners are found, those messages go nowhere.
There's a setting topic setting, TopicDescription.EnableFilteringMessagesBeforePublishing that when is set to true will throw NoMatchingSubscriptionException exception where there are no subscriptions that would be able to process a message. It is not intended for production.

Checking connection to Azure Service Bus

I have some code dependent of Azure Service Bus. I've created an endpoint that checks the availability of my Azure Service Bus topic using the following code:
var connectionString = CloudConfigurationManager.GetSetting("servicebusconnectionstring");
var manager = NamespaceManager.CreateFromConnectionString(connectionString);
var sub = manager.GetSubscription("mytopic", "mysubscription");
var count = sub.MessageCount;
This actually works, but I have two questions (since I'm constantly experiencing timeouts using this code).
Question 1: Is there an easier/better way of checking Service Bus connectivity from C#?
Question 2: When using the code above, which instances should I configure as singleton in my IoC container? I'm suspecting creating all instances every time I ping this endpoint to cause the timeout, since I don't see problems in my other endpoints where I re-use a TopicClient.
Getting MessageCount is potentially an expensive operation, especially if the value is high.
You could run a simple operation like a check whether the topic exists:
var ns = NamespaceManager.CreateFromConnectionString("...");
ns.TopicExists("mytopic");
which will throw an exception (probably MessagingCommunicationException) if communication to Service Bus fails.
It's ok to reuse NamespaceManager between requests, so you can make it singleton. Not sure if that brings any measurable performance benefit though.

Push data from Salesforce to Azure Service Bus

i am looking for a solution for pushing data from salesforce to a azure service bus.
That's what I found:
PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'InvoiceStatementUpdates';
pushTopic.Query = 'SELECT Id, Name, Status__c, Description__c FROM Invoice_Statement__c';
pushTopic.ApiVersion = 36.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
pushTopic.NotifyForFields = 'Referenced';
insert pushTopic;
With this code I can create a PushTopic in Salesforce. If there is any change on Invoice_Statement__c, this topic will send the Id, Name, Status_c and Description_c to all Clients.
The problem is that there is no guarantee that the Client is receiving all messages:
Streaming servers don’t maintain any client state and don’t keep track
of what’s delivered. The client may not receive messages for a variety
of reasons... (Source)
So I wonder if I could send this information (Id,Name...) to a azure service bus. I found this "Help": https://developer.salesforce.com/page/Connecting_Force.com_to_Azure_Service_Bus_Part2
which did not solve my problem.
I wonder if one of you did have the same problem I do.
Hope someone could provide me (and all other guys and girls ;) ) a solution

Resources