Thursday, August 20, 2020

Custom Owin Middleware in Asp.Net PipeLine

Before starting the fundamental about Owin Middleware, Let me start with Owin (Open web interface) in .net.

Owin come in picture when Asp.net decoupled web app and web servers.It defines a standard way for middleware to be used in a pipeline to handle requests and associated responses .

Owin Middleware :- This is a component that could be use to control request and response in Asp.net.

A good takeaway from the above is that the Next property is optional, meaning we can stop the pipeline ourselves by simply not invoking the next OwinMiddleware.

To implement OwinMiddleware we will need a constructor that calls the base constructor and an implementation of the Invoke method. Let's spin up an example.

  Required Packages

Install-Package Microsoft.Owin.Host.SystemWeb

The abstract OwinMiddleware class looks like this:

/// <summary>
/// An abstract base class for a standard middleware pattern.
/// </summary>
public abstract class OwinMiddleware {

    /// <summary>
    /// Instantiates the middleware with an optional pointer to the next component.
    /// </summary>
    /// <param name="next"></param>
    protected OwinMiddleware(OwinMiddleware next) {
        Next = next;
    }

    /// <summary>
    /// The optional next component.
    /// </summary>
    protected OwinMiddleware Next { get; set; }

    /// <summary>
    /// Process an individual request.
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public abstract Task Invoke(IOwinContext context);
}

This is then registered like in StartUp class

app.Use(typeof(MyMiddlewareClass));

Here is the example of Custom Health Check Owin middleware in Asp.net :- 

We will take two different type of health check middleware pipeline example   

public static class AppBuilderExtensions
    {
        public static IAppBuilder UseHealthCheck(this IAppBuilder app, string route, HealthCheckConfiguration config = null)
        {
            config = config ?? new HealthCheckConfiguration();
            return app.Map(route, x => x.Use<HealthCheckMiddleware>(config));
        }
    }
 public class HealthCheckConfiguration
    {
        public TimeSpan Timeout { get; set; }

        public IList<ICheckHealth> HealthChecks { get; set; }

        public HealthCheckConfiguration(TimeSpan timeout = default(TimeSpan), IList<ICheckHealth> healthchecks = null)
        {
            Timeout = timeout;
            HealthChecks = healthchecks;
        }
    }
 public interface ICheckHealth
    {
        string Name { get; }
        Task<HealthCheckStatus> Check();
    }
public sealed class HealthCheckStatus
    {
        public string Message { get; set; }

        public bool HasFailed { get; set; }

        public HealthCheckStatus(string message, bool hasFailed)
        {
            Message = message;
            HasFailed = hasFailed;
        }

        public static HealthCheckStatus Failed(string message = null)
        {
            return new HealthCheckStatus(message ?? "Failed", true);
        }

        public static HealthCheckStatus Passed(string message = null)
        {
            return new HealthCheckStatus(message ?? "Success", false);
        }
    }
 public class HealthCheckMiddleware : OwinMiddleware
    {
        private IList<ICheckHealth> _healthChecks;
        private readonly TimeSpan _timeout;

        public HealthCheckMiddleware(OwinMiddleware next, HealthCheckConfiguration config) : base(next)
        {
            _healthChecks = (config.HealthChecks ?? Enumerable.Empty<ICheckHealth>()).ToArray(); ;
            _timeout = config.Timeout;
        }

        public override async Task Invoke(IOwinContext context)
        {
            if (!string.IsNullOrEmpty(context.Request.Path.Value))
            {
                await Next.Invoke(context);
                return;
            }
            //var queryParameters = context.Request.GetQueryParameters();
            //var debug = false;
            //if (queryParameters.ContainsKey("debug"))
            //    bool.TryParse(queryParameters["debug"], out debug);

            var checkTasks = _healthChecks.Select(async x =>
            {
                try
                {
                    return new
                    {
                        Name = x.Name,
                        Status = await x.Check().ConfigureAwait(false)
                    };
                }
                catch (Exception e)
                {
                    return new
                    {
                        Name = x.Name,
                        Status = HealthCheckStatus.Failed(e.Message)
                    };
                }
            });

            var allTasks = Task.WhenAll(checkTasks.ToArray());
            if (allTasks != await Task.WhenAny(allTasks, Task.Delay(_timeout)).ConfigureAwait(false))
            {
                context.Response.StatusCode = (int)HttpStatusCode.GatewayTimeout;
            }
            else
            {
                var results = allTasks.Result;
                var hasFailed = results.Any(x => x.Status.HasFailed);
                context.Response.StatusCode = hasFailed ? (int)HttpStatusCode.ServiceUnavailable : (int)HttpStatusCode.OK;

                var sb = new StringBuilder();
                foreach (var r in results)
                    sb.AppendLine(r.Name + ": " + r.Status.Message);
                await context.Response.WriteAsync(sb.ToString());

            }

        }
    } 


