Prash's Blog

Introduction to NServiceBus – Part 2 July 29, 2014

Filed under: C# — prazjain @ 7:59 pm
Tags: ,

Service Bus Host

 

In the previous post, we have created project to send messages on nservicebus, now we will create a project to host the service bus.

Create a class library project “App.Backend”, in solution “ServiceBus”. Add reference to “App.Contracts” project in this new project.

Right Click on “References” -> “Manage NuGet References”. Search online for “NServiceBus RavenDB” and add it.

Right Click on “References” -> “Manage NuGet References”. Search online for “NServiceBus Host” and add it.

This auto-generates a class “EndpointConfig” class. This class configures this endpoint and assigns it the role of server. A host can have more than one endpoint and an endpoint can have only one queue for it.

Lets add a class that will handle messages sent by our earlier application

Create a class PlaceOrderHandler, which just prints out the order id for now

    public class PlaceOrderHandler : IHandleMessages<PlaceOrder>
    {
        public void Handle(PlaceOrder message)
        {
            Console.WriteLine("Order received : " + message.OrderId);
        }
    }

IHandleMessages interface of NServiceBus tell the bus, this implementation will process the message of type (as specified in generic args).

 

Housekeeping

 

Lets cleanup the queues created earlier, so we see new queues there.

In “Console.Request” client project from previous post -> “App.Config”, update the UnicastBusConfig section as follows:

  <UnicastBusConfig>
    <MessageEndpointMappings>
      <add Messages="App.Contracts" Endpoint="App.Backend" />
    </MessageEndpointMappings>
  </UnicastBusConfig>

 

Now is the time to run this application.

Set App.Backend as startup project and start it in debug mode.

Now navigate to the exe for “Console.Request” project and run it.

Once they are both up, you will see output like this :

Console.Request output

Generated new Order id : 7417a25b-c278-46ab-bb35-758177ca822d

App.Backend output

Order received : 7417a25b-c278-46ab-bb35-758177ca822d

Check the queues created, it will look something like this:

check queues

 

These queues were generated by the host project when it started up, and Audit queue contains the message that was sent and processed above.

 

Advanced Concepts

 

Fault Tolerance

 

Our Console.Request application may send a message and continue doing about its business, but while processing the message in App.Backend database transaction is rolled back due to database failure or application crash, then we may loose the message.

So we want to make sure when our database rolls back, our queue also rolls back. Similarly when our database commits, our queue also commits (as in removes the message). NService Bus provides following options to deal with such cases:
Simple Retrying can solve transient exceptions like deadlock in database

<MsmqTransportConfig MaxRetries="5"/>

 

Second level retries (SLR) like database is down and will come back up in couple of seconds or minutes

<SecondLevelRetriesConfig Enabled="true" TimeIncrease="00:00:05" NumberOfRetries="2"/>

 

Messages that always fail are moved to an error queue

<MessageForwardingInCaseOfFaultConfig ErrorQueue="error"/> <!-- for remote server : error@remotemachine -->

For permanent exceptions like message deserialization, nservice bus will not even re-try and move them to error queue directly.

To see what will happen when you add above settings in your App.Backend project -> app.config, change PlaceOrderhandler.cs class as follows:

    public class PlaceOrderHandler : IHandleMessages<PlaceOrder>
    {
        public void Handle(PlaceOrder message)
        {
            throw new Exception("Exception occurred");
            Console.WriteLine("Order received : " + message.OrderId);
        }
    }

Now run App.Backend in debug mode, and navigate to Console.Request.exe path and run it as well.

You will notice that when you sent Order through Console.Request, App.Backend threw an exception in Handle method above. This method will be call 5 times in quick succession because of MsmqTransportConfig maxRetries configuration. If still not succeeding then Second Level Retries (SLR) kick-in they further enable another 5 retries, if that fails it SLR makes another try after 5 seconds as configured which enabled further 5 retries as configuration in MsmqTransportConfig.

