Monday 31 October 2016

EventHub - No connection could be made because the target machine actively refused it 127.0.0.1:10000

I recently trying out a simple POC that listens to messages from Azure EventHub. I referred to the online documentation and everything was very simple to set up.

I set up separate policies for Listen and Send and used those to set up simple code that sends and listens to a message. The code was fairly simple but it failed :)

        static string eventHubName = "eventhub1";
        static string listeneventHubConnectionString = "";
        static string sendeventHubConnectionString = "";
        static string storageConnectionString = "UseDevelopmentStorage=true";

        static void Main(string[] args)
        {

            Console.WriteLine("Press Ctrl-C to stop the sender process");
            Console.WriteLine("Press Enter to start now");
            Console.ReadLine();
            SendingRandomMessages();

            string eventProcessorHostName = Guid.NewGuid().ToString();
            EventProcessorHost eventProcessorHost = new EventProcessorHost(eventProcessorHostName, eventHubName, EventHubConsumerGroup.DefaultGroupName, listeneventHubConnectionString, storageConnectionString);
            Console.WriteLine("Registering EventProcessor...");
            var options = new EventProcessorOptions();
            options.ExceptionReceived += (sender, e) => { Console.WriteLine(e.Exception); };
            eventProcessorHost.RegisterEventProcessorAsync(options).Wait();

            Console.WriteLine("Receiving. Press enter key to stop worker.");
            Console.ReadLine();
            eventProcessorHost.UnregisterEventProcessorAsync().Wait();

       }

Here is the exception:

{"Unable to connect to the remote server"}



At first the exception seemed a little misguiding - you get an impression that eventhub is not reachable or you have typed the connectionstring incorrectly. However, if you look at the error stack details, it turns out that Azure Storage Emulator is not started on the machine :). You get more hints when you start digging into the exception details.


{"No connection could be made because the target machine actively refused it 127.0.0.1:10000"}  
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndGetResponse[T](IAsyncResult getResponseResult)


Saturday 15 October 2016

Unit testing Azure Table Storage

This one is a little less explored as far as Internet Search goes. How do you mock a Azure Table Storage operations?

I recently ran into this problem and thought of documenting the steps required to easily Shim the Azure Table Storage. I used MSTest and Microsoft Fakes for creating Shim.


Once Fake is added, Add Shims for Azure Table Storage related classes. Few parts are highlighted in yellow as those parts let you control what data is queried upon. Once you have bound the observable source to ShimTableQuery, even the dynamic filters applied in your ATS queries get applied on the mock data.

[TestInitialize]
public void Initialize()
{
                ShimsContext shimsContext = ShimsContext.Create();

                ShimCloudStorageAccount.ParseString = s => new ShimCloudStorageAccount();

                ShimCloudStorageAccount.AllInstances.CreateCloudTableClient = account => new ShimCloudTableClient();

                ShimCloudTableClient.AllInstances.GetTableReferenceString = (client, s) => new ShimCloudTable();

                ShimTableOperation.InsertOrMergeITableEntity = entity => new ShimTableOperation(); // Insert,Update Shim

                ShimTableResult.Constructor = result => new ShimTableResult();

                ShimTableResult.AllInstances.ResultGet = result => new Entity(); // The entity mapped to the storage.

                ShimCloudTable.AllInstances.CreateIfNotExistsAsync = table => Task.FromResult(true);

                ShimCloudTable.AllInstances.ExecuteAsyncTableOperation =
                    (table, operation) => Task.FromResult(new ShimTableResult().Instance);
               
                var q = new ShimTableQuery();
                q.Bind(
entities); // observable collection of entities that you want to reflect in shim table storage.

                ShimCloudTable.AllInstances.CreateQueryOf1<Entity>((table) => q);
}

[TestCleanup]
public void Cleanup()
{
            shimsContext?.Dispose();
}

Now - good thing is that there is nothing to be changed in the code. Your code should work against both actual ATS and Shim ATS.

Wednesday 12 October 2016

oData like filtering and paging in ASP.NET Web API

oData is quite nice. It lets you present a query and filter friendly REST API endpoint by providing you a standard you can stick to. What's more - there is a great set of tooling available in you want to bind your datasource wrappers/providers like EntityFramework or otherwise if you are building your WebAPIs using ASP.NET MVC. It is specifically helpful if you want to add "free" filtering and paging abilities in your WebAPI. The Queryable data source and oData model binder takes care of it for you.

However, when you want to build real world application, often you do not want to expose your data source directly or sometimes it is not practical at all. In those scenarios if you want to support oData like filtering and paging capabilities in your WebAPI action, then it is a little more involved.

There are some options available.

1. Build a IQueryable data source and expose that. It is not practical in most of the cases though.
2. Build a custom model binder that can pick the paging and filtering expressions from QueryString and bind it to a custom model parameter before executing the WebAPI action.

Help links: Link # 1, Link # 2

Here is a simple run down.

Create a simple FilterModel class (you can build similar paging model too).

public class FilterModel
{
        public Dictionary FilterCriteria { get; set; }
}

Create a simple FilterModelBinder class that implements IModelBinder interface.

public class FilterModelBinder : IModelBinder
    {
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType != typeof(FilterModel))
            {
                return false;
            }
            FilterModel model = new FilterModel();
            model.FilterCriteria = new Dictionary();
            var qs = actionContext.Request.GetQueryNameValuePairs();
            foreach (var kv in qs)
            {
                model.FilterCriteria.Add(kv.Key, kv.Value);
            }
            bindingContext.Model = model;
            return true;
}

Bind the specific WebAPI action's parameter with custom modelbinder.

public string Get(int id, [ModelBinder(typeof(FilterModelBinder))] FilterModel model)
        {
            return "value";
        }

Now, you can try a url like: http://localhost:3539/api/values/5?firstname eq 'David'&pageNumber=10

You can see the filtering and paging criteria gets populated and passed on to the WebAPI action method for your custom implementation to take over.