Enterprise configuration management

Almost every application requires some form of configuration information. This information can be as simple as a database connection string or as complex as multipart and hierarchical user preference information. How and where to store an application’s configuration data are questions you often face as a developer.

Any large enterprise application has many moving blocks. They all need to be configured for a proper working of the application. As the application size increases or for scalability the same configuration has to be repeated in different applications. For most applications once the configuration has been changed the application needs to be restarted.

Sample Code (create a blank console project, add json.net nuget)

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;

namespace CM
{
    // configuration management API, 
    //1. allow clients specify typesafe models for configuations
    //2. Store flat data on server (table) which is easy to edit
    //3. can be extended to have inheritance of values (overrides)
    //4. can be extended to lock / unlock certain property by admins etc.
    
    class Program
    {
        //Sample configuration model
        internal class SampleConfigModal
        {
            public SampleConfigModal()
            {
                Address = new Address();
            }
            public string Name { get; set; }
            public Address Address { get; set; }
            public int Age { get; set; }


        }
        public class Address
        {
            public string Street { get; set; }

        }

        // this is how client api will look like
        static void Main(string[] args)
        {
            // sample client code
            var data = new SampleConfigModal() { Name = "Rajnish", Age = 18, Address = new Address() { Street = "Oxley" } };

            // save Configuration
            SaveConfiguration("app", "section", data);

            //get Configuration
            var data2 = GetConfiguration("app", "section");
        }

        // Client side framework api -> call to rest end point
        private static T GetConfiguration(string appName, string SectionName) where T : new()
        {
            var defaultValue = new T();
            var samplePayload = JsonConvert.SerializeObject(defaultValue);
            var payload = GetConfiguration(appName, SectionName, samplePayload);
            return JsonConvert.DeserializeObject(payload);
        }

        // Client side framework api -> call to rest end point
        private static void SaveConfiguration(string appName, string SectionName, T data)
        {
            var payload = Newtonsoft.Json.JsonConvert.SerializeObject(data);
            SaveConfigurationa(appName, SectionName, payload);
        }


        //---------------------------------------- Server Code -------------------------- 
        //-------------- server has no knowledge of configuration structure or model

        private static Dictionary<string, string> storage;

        private static void SaveConfigurationa(string appName, string SectionName, string payload, string enumForHierarchyLevel = null)
        {
            // transformer
            var section = string.Format("{0}.{1}", appName, SectionName);
            var data = (JObject)JsonConvert.DeserializeObject(payload);
            var keyValueData = Flatten(data, section);

            // check if user has permission for level overrides
            // store with proper overides

            // store the flat list in sql or data 
            //| KEY |           |Value|            |OverrideType| - default,sysadmin,appadmin,groups,user etc
            //app.section.Name, Rajnish
            //app.section.Address.Street, Oxley
            //app.section.Age, 18

            storage = keyValueData;
        }

        private static string GetConfiguration(string appName, string SectionName, string samplePayload)
        {
            var section = string.Format("{0}.{1}", appName, SectionName);
            var data = (JObject)JsonConvert.DeserializeObject(samplePayload);
            var keyValueSample = Flatten(data, section);
            // update data from sql or data store
            // apply property override rules and get value from overrides if exists
            var keyValueData = keyValueSample.Select(x => new KeyValuePair<string, string>(x.Key, storage[x.Key]));

            //read these
            //app.section.Name, Rajnish
            //app.section.Address.Street, Oxley
            //app.section.Age, 18

            UnFlatten(data, section, keyValueData);

            var formatedData = JsonConvert.SerializeObject(data);
            /*
             * {
                  "Name": "Rajnish",
                  "Address": {
                    "Street": "Oxley"
                  },
                  "Age": "18"
                }
             * */
            return formatedData;

        }
        
        // Server side json helper

        private static void UnFlatten(JObject jsonObject, string prefix, IEnumerable<KeyValuePair<string, string>> data)
        {
            foreach (var item in data)
            {
                var keyName = item.Key.Substring(prefix.Length + 1);
                var storageValue = item.Value;
                if (keyName.Contains("."))
                {
                    var keys = keyName.Split('.');
                    var jtoken = (JToken)jsonObject;
                    foreach (var k in keys)
                    {
                        jtoken = jtoken.SelectToken(k);
                    }
                    ((JValue)jtoken).Value = storageValue;
                }
                else
                {
                    jsonObject[keyName] = storageValue;
                }
            }
        }