When all tries fail, the message is saved in ErrorQueue=”error” as configured above. (You can navigate to the queues and check the saved message there for its contents).

Now lets say, the problem has been fixed and we want to process the messages which were ignored earlier. (remove the line – throw new Exception(“Exception occurred”); )

For this you will need to install “NServiceBus Tools” nuget package.

 

Move the error messages from error queue back to their source queues, run this executable :

<SolutionDirectory>\ServiceBus\packages\NServiceBus.Tools.4.4.3\ReturnToSourceQueue.exe

 

This will move the message back to the incoming queue for App.Backend application.

Now run the App.Backend application (if it is not already running), and you will see, it picks up the messages from its incoming queue and processes them as usual.

 

Distributed Transactions

 

Let’s ensure Network DTC is enabled. Go to “Component Services” from Windows start menu.

dtc_enabled

Install “RavenDB Client” package in App.Backend project.

Now update PlaceOrderHandler.cs as follows to save some data in RavenDB. Code is self explanatory. (place both classes below in same file, unless you want to create a separate file for Order class with just one property)

public class PlaceOrderHandler : IHandleMessages<PlaceOrder>
    {
        public void Handle(PlaceOrder message)
        {
            // Initialize the data store, point url to where db is listening
            var store = new DocumentStore { Url = "http://localhost:8080", DefaultDatabase = "App.Backend" };
            store.Initialize();
            using (var session = store.OpenSession())
            {
                session.Store(new Order() { OrderId = message.OrderId });
                session.SaveChanges();
            }
            //throw new Exception ("Exception!");
            Console.WriteLine("Order received : " + message.OrderId);
        }
    }

    public class Order
    {
        public Guid OrderId { get; set; }
    }

Now run the App.Backend project, and navigate to Console.Request.exe and run it to send request.

When you see request generated and processed, navigate to http://localhost:8080 and check documents to see the newly inserted Order object.

To see how exception handling and transaction work, uncomment Exception line in PlaceOrderHandler.Handle method and run App.Backend again.

This time you will when handling a new order from Console.Request, App.Backend throws exception and goes through all the retry logic (as configured), but no data is saved!

Even though we had a session.SaveChanges() call, no data was saved in RavenDB, this is because NServiceBus encloses each message handling method inside a transaction. So if a message handler completes successfully, transaction is committed else transaction is rolledback.

(You can now comment out the exception line again before proceeding ahead)

 

Dependency Injection

 

If you look at our PlaceOrderHandler class, you can see we instantiate DocumentStore and Session objects there. These are good candidates for dependency injection.

Update the PlaceOrderHandler code as below:

 public class PlaceOrderHandler : IHandleMessages<PlaceOrder>
    {
        public IDocumentStore Store { get; set; }
        public IDocumentSession Session { get; set; }
 
        public void Handle(PlaceOrder message)
        {
            Session.Store(new Order() { OrderId = message.OrderId });
            Session.SaveChanges();
            Console.WriteLine("Order received : " + message.OrderId);
        }
    }

Now lets add a class RavenBootstrapper.cs in App.Backend project, which will instantiate these dependencies and register them with NServiceBus container. NServiceBus container will then inject them into PlaceOrderHandler properties. Below is the code for RavenBootstrapper.cs:

public class RavenBootstrapper : INeedInitialization
    {
        public void Init()
        {
            Configure.Instance.RavenDBStorage("RavenDB", "App.Backend");
            Configure.Instance.Configurer.ConfigureComponent<IDocumentStore>(
                () =>
                    {
                        // Initialize the data store, point url to where db is listening
                        var store = new DocumentStore { Url = "http://localhost:8080", DefaultDatabase = "App.Backend" };
                        store.Initialize();
                        store.JsonRequestFactory.DisableRequestCompression = true;
                        return store;
                    }
                    , DependencyLifecycle.SingleInstance);

            Configure.Instance.Configurer.ConfigureComponent<IDocumentSession>(() =>
                {
                    return Configure.Instance.Builder.Build<IDocumentStore>().OpenSession();
                }
                , DependencyLifecycle.InstancePerCall);

        }
    }