1. HttpHealthCheck  :- This pipeline will use to check the http client health check in Asp.net pipeline

public class HttpHealthCheck : BaseHealthCheck
    {
        private readonly Uri _uri;
        private readonly ICredentials _credentials;

        public HttpHealthCheck(string name, Uri uri, ICredentials credentials = null)
        {
            Name = name;
            _uri = uri;
            _credentials = credentials;
        }

        public override async Task<HealthCheckStatus> Check()
        {
            var request = (HttpWebRequest)WebRequest.Create(_uri);
            request.UserAgent = "Owin.HealthCheck";
            request.Method = "GET";
            request.Credentials = _credentials;

            using (var response = (HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false))
            {
                var statusCode = (int)response.StatusCode;
                if (statusCode >= 200 && statusCode < 300)
                    return HealthCheckStatus.Passed(response.StatusDescription);
                else
                    return HealthCheckStatus.Failed(response.StatusDescription);
            }
        }
    }

2. Ping Health Check Pipeline:- This pipeline is used to check the server health while process the request

 public class PingHealthCheck : BaseHealthCheck
    {
        private readonly string _host;
        private readonly TimeSpan _timeout;

        public PingHealthCheck(string name, string host, TimeSpan timeout)
        {
            if (string.IsNullOrEmpty(host))
                throw new ArgumentException(string.Format("host cannot be empty {0}", name));
            Name = name;
            _host = host;
            _timeout = timeout;
        }

        public override async Task<HealthCheckStatus> Check()
        {
            var ping = new Ping();
            var result = await ping.SendPingAsync(_host, (int)_timeout.TotalMilliseconds).ConfigureAwait(false);
            return new HealthCheckStatus(result.Status.ToString(), result.Status != IPStatus.Success);
        }
    }

To register the middleware you need to pass the type 

 app.UseHealthCheck("/healthcheck", new HealthCheckConfiguration
            {
                Timeout = TimeSpan.FromSeconds(20),
                HealthChecks = new List<ICheckHealth>()
                {
                     new HttpHealthCheck("Google Check", new Uri("https://www.google.com")),
                     new PingHealthCheck("Local Ping", "localhost", TimeSpan.FromSeconds(10))
                }
            });


Sunday, March 1, 2020

MediatR dependency resolved by Autofac and structureMap


MediatR is a messaging handler which has responsibility for dealing with command and queues.It simplify the controller with single dependency(Most of the case).
Controller use mediatr to send for the data they need to fetch or the action they need to perform.

MediatR with AutoFac :-
1. First need the mediatR using package manager console by command "Install-Package MediatR "
2. Install autofac by "Install-Package Autofac".


    // Intializes IOC container...
    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    builder.RegisterWebApiFilterProvider(config);       
    builder.RegisterType<ApiWorkingContext>().As<IApiWorkingContext>();
    builder.Register(c => new     
            HttpContextWrapper(HttpContext.Current)).As(typeof(HttpContextBase));
       
    builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly)
    .AsImplementedInterfaces();

    // Register all the Command classes (they implement IRequestHandler) in assembly holding the             Commands
    builder.RegisterAssemblyTypes(typeof(CreateOrderCommand).GetTypeInfo().Assembly)
    .AsClosedTypesOf(typeof(IRequestHandler<,>));

    builder.Register<ServiceFactory>(context =>
            {
                var componentContext = context.Resolve<IComponentContext>();
                return t => { object o; return componentContext.TryResolve(t, out o) ? o : null; };
            });

MediatR with StructureMap :-
1. First need the mediatR using package manager console by command "Install-Package MediatR "
2. Install autofac by "Install-Package structuremap".

  Scan.ConnectImplementationsToTypesClosing(typeof(IRequestHandler<,>));
  Scan.ConnectImplementationsToTypesClosing(typeof(INotificationHandler<>));
  Scan.AssemblyContainingType<IMediator>();
  Scan.WithDefaultConventions();
  Scan.For<IMediator>().Use<Mediator>();


     



Thursday, January 30, 2020

Generate unique random integers without collisions in sql server


Here is the solution to generate unique number  in sql server. We may use one of these calculations to generate a number in this set:

SELECT
  1000000 + (CONVERT(INT, CRYPT_GEN_RANDOM(3)) % 1000000),
  1000000 + (CONVERT(INT, RAND()*1000000) % 1000000),
  1000000 + (ABS(CHECKSUM(NEWID())) % 1000000);


