- D365 does not appear to work well with .Net async approaches.
- D365 does not appear to work well with generics.
Once downloaded, open it as a zip file (you may need to change the extension to zip) and extract out the dll. Then add the dll as a reference in D365. Once there, the following class can be used to connect and download messages. Sending messages would use a similar logic. Please note that my requirements were to use Topics and Subscriptions rather than Queues. Also, please note that I save all of the connection parameters in a separate table. That way the system may access different Topic/Subscription combinations as required. Also, if the connection information is changed, then this can be reflected in data.
public class ServiceBusConnect
{
public void new()
{
}
public void receiveMessages(str _topic, str _subscription)
{
str strBody;
System.IO.Stream stream;
System.IO.StreamReader reader;
Microsoft.ServiceBus.Messaging.SubscriptionClient subscriptionClient;
Microsoft.ServiceBus.Messaging.MessagingFactory messagingFactory;
Microsoft.ServiceBus.Messaging.BrokeredMessage message;
ServiceBusConnectionParameters parameters;
select firstonly parameters where parameters.Topic == _topic && parameters.Subscription == _subscription;
ServiceBusConnector.BrokeredMessageProcessor connector = new ServiceBusConnector.BrokeredMessageProcessor();
messagingFactory = Microsoft.ServiceBus.Messaging.MessagingFactory::Create(parameters.ConnectionString,
Microsoft.ServiceBus.TokenProvider::CreateSharedAccessSignatureTokenProvider(parameters.SharedAccessKeyName, parameters.SharedAccessKey));
subscriptionClient = messagingFactory.CreateSubscriptionClient(parameters.Topic, parameters.Subscription);
message = subscriptionClient.Receive(System.TimeSpan::FromSeconds(5));
if(message != null)
setPrefix("Messages");
while(message != null)
{
strBody = connector.GetBrokeredMessageContents(message);
info(strBody);
subscriptionClient.Complete(message.LockToken);
message = subscriptionClient.Receive(System.TimeSpan::FromSeconds(5));
}
subscriptionClient.Close();
}
}
The table ServiceBusConnectionParameters contains all the data for connection to Service Bus. The Topic and Subscription should be based on how your project's service is configured. The connection string will be sb://<your project>.servicebus.windows.net. The SharedAccessKeyName will be what ever is configured in your service bus. The default is RootManageSharedAccessKey. The shared access key is the primary key as displayed on your Service Bus Explorer.
As usual for using .net assemblies in D365, all class references must be fully qualified with their name spaces. The parameter in the subscriptionClient.Receive call is a timeout. If no messages are found within 5 seconds, the call is aborted and the message is set to null. Without it, the system just hangs indefinitely waiting for messages. The call to GetBrokeredMessageContents uses a call to the GetBody method on the message itselft. This method requires a generic reference to type the message. I could not, however, find a way to do that within D365. The wrapper to deserialize the message was pretty straightforward.
using System.IO;
using Microsoft.ServiceBus.Messaging;
namespace ServiceBusConnector
{
public class BrokeredMessageProcessor
{
public string GetBrokeredMessageContents(BrokeredMessage message)
{
string strResult;
using (var stream = message.GetBody<Stream>())
{
using (var reader = new StreamReader(stream))
{
strResult = reader.ReadToEnd();
}
}
return strResult;
}
}
}
No comments:
Post a Comment