INeedInitialization interface, as the name suggests, says to NServiceBus that it needs to be initialialized. It is here that we have configured and registered a DocumentStore and DocumentSession.

DocumentStore has dependency lifecycle of SingleInstance because we only need one instance of DataStore for the life of this application, but DocumentSession has dependency lifecycle of InstancePerCall because this needs to be instantiated for every call.

In NServiceBus a single message can have multiple handlers, so a single Order message above can be sent to multiple handlers. In such cases we do not want to have SaveChanges() call in every handler, we can have it once at the end, when all handlers have been invoked for that message.

So now lets update PlaceOrderHandler Handle method as below:

public void Handle(PlaceOrder message)
        {
            Session.Store(new Order() { OrderId = message.OrderId });
            Console.WriteLine("Order received : " + message.OrderId);
        }

To make sure SaveChanges is called on Session, update the RavenBootstrapper.cs file as below:

namespace App.Backend
{
    public class RavenBootstrapper : INeedInitialization
    {
        public void Init()
        {
            Configure.Instance.RavenDBStorage("RavenDB", "App.Backend");
            Configure.Instance.Configurer.ConfigureComponent<IDocumentStore>(
                () =>
                    {
                        // Initialize the data store, point url to where db is listening
                        var store = new DocumentStore { Url = "http://localhost:8080", DefaultDatabase = "App.Backend" };
                        store.Initialize();
                        store.JsonRequestFactory.DisableRequestCompression = true;
                        return store;
                    }
                    , DependencyLifecycle.SingleInstance);

            Configure.Instance.Configurer.ConfigureComponent<IDocumentSession>(() =>
                {
                    return Configure.Instance.Builder.Build<IDocumentStore>().OpenSession();
                }
                , DependencyLifecycle.InstancePerUnitOfWork);

            Configure.Instance.Configurer.ConfigureComponent<RavenUnitOfWork>(DependencyLifecycle.InstancePerUnitOfWork);
        }
    }

    public class RavenUnitOfWork : IManageUnitsOfWork
    {
        public IDocumentSession Session { get; set; }

        public void Begin()
        {
            
        }

        public void End(Exception ex = null)
        {
            if (ex==null) Session.SaveChanges();
        }
    }
}

Over here, we have created a RavenUnitOfWork, which implements IManageUnitsOfWork, this is registered with NServiceBus which manages its lifecycle as InstancePerUnitOfWork (i.e per message processing across multiple handlers).

We have also update the dependency life cycle of DocumentSession to be InstancePerUnitOfWork, because now we want instance to be created / disposed only once after the message has been processed through all its handlers (rather instantiating and disposing than per handler).

 

Lets conclude the post here, in this post we have seen:

  • How to write a backend application using NServiceBus
  • How to deal with exception handling and recover unprocessed messages.
  • How to interact with database.
  • How to use Dependency Injection
 

Introduction to NServiceBus July 28, 2014

Filed under: C# — prazjain @ 4:39 pm
Tags: ,

It is a light weight communication framework used generally in a heterogeneous environment where different applications, all using different technologies, need to communicate with each other.

What is a ServiceBus
When do I need one

 

Getting Binaries

 

  • Download NServiceBus.
    • From the installation options, just select NServiceBus (and unselect the rest, we do not need them for this tutorial). This will also setup MSMQ, Distribute Transaction Coordinator (DTC), RavenDB database, Performance counters, Lucene etc.
    • RavenDB will get installed as windows service, stop the windows service. Install latest version of Raven from official website. Navigate to services and make sure it is now running latest version of RavenDB.
    • Check RavenDB is setup by visiting url : http://localhost:8080/raven/studio.html

RavenDB home page

  • Check queues under Computer Management -> Services and Application -> Message Queuing. (Right click on “My Computer” -> Manage : To reach at Computer Management screen)

