Sunday 12 November 2017

configuration based queue or topic or subscription name for web job processing

In this post we are going to see how to make a configured based queue or topic or subscription name for webjob processing. for this we have to create a class which implements INameResolver interface.


using Microsoft.Azure.WebJobs;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServiceConsole
{
    class WebJobNameResolver : INameResolver
    {
        public string Resolve(string name)
        {
            var resolvedName = ConfigurationManager.AppSettings[name];
            if (string.IsNullOrWhiteSpace(resolvedName))
            {
                throw new InvalidOperationException("Cannot resolve " + name);
            }
            return resolvedName;
        }
    }
}


Create a two keys in app.config file,specify this keyname in the ServicebusTrigger with covered by %%symbol

<add key="topicname" value="testTopic" />

<add key="subscriptionname" value="rajSubscription"/>

Then we have to change the queue name or topic name or subscription name with covered by %%
symbol.

[ServiceBusTrigger("%topicname%", "%subscriptionname%", AccessRights.Listen)]


using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions;
using Microsoft.ServiceBus.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServiceConsole
{
    public class SampleCreate
    {
        public SampleCreate()
        {

        }

        public async Task Process([ServiceBusTrigger("%topicname%", "%subscriptionname%", AccessRights.Listen)]BrokeredMessage message )
        {
            var data = message.GetBody<Model>();
            var username = message.Properties["Mac"];
            Console.WriteLine("read the message");           
        }
    }
}


Then we have to configure the webjob for resolve these names from our resolver which is created few minutes back. example : NameResolver = new WebJobNameResolver()


var config = new JobHostConfiguration {
                JobActivator = new UnityJobActivator(container),
                NameResolver = new WebJobNameResolver()
            };


config.UseServiceBus(new Microsoft.Azure.WebJobs.ServiceBus.ServiceBusConfiguration {
ConnectionString = ConfigurationManager.ConnectionStrings["ServiceBus"].ConnectionString
            });
         
           

            /* Run the webjob to listen for messages*/
            JobHost host = new JobHost(config);

            host.RunAndBlock();





From this post you can learn how to make a configuration based queue or topic or subscription name for webjob processing.

Creating a Topic and subscription for sending a message and receiving through WebJobs in Azure

In this post we are going to see how to create the Topic and subscription in Azure, and sending a message to topic and receive the message from subscription through Webjob in Azure.

First we will see how to create a webjob, the important thing in webjob is we have to add two connection string in app.config that is AzureWebJobsDashboardAzureWebJobsStorage. in app.config sample

<connectionStrings>
    <add name="ServiceBus" connectionString="" />
    <add name="AzureWebJobsDashboard" connectionString="" />
    <add name="AzureWebJobsStorage" connectionString="" />
  </connectionStrings>

If you miss this connection string then webjob will throw error for missing this key. Next important thing in webjob is

JobHost host = new JobHost(config);

host.RunAndBlock();



Now we got two important thing in webjob. we start coding from program.cs.

using CommonServiceLocator;
using Microsoft.Azure.WebJobs;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.ServiceLocation;

namespace ServiceConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer container = new UnityContainer();
            IServiceLocator locator = new UnityServiceLocator(container);
            ServiceLocator.SetLocatorProvider(() => locator);

            var config = new JobHostConfiguration {
                          JobActivator = new UnityJobActivator(container)
                         };

            config.UseServiceBus(new ServiceBusConfiguration {
                ConnectionString = ConfigurationManager.ConnectionStrings["ServiceBus"].ConnectionString
            });
         
            /* Creating topic and subscription */
            SampleServiceBus.CreateSubscription();

            /* Sending message to Topic */
            SampleSend.SendMessage();
           
            /* Run the webjob to listen for messages*/
            JobHost host = new JobHost(config);
            host.RunAndBlock();
        }
    }
}



We are creating the unity container and pass that to the JobActivator of JobHostConfiguration


Now the next thing is we have to call the config.UseServiceBus and pass the connectionString to it.
Next two lines are creating Topic,Subscription and sending message to Topic, Finally hosting the Job.
This Job is host to monitor the ServiceBusTrigger for certain topic and subscrition, next we will see that.

UnityJobActivator.cs
*************************************
using Microsoft.Azure.WebJobs.Host;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;

namespace ServiceConsole
{
    public class UnityJobActivator : IJobActivator
    {
        private readonly IUnityContainer _container;

        public UnityJobActivator(IUnityContainer container)
        {
            _container = container;
        }

        public T CreateInstance<T>()
        {
            return _container.Resolve<T>();
        }
    }
}



Messaging Model class
*************************************    
public class Model
    {
        public string Name { set; get; }
        public int Id { set; get; }
    }



WebJob Function
********************************************
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions;
using Microsoft.ServiceBus.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServiceConsole
{
    public class SampleCreate
    {
        public SampleCreate()
        {

        }

        public async Task Process([ServiceBusTrigger("testTopic", "rajSubscription",                              
           AccessRights.Listen)]BrokeredMessage message )
        {
            var data = message.GetBody<Model>();
            var username = message.Properties["Mac"];
            Console.WriteLine("read the message");           
        }

        public async Task ErrorHandler([ErrorTrigger("0:00:01", 1)] TraceFilter filter)
        {
            Console.WriteLine(filter.Message);
        }
    }
}

ServiceBusTrigger is the important attribute which will trigger the message received.

In the above code you can see that Topic : testTopic and Subscription : rajSubscription is monitored for message, we can get messages in two way one from GetBody , next from properties


Create Topic and Subscription:
*******************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;

namespace ServiceConsole
{
    public class SampleServiceBus
    {
        private static string _connectionString = ConfigurationManager.ConnectionStrings["ServiceBus"].ConnectionString;

        private static NamespaceManager _manager = NamespaceManager.CreateFromConnectionString(_connectionString);

                  
        public static void CreateSubscription()
        {
            string topicName = "testTopic";
            string subscribtionname = "rajSubscription";
           
            if(!_manager.TopicExists(topicName))
            {
                TopicDescription topicDescription = new TopicDescription(topicName);
                topicDescription.DefaultMessageTimeToLive = new TimeSpan(1, 0, 0, 0);
                topicDescription.AutoDeleteOnIdle = new TimeSpan(1, 0, 0, 0);
                _manager.CreateTopicAsync(topicDescription);
            }

            if (!_manager.SubscriptionExists(topicName, subscribtionname))
            {
                var _subscriptionDescription = new SubscriptionDescription(topicName,                 
                                                   subscribtionname);              
                _manager.CreateSubscriptionAsync(_subscriptionDescription);
            }

        }
    }
}



Sending messages
*******************

using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServiceConsole
{
    public class SampleSend
    {
        private static readonly string _connectionString = ConfigurationManager.ConnectionStrings["ServiceBus"].ConnectionString;

        private static readonly NamespaceManager _manager = NamespaceManager.CreateFromConnectionString(_connectionString);

        public static void SendMessage()
        {
            var _messFac = MessagingFactory.CreateFromConnectionString(_connectionString);

            var topclient = _messFac.CreateTopicClient("testTopic");
            BrokeredMessage message = new BrokeredMessage(new Model()
                                          {Id=1,Name="suresh" });
            message.Properties.Add("Mac", "Dell");
            topclient.Send(message);
        }

    }
}


Here you can see i am sending message using TopicClient from MessagingFactory, i am sending messaging using Model class which can be deserialized in the receiving side, and also i am sending value in properties, Now we will see how the messages will be seen in servicebus eXplorer.




You can see in debug the message is deserialized to Model again.








From this post you can learn how to create the Topic and subscription through code and run a webjob to receive that message from subscrition