        private static Dictionary<string, string> Flatten(JObject jsonObject, string prefix)
        {

            IEnumerable jTokens = jsonObject.Descendants().Where(p => p.Count() == 0);
            Dictionary<string, string> results = jTokens.Aggregate(new Dictionary<string, string>(), (properties, jToken) =>
            {
                properties.Add(string.Format("{0}.{1}", prefix, jToken.Path), jToken.ToString());
                return properties;
            });
            return results;
        }
    }
}

Sandbox AppDomain Creation

Application domains provide a unit of isolation for the common language run-time. Creating Sandbox environment to isolate code base that can be used to load and unload assemblies make possible to unload unwanted assemblies to avoid memory leaks, eg. Host for Rosyln Compiler etc.

Security is important aspect when you allow 3rd party assemblies like plugins to run within your application,With the evidence, you can control the pre-defined permissions sets granted to code running in sub app domain.

Code snippet

private PermissionSet GetPermissionSet()
{
//create an evidence of type zone
var ev = new Evidence();
ev.AddHostEvidence(new Zone(SecurityZone.MyComputer));

//return the PermissionSets specific to the type of zone
var permissions = SecurityManager.GetStandardSandbox(ev);

if (permissions != null)
{
permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
permissions.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted));
permissions.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
}

return permissions;
}

private AppDomain CreateSandbox()
{
var ps = GetPermissionSet();

var setup = new AppDomainSetup
{
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
ApplicationName = DomainName,
DisallowBindingRedirects = true,
DisallowCodeDownload = true,
DisallowPublisherPolicy = true
};

var trusted = new[]
{
typeof (EngineFactory).Assembly.Evidence.GetHostEvidence<StrongName>()
};

var domain = AppDomain.CreateDomain(DomainName, AppDomain.CurrentDomain.Evidence, setup, ps, trusted);
return domain;
}

ViewModel First – ViewCaching

With View model first approach, view are usually created via DataTemplate, and each time a view model is injected in the content control, the corresponding view is recreated.

If you have complex view where it take bit time to create view, you may see the performance hits. To avoid the performance hit you may want to cache the view and use the cached view when available. This can be done via creating CacheContentControl and you choice of view factory.

The basic idea is to wrap the view inside CacheContentControl and delegate the view creation logic to your view factory. The attached sample uses weakreference view factory,say if GC has not collected the view, you may use the cached view instead of creating view each time. This will work with controls like tab control docking controls etc.

The CacheContentControl  code

public class CacheContentControl : ContentControl
    {
        public CacheContentControl()
        {
            Unloaded += ViewCache_Unloaded;
            ViewFactory = WeakReferenceViewFactory.Instance;
        }

        void ViewCache_Unloaded(object sender, RoutedEventArgs e)
        {
            Content = null;
        }

        private Type _contentType;
        public Type ContentType
        {
            get { return _contentType; }
            set
            {
                _contentType = value;
               //  use you favorite factory
                Content = ViewFactory.GetView(value);
            }
        }

        public IViewFactory ViewFactory { get; private set; }
    }

In the DataTemplate, use the ViewCache, pass the type of the real view you want to use:

<DataTemplate DataType=”{x:Type moduleB:Panel3Vm}”>

<Border Background=”Green”>

<local:CacheContentControl ContentType=”{x:Type moduleB:Pane3 }” Margin=”5″/>

</Border>

</DataTemplate>

The example uses standard data template (red option) to demonstrate each time you navigate to panes the corresponding views are recreated with new hash code.

If you select CacheContentControl (green option) and navigate the view is only created once. If you click on button to collected the GC then view are created on navigation if they are claimed by GC.

Why ViewModel first ?