Computer Management - Queues

  • Install NuGet Package Manager
    • Go to Visual Studio -> Tools -> Extension and Updates and download as depicted below

Install NuGet Package Manager

Preparation

 

  • ¬†Lets create a console project and call it Console.Request and name the solution ServiceBus. This project will contain code that generates messages.

Console.Request project

  • Now that we have defined our Message, let go back to Console.Request project and use this message type.In Console.Request project, open App.config file and add the below code:
      <configSections>
     <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core"/>
     </configSections>
     
     <UnicastBusConfig>
     <MessageEndpointMappings>
     <add Messages="App.Contracts" Endpoint="backendQueue" />
     </MessageEndpointMappings>
     </UnicastBusConfig>
    

    The above configuration allows any messages defined in namespace App.Contracts to be sent to “backendQueue”. This allows us to change the destination of messages based on their type, without changing the code.

    Until now, we have defined a message type and associated a queue with particular types of messages. To be able to send message we need to write code to send it. Add OrderGenerator class as below to Console.Request project:

    public class OrderGenerator
     {
     public OrderGenerator()
     {
     // Lets configure the bus using Fluent API
     Bus = Configure.With().Log4Net().DefaultBuilder().UseTransport&lt;Msmq&gt;().UnicastBus().SendOnly();
     }
     
     public IBus Bus { get; set; }
     
     public Guid NewOrder()
     {
     var order = new PlaceOrder
     {
     OrderId = Guid.NewGuid(),
     ProductId = Guid.NewGuid(),
     CustomerId = Guid.NewGuid()
     };
     
     Bus.Send(order);
     return order.OrderId;
     }
     }
    

    Next, update your Program.cs file in Console.Request as follows:

    class Program
     {
     static void Main(string[] args)
     {
     OrderGenerator orderGenerator = new OrderGenerator();
     while (true)
     {
     System.Console.WriteLine("Generated new Order id :" + orderGenerator.NewOrder());
     System.Console.ReadLine();
     }
     }
     }
    

    Now lets run the code we have so far. You are on right track if you see message as below:

Queue_not_exists

  • Include NServiceBus libraries in the project
    • Go to Visual Studio -> View -> OtherWindows -> Package Manager Console. Run the command on prompt
      PM> install-package nservicebus
    • Messages are common types that will be needed by all projects / libraries. So we will create messages in a separate library project.
      • Create a new library project “App.Contracts”.
        • Go to Package Manager Console. Run the command
          PM> install-package nservicebus-interfaces

          In this project we do not need the entire nservice bus library package, we just need the interface to define nservice bus messages, so we install just the interfaces.

      • Lets create a sample message as below:
        namespace App.Contracts
        {
            /// &lt;summary&gt;
            /// This is a message type. Any NServiceBus message needs to implement marker interface IMessage.
            /// &lt;/summary&gt;
            public class PlaceOrder : IMessage
            {
                public Guid ProductId { get; set; }
                public Guid OrderId { get; set; }
                public Guid CustomerId { get; set; }
            }
        }
        

 

In NServiceBus, it is the responsibility of the hosting process to create the queue. Until now we have only written the requesting process, so the queue does not exists and requesting process is surely complaining about it.

Lets go ahead and create the queue ourselves. Create a private transactional queue as shown below, as NServiceBus uses private and transactional queues.

create backendQueue

Once the queue is created, run the program again. (Press enter a few times to generate more messages) If it has completed successfully, you can check the queue again (refresh if needed).

 

Output

 

Console will show message like this:

Generated new Order id : 21217e71-1ec0-4c1b-a333-38a9b7d9c6a8

Message queue will look like this:

backendQueue message body

Xml is a bit like this:

<?xml version="1.0"?>
<Messages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.net/App.Contracts">
 <PlaceOrder>
 <ProductId>27a06c53-13d1-42f5-8cbf-f875742f540e</ProductId>
 <OrderId>21217e71-1ec0-4c1b-a333-38a9b7d9c6a8</OrderId>
 <CustomerId>1f83a791-36ff-4f0d-8bf2-bff8134e406e</CustomerId>
 </PlaceOrder>
