Alik Levin's

Clarity, Technology, and Solving Problems | PracticeThis.com 

May, 2010

  • Alik Levin's

    Solution Architecture For The Masses. Step 4: Design Your Presentation Layer – Part I

    • 2 Comments
     Alik Levin    In Step 1 I have structured my Visual Studio Solution. In Step 2 I have designed and implemented my Entities and Business Services. In Step 3 I have designed and implemented basic crosscutting functionality – exception, handling, logging, instrumentation and input sanitization. I am ready to build my presentation layer. There are few principles that I must follow when creating presentation layer in Web Application Archetype called Web Application frame.

    Quick Resource Box

    In this post I will be structuring my ASP.NET Web Project following the principles outlined in the Web Application frame:

    • Authentication
    • Authorization
    • Caching
    • Exception Management
    • Logging, Instrumentation
    • Navigation
    • Page Layout (UI)
    • Page Rendering
    • Presentation Entity
    • Request Processing
    • Service Interface
    • Session Management
    • Validation

    Authentication & Authorization

    IIdentity and IPrincipal interfaces are the heart of .Net authentication and authorization. All authentication and authorization implementations implement these interfaces. Concrete classes that implement the IPrincipal interface populated with concrete classes that implement IIdentity and stored in HttpContenxt.Current.User where authorization frameworks such RoleManager will look for it.

    I have not decided where my application will be deployed – Internet, Intranet, or Azure. So the best bet for me in regards to Authentication and Authorization would be to assume this:

    • The concrete Authentication & Authorization framework will be configured in Web.Config without affecting the code.
    • Authorization logic will be made by Authorization framework or in code based on concrete implementation of IPrincipal located in HttpContext.Current.User anyway.

    Main decision to make at this point is to structure the project’s folders the way that there is clean separation between restricted pages and resources that do not require authentication and authorization. Following is how my web application is structure in terms of folders:

    image

    The following folders I have created manually:

    • Controls. This folder will hold user controls, ASCX’s. Does not require authentication. Direct access to ACSX files will be restricted by ASP.NET runtime.
    • CSS. This folder will hold CSS stylesheet files. Does not require authentication. It will be configured for anonymous access purposefully.
    • IMG. This folder will hold image files (JPG, PNG, etc.). Does not require authentication. It will be configured for anonymous access purposefully.
    • JS. This folder will hold JavaScript files. Does not require authentication. It will be configured for anonymous access purposefully.
    • Restricted. This folder will hold any use case that requires authentication/authorization.

    Minimum Authorization configuration in Web.Config:

    <location path="Restricted">
           <system.web>
                 <authorization>
                        <deny users="?"/>
                 </authorization>
           </system.web>
    </location>

    From p&p’s ASP.NET 2.0 Internet Security Reference Implementation

    Partition the site into restricted areas and public areas

    All pages that require authenticated access are placed in either the Restricted or Admin folders. Pages and resources in other directories are anonymously accessible. By partitioning the site, SSL is used only on those pages that need it. Since the use of SSL has a significant overhead, using it sparingly will improve system performance.

    There is more to partitioning than SSL [BTW, I’d argue SSL has “a significant overhead” – it does, but less than significant image ].

    Partitioning to folders fosters authorizing users based on folder names vs. particular pages. Authorizing users to particular pages is bug prone and less secure practice – imagine if someone just copy and pastes SuperSecurePage.aspx to ‘Copy of SuperSecurePage.aspx’ while you authorization configuration was as follows [very bad practice]:

    <location path="SuperSecurePage.aspx">
           <system.web>
                 <authorization>
                        <allow roles="SuperAdmin"/>
                 </authorization>
           </system.web>
    </location>

    Suddenly an attacker has free access to sensitive logic at ‘Copy of SuperSecurePage.aspx’ without being authorized.

    Concentrate restricted pages into folders and authorized on per folder basis, not per page basis.

    Another aspect of partitioning the application in separate folders relates to caching, which is next.

    The summary of my authentication and authorization strategy is:

    • Undecided.
    • Rely on the fact that whatever the implementation comes along it is based on IPrincipal, and IIdentity located in Http.Context.Current.User.

    Caching

    When it comes to caching in distributed web application there are four different types of caching come to mind:

    1. Browser caching. Cached content being stored on client machines and managed by browser’s caching mechanism. Proxy server caching is out of scope for this post.
    2. Output caching. Rendered HTML output by ASP.NET managed by IIS Server and ASP.NET engine on Web Server. Will be discussed in Page Layout (UI) section.
    3. Application data caching. Data retrieved from data sources such SQL Server and cached by middle tier [either by IIS Web Server, or Dedicated Downstream server] – out of scope at this point. More info here: Caching Architecture Guide for .Net Applications
    4. Data source caching. Enabling data source such as SQL Server to cache read only data in the data tier. Out of scope for this post. In short, it’s either achieved by scaling up by setting up a big box with 32 GB RAM and up, or scaling out by separating read and write data as described in Scaling Databases part.

    The summary of my decisions regarding Browser caching was made:

    • Creating separate folders for static content – CSS, IMG, JS. It will help operations system engineering team easily set expiration policies in production which should lead to less HTTP 304’s improving overall user experience and rendering time.
    • Allowing anonymous access to the folders other than Restricted as described in previous section. It will reduce HTTP 401 roundtrips improving user experience and rendering time.

    More info here ASP.NET Performance: Get Rid of HTTP 401 and HTTP 304.

    Exception Management

    General guidelines from Chapter 15: Web Application Archetype:

    • Do not use exceptions to control the logical flow of your application.
    • Do not catch exceptions unless you *must* handle them, you need to strip sensitive information, or you need to add additional information to the exception.
    • Design a global error handler to catch unhandled exceptions.
    • Display user-friendly messages to end users whenever an error or exception occurs.
    • Do not reveal sensitive information, such as passwords, through exception details.

    As per How To: Design Exception Management the key considerations of detecting [catching] exceptions are:

    Guidelines
    My take
    • Only catch the exception when you must perform any of the following tasks:
      • Gathering exception details for logging.
      • Adding relevant and additional information to the exception.
      • Cleaning up any resources used in the code block.
      • Retrying the operation to recover from the exception.
    • Do not catch an exception and allow the exception to propagate up the call stack, if you do not have any task to accomplish.
    • Required information will be gathered in global error handler
    • I do not plan to add more information.
    • Resources will be cleaned as part of try/catch/finally triplet. But main approach will be using *using* clause.
    • I do not plan to retry.

    The strategy for handling such unhandled exceptions is:

    • Gather the required information. I will rely on Web Events to gather the info.
    • Log the exception information. I will rely on Health Monitoring mechanism to publish/log exceptions.
    • Send any notifications. I will not be doing that. If needed, will route the event to event log and configure it for further actions.
    • Perform any clean-up required. I will do it in try/catch/finally triplet or inside using clause.
    • Communicate the error information to the user. I will show generic error page without revealing any implementation details.

    The summary of the my exception handling strategy:

    For now this is what I have in my Visual Studio project regarding exception handling:

    Global.asax:

    protected void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError().GetBaseException();
        string message = ex.ToString();
        Tracing.TraceMessage(message);
        EventsServices.PublishException("GLOBAL ERROR HANDER: " +
                                        message);
        Server.ClearError();
        Response.Redirect("GenericErrorPage.htm");
    }

    Notice EvenstServices and Tracing classes I use – I utilize previously implemented logging mechanism.

    Web.Config [make sure you have created GenericErrorPage.htm]:

    <customErrors mode="RemoteOnly"
                  defaultRedirect
    ="GenericErrorPage.htm">
    </customErrors>

    Logging & Instrumentation

    Logging is implemented in previous step. In previous section I have used it to publish and log an exception caught in global error handler. Since it is based on built-in ASP.NET health monitoring the following section needed to be added to Web.Config:

    <healthMonitoring>
      <eventMappings>
        <add name="Exception Event"
             type
    ="WebEvents.ExceptionEvent"/>
      </eventMappings>
      <rules>
        <add name="Exception" eventName="Exception Event"
                              provider
    ="EventLogProvider"
                              minInterval
    ="00:00:01"/>
      </rules>
    </healthMonitoring>

     

    It reads as follows:

    • There is a custom event of type “WebEvent.ExceptionEvent”
    • I map it to a friendly name “Exception Event”.
    • I route this event to Event Log [notice provider attribute].

    Anytime a code similar to the following code runs:

    EventsServices.PublishException(“Some Message”);

    I should observe it in Event Log. Here an example for division by zero caught by global error handler:

    image

    Instrumentation is performed by Tracing.TraceMessage(message). I have already used it in global error handler [look in the example above]. The results it produces observed using DebugView:

    image

    Other categories of Web Application frame will be discussed in the next part. Stay tuned.

    Related Books

  • Alik Levin's

    Robust, Efficient, & Fast Data Access With LINQ to SQL

    • 2 Comments
     Alik Levin    In the post I have quickly captured the steps required to access a database using LINQ to SQL. I am reading a book LINQ in Action – good read, easy and practical. Love it a lot.

    Quick Resource Box

    General ORM Limitations

    In the book the authors specify key limitations of existing ORM [object relational mapping] tools:

    “Some of their [ORM tools] main limitations include the following:

    • A good knowledge of the tools is required before being able to use them efficiently and avoid performance issues.
    • Optimal use still requires knowledge of how to work with a relational database.
    • Mapping tools are not always as efficient as handwritten data-access code.
    • Not all the tools come with support for compile-time validation.”

    I’d summarize the summary as “ORM usually hit developer’s and/or code’s performance.

    Accessing Database with LINQ to SQL

    Summary of steps:

    • Step 1 – Create entity class
    • Step 2 – Write LINQ to SQL Query
    • Step 3 – Test your code

    The following section describes each step in details.

    Step 1 – Create entity class

    I am using Pet Shop database. I have created a simple ProductInfo entity [Table] class as follows:

    [Table(Name = "Product")]
    public class ProductInfo
    {
        [Column (IsPrimaryKey=true, Name="ProductId")]
        public string ID { get; set; }
        [Column]
        public string Name { get; set; }
        [Column (Name="Descn")]
        public string Description { get; set; }
        [Column (Name="CategoryId")]
        public string Category { get; set; }
    }

    Notice the annotations for each property. The annotations actually map the class’ properties to the table’s fields.

    Step 2 – Write LINQ to SQL Query

    Next is creating the DataContext object – effectively the connection to the database, and then building the query:

    DataContext db = new DataContext(@"Data Source=.\sqlexpress;
                         Initial Catalog=MSPetShop4;
                         Integrated Security=True"
    );
    var products=
        from product in db.GetTable<ProductInfo>()
        where product.Category.Equals("FISH")
        select product;

    Step 3 – Test your code

    To test the code I have dumped the values to the console and received the result:

    foreach (ProductInfo product in products)
    {
           Console.WriteLine("NAME {0} DESCRIPTION {1}",
                             product.Name,
                             product.Description);

    }

    image

    I have also ran a SQL Express Profiler to observe the SQL Statement issued against the DB":

    exec sp_executesql N'SELECT [t0].[ProductId] AS [ID], [t0].[Name], [t0].[Descn] AS [Description], [t0].[CategoryId] AS [Category]
    FROM [Product] AS [t0]
    WHERE [t0].[CategoryId] = @p0',N'@p0 nvarchar(4000)',@p0=N'FISH'

    Analysis

    In the book authors summarize the efficiency of the approach as follows:

    “Let’s sum up what has been done automatically for us by LINQ to SQL:

    • Opening a connection to the database
    • Generating the SQL query
    • Executing the SQL query against the database
    • Creating and filling our objects out of the tabular results”
    • [ALIKL] Closing/Disposing connection to the database

    As  performance guy I must also add the LINQ to SQL closes/disposes the connection automatically. In too many cases developers neglect closing/disposing the connection which usually leads to connection leak and as a result to unstable or less than optimal performance.

    Conclusion

    Seems like LINQ to SQL breaks the limitations I have mentioned in the beginning. For my Solution Architecture For the Masses series I am using old school database approach. I believe since the solution I have build utilizes layered approach and since the layers are abstracted one from another I will be porting the DAL [Data Access Layer] from ADO.NET to LINQ to SQL.

    Read the book LINQ in Action.

    Related Books

  • Alik Levin's

    Inspecting Solution For Performance

    • 2 Comments
     Alik Levin    In this post I’d like to share my approach to managing performance throughout SDLC (Software Development Life Cycle). Before recently joining the Solution Engineering team I worked as a field consultant with MCS [Microsoft Consulting Services].

    Quick Resource Box

    My assignments included delivering performance workshops, reviewing architecture and design for performance, conducting performance code inspections, inspecting solution deployment for performance, and resolving performance incidents in production. In short, I was required to inspect the solution for performance at any phase of the development lifecycle.

    The Challenge

    The challenge I was constantly facing is how to efficiently and effectively communicate my recommendations to a customer. By customer I mean Business Sponsor, Project Manager, Solution Architect, Developer, Test Engineer, System Engineering, and End User. Different roles, different focus, different languages. If I am not efficient, I’d be wasting customer’s time. If I am not effective, my recommendations won’t be used.

    Performance Language

    What worked for me is establishing a common performance language across the team. First we’d agree on what performance is, and that is:

    • Response Time. Time that it takes for a server to respond to a request.
    • Throughput. Number of requests that can be served by your application per unit time.
    • Resource utilization. How much server and network resources are consumed.
    • Workload. Total number of users and concurrent active users.

    This simple definition helped when communicating a performance goals with decision makers in the inception stages of a project.

    Then we’d agree on what affects performance the most. I could not find any better categorization than Performance Frame:

    • Caching. Per user, application-wide, data volatility.
    • Communication. Transport mechanism, boundaries, remote interface design, round trips, serialization, bandwidth.
    • Concurrency. Transactions, locks, threading, queuing.
    • Coupling/Cohesion. Loose coupling, high cohesion among components and layers.
    • Data Access. Schema design; Paging; Hierarchies; Indexes; Amount of data; Round trips.
    • Data Structures/Algorithms. Choice of algorithm, Arrays vs. collections vs. DataSets vs. else.
    • Resource Management. Allocating, creating, destroying, pooling.
    • State Management. Per user, application-wide, persistence, location.

    This simple frame helped during architect/design phase when working with Solution Architects on creating a blueprint of the solution. It also helped during coding phase when working with developers on improving their code for performance. During production incidents I’d usually run series of questions trying to narrow down to a specific category. Once identified, I’d go off and use specific performance scalpel to dissect the issue at hand.

    Following are two quick case studies of how the well established performance language helped to effectively and efficiently improve performance - one during the architecture phase, and the other when solving production performance incident.

    The Case Of Over-Engineered Architecture

    I was responsible for performance as part of architecture effort for one of our customers. Based on the requirements the team came up with the design that supports high level of decoupling. The reason for it was enabling future extensibility and exposure to external systems. The design looked similar to this [the image is from Chapter 9: Layers and Tiers]:

     image

    The conceptual design recommended using WCF as a separate physical layer exposing the functionality to both external systems and to the application’s intrinsic UI. It also assumed DataSet as a DTO [Data Transfer Object].

    Worth to note, that one of the quality attributes was very aggressive performance requirements in terms of response time. Using Performance Frame we reviewed the design for performance and identified that such design wouldn’t be optimal in regards to performance:

    • Communication. Introducing another physical layer would incur latency due to serialization costs and security checks.
    • Concurrency. Extra measures need to be taken for throttling communications between the layers that would affect the throughput (concurrency). Concurrency issues would introduce requests queuing.
    • Data Structures/Algorithms. DataSets are less controllable in terms what gets serialized and what’s not when working with WCF. That would lead to extra dev effort or all-or-nothing serialization that would lead to extra latency.

    Next round of design improvements produced the conceptual design that exposed its functionality to it’s UI without going through the separate physical services layer, similar to this [the image taken from Chapter 9: Layers and Tiers]:

    image

    We all agreed that this time the design is simpler and should foster better response time for it’s native UI that account for 80% of the system’s workload.

    The Case Of Ever Growing Cache

    A customer complained that the application was throwing all active users periodically. The business was losing money as the application was responsible for getting new customers.

    We reviewed event logs for recycles and quickly identified that IIS was recycling and the reason is memory limits being hit. After quick interview with the team we assumed application was implementing caching in less than appropriate way or using data structures in a way that caused the recycles. We have taken few memory dumps and analyzed it using WinDBG. The culprit indeed was a datatable instantiated as a static variable serving for caching purposes. Since the datatable was instantiated as static variable it had no way to purge its values other than grow endlessly and cause the recycles. We were able to communicate our findings and recommendations back to the team using the performance language we established earlier.

    Conclusion

    Performance like Security is never ending story, it’s work in progress. It’s never too early to start improving both. The trick is setting clear goals and frame the approach that works best for you and the rest of the team.

    What works best for you and your team?

     

Page 1 of 3 (8 items) 123