I prefer to use view model first approach. For many reasons:

  • Vms are your application containing most of logic apart from glue code in form of behaviors or triggers.
  • If you creates views then you are responsible for its life and cleanup code. You have to deal with threading and other issues which are difficult to test. On the other hand of you create vms and leave the view creation logic with WPF via data template.. you don’t have to worry about threading issue. And there will be better separation of concerns.
  • With vm first approach zero code behind.
  • With a project level isolation for view and vms you can restrict developers using view specific things like dispatcher in the view model leaving more cleaner and testable code base. I.e view project sprojec to vm. And vm project should not refer to any presentation lib.
  • If there is clear boundary between view and vm. Both can evolve and will be less fragile.
  • Allows more complete testing of logic to open new Views and ViewModels
  • Tends to be DRYer (don’t repeat yourself ) as applications get larger
  • View and ViewModel are more independent and can be worked on separately more easily.

For more details see attached source code (download and rename docx to zip)

ViewCache Source Code

Future of web – OWIN & vNext

The ASP.NET Framework has been around for over ten years, and the platform has enabled the development of countless Web sites and services. As Web application development strategies have evolved, the framework has been able to evolve in step with technologies like ASP.NET MVC and ASP.NET Web API.

Web Evolution

  • Classic ASP – At the time, ASP was one of the primary technologies for creating dynamic, data-driven Web sites and applications by interweaving markup and server-side script. The ASP runtime supplied server-side script with a set of objects that abstracted core aspects of the underlying HTTP protocol and Web server and provided access to additional services such session and application state management, cache, etc. While powerful, classic ASP applications became a challenge to manage as they grew in size and complexity. This was largely due to the lack of structure found in in scripting environments coupled with the duplication of code resulting from the interleaving of code and markup
  • ASP.Net – The first version of ASP.NET – also known as “Web Forms” provided a similar design time experience along with a server-side event model for user interface components and a set of infrastructure features (such as ViewState) to create a seamless developer experience between client and server side programming. Web Forms effectively hid the Web’s stateless nature under a stateful event model that was familiar to WinForms developers.
    • ASP.Net MVC – ASP.NET team took several evolutionary steps to enable ASP.NET as a family of pluggable Web components rather than a single framework.One of the early changes was the rise in popularity of the well-known model-view-controller (MVC) design pattern thanks to Web development frameworks like Ruby on Rails. This style of building Web applications gave the developer greater control over her application’s markup while still preserving the separation of markup and business logic, which was one of the initial selling points for ASP.NET.
    • ASP.Net Web API – Another major shift in Web application development was the shift from dynamic, server-generated Web pages to static initial markup with dynamic sections of the page generated from client-side script communicating with backend Web APIs through AJAX requests. This architectural shift helped propel the rise of Web APIs, and the development of the ASP.NET Web API framework. As in the case of ASP.NET MVC, the release of ASP.NET Web API provided another opportunity to evolve ASP.NET further as a more modular framework.

By decoupling framework components from one another and then releasing them on NuGet, frameworks could now iterate more independently and more quickly.A modern Web application generally supports static file serving, dynamic page generation, Web API, and more recently real-time/push notifications. Expecting that each of these services should be run and managed independently was simply not realistic.

What was needed was a single hosting abstraction that would enable a developer to compose an application from a variety of different components and frameworks, and then run that application on a supporting host.

The Open Web Interface for .NET (OWIN)

Inspired by the benefits achieved by Rack in the Ruby community, several members of the .NET community set out to create an abstraction between Web servers and framework components. Two design goals for the OWIN abstraction were that it was simple and that it took the fewest possible dependencies on other framework types. These two goals help ensure:

New components could be more easily developed and consumed.
Applications could be more easily ported between hosts and potentially entire platforms/operating systems.
The resulting abstraction consists of two core elements. The first is the environment dictionary. This data structure is responsible for storing all of the state necessary for processing an HTTP request and response, as well as any relevant server state. The environment dictionary is defined as follows:

IDictionary<string, object>
An OWIN-compatible Web server is responsible for populating the environment dictionary with data such as the body streams and header collections for an HTTP request and response. It is then the responsibility of the application or framework components to populate or update the dictionary with additional values and write to the response body stream.

In asp.net WebApi v2, the OWIN pipeline becomes the default. It is eventually going to be the standard pipeline under any asp.net project.

Without OWIN, the asp.net bits are coupled to the way IIS communicates with the application. OWIN abstracts web servers and framework components. That means that your application code will now be aware of the OWIN interface, but not of the webserver that is serving the request.

In return, applications can be more easily ported between hosts and potentially entire platforms/operating systems. For example, the ability to host an application in a console or any process allows Mono to host it without efforts…