</Messages>

This is it!

We wrote ‘producer’ application (application generating messages) that can send messages using NServiceBus, to be used by another application.

In the second part to this post, we will see how a ServiceBus Host application is written using NServiceBus. This second application can then be used to process messages we have in the queue.

 

Seed Funding Vs Series A Funding for tech startups July 25, 2014

Filed under: Uncategorized — prazjain @ 6:32 pm
Tags: , , , ,

Good knowledge base of legal know how for tech startups.

http://www.taylorwessing.com/twtechfocus/

http://www.taylorwessing.com/twtechfocus/seed.php

http://www.taylorwessing.com/twtechfocus/seed2.php

http://www.taylorwessing.com/twtechfocus/seed3.php

 

Insufficient Storage Space Available on Android when installing apps June 27, 2014

Filed under: Android — prazjain @ 5:39 pm

I tried quite a few things like uninstalling apps, moving apps to SD card but this error keeps coming back.
Here is what worked for me:


Open the Phone app and switch to Keypad.
Dial *#9900#
On the screen that appears, click on the button labelled "Delete dumpstate/logcat".

 

How to show message count on app icon in Android June 6, 2014

Filed under: Android — prazjain @ 9:08 pm
Tags:

I was curious about how whatsapp and facebook showed a count of unread messages or notifications on app icon in Android, and I wanted to find that out for myself.

It is explained well in the link below.


//This is for samsung touchwiz

public static void setBadge(Context context, int count) {
    String launcherClassName = getLauncherClassName(context);
    if (launcherClassName == null) {
        return;
    }
    Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
    intent.putExtra("badge_count", count);
    intent.putExtra("badge_count_package_name", context.getPackageName());
    intent.putExtra("badge_count_class_name", launcherClassName);
    context.sendBroadcast(intent);
}

public static String getLauncherClassName(Context context) {

    PackageManager pm = context.getPackageManager();

    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);

    List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
    for (ResolveInfo resolveInfo : resolveInfos) {
        String pkgName = resolveInfo.activityInfo.applicationInfo.packageName;
        if (pkgName.equalsIgnoreCase(context.getPackageName())) {
            String className = resolveInfo.activityInfo.name;
            return className;
        }
    }
    return null;
}

Sony devices use a class named BadgeReciever.
Declare the com.sonyericsson.home.permission.BROADCAST_BADGE permission in your manifest file:
Broadcast an Intent to the BadgeReceiver:

Intent intent = new Intent();

intent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", "com.yourdomain.yourapp.MainActivity");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", true);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", "99");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", "com.yourdomain.yourapp");

sendBroadcast(intent);

Done. Once this Intent is broadcast the launcher should show a badge on your application icon.

To remove the badge again, simply send a new broadcast, this time with SHOW_MESSAGE set to false:


intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", false);

More details in the links below

stackoverflow.com how-to-display-count-of-notifications-in-app-launcher-icon

android-notification-badge-app-icon-sony/

 

Ways to improve performance of wpf application March 10, 2014

Filed under: Uncategorized — prazjain @ 5:14 pm

Ways to improve performance of wpf application

Nice article about ways you can improve performance of your wpf application.

 

 

Visual Studio 2013 builds fine but Resharper 7 shows errors February 18, 2014

Filed under: C# — prazjain @ 9:59 am
Tags: , ,

I hit this problem while doing some massive refactoring on my VS 2013 solution. Visual studio showed build successful, but resharper had 400+ errors. This is how i resolved it:

Menu -> Tools -> Options -> Resharper -> Suspend

Delete Resharper cache -> [User]/AppData/Local/JetBrains/v7.1/SolutionCache

Menu -> Tools -> Options -> Resharper -> Resume

 

 
Follow

Get every new post delivered to your Inbox.

Join 25 other followers