But think again, Is number unique ?

Generating a random number on its own is not difficult, using methods like RAND() or CHECKSUM(NEWID()). The problem comes when you have to detect collisions. Let's take a quick look at a typical approach, assuming we want CustomerID values between 1 and 1,000,000: 

DECLARE @rc INT = 0,
  @CustomerID INT = ABS(CHECKSUM(NEWID())) % 1000000 + 1;
              -- or ABS(CONVERT(INT,CRYPT_GEN_RANDOM(3))) % 1000000 + 1;
              -- or CONVERT(INT, RAND() * 1000000) + 1;
WHILE @rc = 0
BEGIN
  IF NOT EXISTS (SELECT 1 FROM dbo.Customers WHERE CustomerID = @CustomerID)
  BEGIN
    INSERT dbo.Customers(CustomerID) SELECT @CustomerID;
    SET @rc = 1;
  END
  ELSE
  BEGIN
    SELECT @CustomerID = ABS(CHECKSUM(NEWID())) % 1000000 + 1,
      @rc = 0;
  END
END


Wait, As the table gets larger, not only does checking for duplicates get more expensive (More time required to complete the process)

Different Approach

One idea is to pre-calculate a large number of random number and store it in different table 

CREATE TABLE dbo.RandomIDs
(
  RowNumber INT PRIMARY KEY CLUSTERED,
  NextID INT 
) WITH (DATA_COMPRESSION = PAGE);
-- data compression used to minimize impact to disk and memory

-- if not on Enterprise or CPU is your bottleneck, don't use it
;WITH x AS
(
  SELECT TOP (1000000) rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
    FROM sys.all_objects AS s1
    CROSS JOIN sys.all_objects AS s2
    ORDER BY s1.[object_id]
)
INSERT dbo.RandomIDs(RowNumber, NextID)
  SELECT rn, ROW_NUMBER() OVER (ORDER BY NEWID()) + 1000000
  FROM x;

Now, in order to generate the next ID, we can simply delete the lowest RowNumber available, and output its NextID for use. We'll use a CTE to determine the TOP (1) row so that we don't rely on "natural" order 

DECLARE @t TABLE(NextID INT);
;WITH NextIDGenerator AS
(
  SELECT TOP (1) NextID FROM dbo.RandomIDs ORDER BY RowNumber
)
DELETE NextIDGenerator OUTPUT deleted.NextID INTO @t;
INSERT dbo.Users(UserID /* , other columns */)
  SELECT NextID /* , other parameters */ FROM @t;
















Saturday, January 18, 2020

Decorator Design Pattern - C#

Attaching additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.



The classes and objects participating in this pattern are:
  • Component 
    • defines the interface for objects that can have responsibilities added to them dynamically.
  • ConcreteComponent   
    • defines an object to which additional responsibilities can be attached.
  • Decorator 
    • maintains a reference to a Component object and defines an interface that conforms to Component's interface.
  • ConcreteDecorator 
    • adds responsibilities to the component.


Code :-

//Component
namespace DecoratorDemo.Component
{
    public interface IHome
    {
        string Make { get; }
        double GetPrice();
    }
}


//Concrete Component

  public class MyHome : Component.IHome
    {
        public string Make {
            get
            {
                return "MyHome";
            }
        }

        public double GetPrice()
        {
            return 8000000;
        }
    }


//Decorator
 public abstract class HomeDecorator : IHome
    {
        private readonly IHome home;

        public HomeDecorator(IHome home)
        {
            this.home = home;
        }
        public string Make
        {
            get
            {
                return "MyHome";
            }
        }

        public double GetPrice()
        {
            return home.GetPrice();
        }
        public abstract double GetDiscountPrice();
    }

  // Concrete Decorator
  public class OfferPrice : HomeDecorator
    {
        public OfferPrice(IHome home)  : base(home)
        {

        }
        public override double GetDiscountPrice()
        {
            return .8 * base.GetPrice();   
        }
    }

// Execution

 class Program
    {
        static void Main(string[] args)
        {
            IHome home = new MyHome();
            HomeDecorator decorator = new OfferPrice(home);

            Console.WriteLine(string.Format("Make : {0} Price {1} DiscountPrice {2}", decorator.Make, decorator.GetPrice(), decorator.GetDiscountPrice()));
        }
    }


OutPut
Make : MyHome Price 8000000 DiscountPrice 6400000











Part 7 — Enterprise RAG Reference Architecture

  "Architecture is not about connecting components. It is about defining responsibilities that can evolve independently." Welcome ...