The second aspect is that it works as a pipeline.

You can plug any middlewares (and as many as you want) between the webserver and your application.
This allows for more modular solutions. You can develop redistributable middlewares that can impact the request/response coming to/from your application, but keep these modules separated from the application code.

To persuade yourself of the benefits of this modular approach, take a look at the nuget packages available for OWIN : http://www.nuget.org/packages?q=owin

A lot of these packages were previously core asp.net functionality, and have been extracted as middleware.
For example, adding support to login using various OAuth providers becomes an infrastructure concern (a middleware) and does not need to be part of your application code anymore :

Learn more about OWIN

Project Katana

Whereas both the OWIN specification and Owin.dll are community owned and community run open source efforts, the Katana project represents the set of OWIN components that, while still open source, are built and released by Microsoft. These components include both infrastructure components, such as hosts and servers, as well as functional components, such as authentication components and bindings to frameworks such as SignalR and ASP.NET Web API. The project has the following three high level goals:

Portable – Components should be able to be easily substituted for new components as they become available. This includes all types of components, from the framework to the server and host. The implication of this goal is that third party frameworks can seamlessly run on Microsoft servers while Microsoft frameworks can potentially run on third party servers and hosts.
Modular/flexible – Unlike many frameworks which include a myriad of features that are turned on by default, Katana project components should be small and focused, giving control over to the application developer in determining which components to use in her application.
Lightweight/performant/scalable – By breaking the traditional notion of a framework into a set of small, focused components which are added explicitly by the application developer, a resulting Katana application can consume fewer computing resources, and as a result, handle more load, than with other types of servers and frameworks. As the requirements of the application demand more features from the underlying infrastructure, those can be added to the OWIN pipeline, but that should be an explicit decision on the part of the application developer. Additionally, the substitutability of lower level components means that as they become available, new high performance servers can seamlessly be introduced to improve the performance of OWIN applications without breaking those applications.

And Now.. 

ASP.Net 5 – vNext 

The next generation of ASP.net

ASP.NET 5 is a significant redesign of ASP.NET.

ASP.NET 5 includes the following features:

  • New flexible and cross-platform runtime
  • ASP.NET MVC and Web API have been unified into a single programming model
  • New modular HTTP request pipeline
  • Cloud-ready environment configuration
  • Modular design, depedency injection and lot more.
  • Unified programming model that combines MVC, Web API,SignalR and Web Pages
  • Ability to see changes without re-building the project
  • Side-by-side versioning of the .NET Framework
  • Ability to self-host or host on IIS
  • New tools in Visual Studio 2015
  • Open source in GitHub
  • Can run on Mono, on Mac and Linux

Learn more : http://www.asp.net/vnext

 

Authorization Vs Authentication

Authentication

Authentication is the mechanism whereby systems may securely identify their users. Authentication systems provide an answers to the questions:

  • Who is the user?
  • Is the user really who he/she represents himself to be?

Authentication is the process of obtaining identification credentials from a user ( such as name and password ), and validating those credentials against some authority. If the credentials are valid, the entity that submitted the credentials is considered an authenticated identity.

ASP.NET implements authentication through authentication providers, the modules that contain the code to authenticate the requestor’s credentials. Following are built in ASP.Net authentication providers.

  • Windows Authentication Provider
  • Forms Authentication Provider
  • Passport Authentication Provider

Authorization

Authorization, by contrast, is the mechanism by which a system determines what level of access a particular authenticated user should have to secured resources controlled by the system.

Authorization systems provide answers to the questions:

  • Is user X authorized to access resource R?
  • Is user X authorized to perform operation P?
  • Is user X authorized to perform operation P on resource R?

Once an identity has been authenticated, the authorization process determines whether that identity has access to a given resource.

ASP.NET implements authorization through authorization providers, the modules that contain the code to authorize access to a given resource. ASP.NET includes the following authorization modules.

  • File Authorization Provider
  • URL authorization

Authentication and authorization are somewhat tightly-coupled mechanisms – authorization systems depend on secure authentication systems to ensure that users are who they claim to be and thus prevent unauthorized users from gaining access to secured resources.

ASP.NET Membership (Providers)

ASP.NET Roles (Providers)