Saturday, October 24, 2015

Javascript Design Patterns - Singleton with Closure

Singleton Pattern: 
Singleton Pattern is a design pattern that restricts a instantiation of a class to single object. Only one object will service all the action across the system.

Problem in Javascript with Singleton Pattern
It is pretty easy to implement singleton pattern in normal object oriented languages. You can make the constructor of the class to private and you can expose static method to return the instance of the object. Your static  method can take care of single object creation.

But the Javascript world is completely different. There are couple of issues in implementing Singleton pattern in javascript

  • Here variable  scope can be global or functional. It is not possible to have "private" member variable by default
  • It is not possible to  have "Private" function to hide from outside application. 
In order to overcome the problem of handling "private" function/variable, Closure is useful.


Closures:
Closures are the functions which can reference/remember the variables that are created in the environemnt on which it is created. While the function is created, it gets the reference to the variable. When ever you call the function from outside, it will hold the reference of the variable and will have the ability to update/call the variables/functions.


How Singleton and Closures Goes Hand in Hand
As you see from the definition of Closure, a function can remember the reference of the variable/function that was created in their environment. To simplify this, outer function can refer the variable with its scope . So when the function is instantiated, variable will be created but the scope will alive even after returning the method. But inner function will have access to the variable. It will act as "Private variable" scenario.

Practical Scenarios
Problem with most of the developers is that they read the concepts of the design pattern but they do not know where to apply the concepts. Let's see some of the practical  scenario where you can use Singleton design pattern in with usage.


  1. Global Cache maintenance: Assume that you are using Single Page Application (SPA) and handling multiple  pages using AJAX request. If you have some application level definition data or  common data such as State of a country, cities etc , they  can be used in multiple places. It is unnecessary to load multiple time. If you create global cache object in browser, you can store the data. When you first time request data, browser should request application and get the data and should cache it. Next time, it should return the data from cache. So Only one instances should be maintained. Singleton pattern will be useful to get handle cache
  2. Logging: Normally Javascript logging can be implemented by various frameworks like log4javascript. you use singleton pattern to create single logger and can encapulate the logger object and expose the logging related functionalities alone in other places
Logging Example

Let's see how Singleton design pattern works with closure in a practical use case. Assume that the application uses Log4Javacript library for logging Client side javascript errors into Server. Here is the sample code which uses all the concepts that was mentioned before to achieve the results elegantly.

 Client.Logger = (function () {
       //Private Variable
        var serverLogger;
       //Private Member
        function setServerLogger() {
            //Logic to create Log4javascript object creation 
            if (typeof (serverLoggeer) != 'undefined') return serverLogger;
            serverLogger= log4javascript.getDefaultLogger();
             var baseurl = 'http://localhost/app';
            var callAppender = new log4javascript.AjaxAppender(baseurl + "ClientLogger/ClientLogMessageListener.php/");
           
            serverLogger.addAppender(callAppender);

           
        }
    

        return {            //public exposed methods
            debug: function (msg) {

                if (!serverLogger) {
                    setServerLogger();
                }
                
                serverLogger.debug(msg);
              
            },
            error: function (msg) {
               
                   if (!serverLogger) {
                    setServerLogger();
                }
               
                    serverLogger.error(msg);
                }
            }
            }

        };
    } ());

   window.onerror = function (msg, url, line) {
    
        Client.Logger.warn(msg );
    };

Anatomy of Code

  • In the above code, Serverlogger and Setserverlogger are the private members.
  • Serverlogger is the Log4Javascript object. We want to create single object and that obejct has to be shared accross application (Singleton object)
  • When the Client.logger instantiates, it creates method such as warn and error method. Durng the creation of method, it has the access to the outside variable serverlogger and method setserverloggermethod.
  • From through out the Application code, warn and error method can be access by calling client.logger.warn('test') and client.logger.error('error') methods to do the logging.
  • serverlogger.warn() and serverlogger.error() are server methods which update the details in log file/database.
Happy Coding!


Tuesday, January 7, 2014

Render Report Asynchronously using ReportExecutionService in SSRS with Custom Authentication

Rendering Long running report from SSRS  is always one of the nightmare for users. These reports can not be run by user  in real time. It might take more time for the user to view the report. To overcome the issue user can

1. Schedule a long running report and view it from Mail/Shared Folder
2. Render a report in the background process using ReportExecutionService

This back ground execution can be used to export big chunk of  data from the database as well. As Scheduler/ReportExecution service can transfer the data to CSV,PDF,Excel,XML,Tiff etc format, this can be used as Exporting tool. Normally Tablix type of report are used for these Export functionality.

Scheduling option is the best solution if you use SSRS directly. If you use SSRS using custom application,  Report Execution Service provides more flexibility. If you want to invoke this service in ad-hoc manner for multiple reports, Later suits well.

As any other coding that are related to SSRS processing, Rendering Report also has it own challenge. In this post, We can see How Report can be rendered asynchronously using ReportExecutionService from WCF Service using Custom Authentication in SSRS.

This Post covers the following topics

1. How to Render Report from WCF service
2. How to use custom authentication in ReportExecutionService
3. How to invoke ReportExecutionService Asynchronously from WCF service
4. Various Timeouts Involved in SSRS
5. Exported data issues in XML and Excel

1.Make sure to increase various Timeout for the Rendering Report

a) DatabaseQueryTimeout element in RSReportServer.config – Specifies the number of seconds after which a connection to the report server database times out. Set the larger value

b) Set ReportTimeout value to higher value.

  • This can be set from Report Manager =>Report=>Properties=>Processing Options.
  • If use SOAP API, Use the SetProperties API


        
            Property[] props = new Property[1];
            Property timeoutProp = new Property();
            timeoutProp .Name = "ReportTimeout";
            timeoutProp .Value = 20000;
            props[0] = timeoutProp ;
            reportName = "Myreport";
            rService.SetProperties(reportName, props);



If you want to process very Large report which can take hours, this value should be a big number.

c) ReportExecutionService proxy's Timeout should be set to higher value. So that service call can wait until the long running report finishes its execution. We can see more about this later in the post.

This MSDN article gives more idea about various timeouts.

2.Get proxy using proxy generator instead of Web Reference

You can provide web reference using Adding Service Reference method. Most of the time, It doesn't create proper proxy class. You will end up getting API methods as class name. To avoid this, use WSDL tool create proxy. Then you can include the proxy file in your WCF service application.

3. Custom Authentication for Report Execution Service

To make use of SSRS Custom Authentication, Authentication Cookie needs to be passed with every request to SSRS. It has the following steps

a).Inherit ReportExecutionService Proxy class

b).Override GetWebRequest and GetWebResponse methods. So that you can send the authentication cookie along with the Request

c). Call LogonUser() SOAP API to receive authentication cookie

d) Use the Same proxy class for the Subsequent requests.

Lets assume that ReportExecutionService is the Proxy class name, Here is the inherited proxy code to inject authentication cookie

        
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SqlServer.ReportExecution;


    class RESProxy:ReportExecutionService
    {
        public Cookie SSRSSSRSAuthCookie
        {
            get
            {
                return m_SSRSAuthCookie;
            }
            set
            {
                m_SSRSAuthCookie = value;
            }
        }
        private Cookie m_SSRSAuthCookie = null;
        protected override WebRequest GetWebRequest(Uri uri)
        {
            HttpWebRequest request;
            request = (HttpWebRequest)HttpWebRequest.Create(uri);
            CookieContainer cookieJar = new CookieContainer();
            request.CookieContainer = cookieJar;
            Cookie SSRSAuthCookie = SSRSAuthCookie;
            // if the client already has an auth cookie
            // place it in the request's cookie container
            if (SSRSAuthCookie != null)
            {
                request.Headers.Add("RSAuthenticationHeader", SSRSAuthCookie.Name);
                request.CookieContainer.Add(SSRSAuthCookie);

            }

            request.Timeout = -1;
            return request;
        }
        protected override WebResponse GetWebResponse(WebRequest request)
        {
            WebResponse response = base.GetWebResponse(request);
            string cookieName = response.Headers["RSAuthenticationHeader"];
            // If the response contains an auth header, store the cookie
            if (cookieName != null)
            {
                HttpWebResponse webResponse = (HttpWebResponse)response;
                Cookie SSRSAuthCookie = webResponse.Cookies[cookieName];
                // If the auth cookie is null, throw an exception
                if (SSRSAuthCookie == null)
                {
                    throw new Exception(
                        "Authorization ticket is not recieved");
                }
                // otherwise save it for this request
                SSRSAuthCookie = SSRSAuthCookie;

            }
            return response;
        }
    }



Next step is to create Object for proxy and call the Logonuser to get authentication cookie for further calls.
 
 
var rs=  new RESProxy();
rs.Url = @"http://localhost/reportserever/ReportExecution2005.asmx"
rs.LogonUser("userid", "password",null);
 
 
If you use Windows Authentication, WCF service account should have proper privilege in SSRS . You can create a proxy class from original referenced class and you don't need to create inherited proxy class .
 
 
var rs =  new ReportExecutionService() 
rs.UseDefaultCredentials = true;  
 
 
4.Asynchronously  invoking the ReportExecutionService

Once the Proxy is ready with authentication cookie, Now call the webservice render method asynchronously. This MSDN article will give good idea about execution Lifecycle. It will be useful if you use cached reports in SSRS
 
  
var rs=  new RESProxy();
rs.Url = @"http://localhost/reportserever/ReportExecution2005.asmx"
rs.LogonUser("userid", "password",null);
string reportPath = @"/RootFolder/MyReport";
string format = "CSV";
string historyID = null;
string devInfo = "";
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, historyID);
rs.Timeout = 1000000;
rs.RenderAsync(format, devInfo);
AsyncCallback cb = RenderCallback;
RenderService.BeginRender(format, devInfo, cb, rs);


Next step is to implement the callback

 public void RenderCallback(IAsyncResult ar)
        {
            var logMessage = new StringBuilder();
            var rs = (RESProxy)ar.AsyncState;
            byte[] results = null;
            string extension;
            Warning[] warnings = null;
            string[] streamIDs = null;
            string mimeType;
            string encoding;
            results = rs.EndRender(ar, out extension, out encoding, out mimeType, out warnings,
                    out streamIDs);
    File.WriteAllBytes(@"C:\ReportData.csv", result);
         }


Possible Export Issues

1.If You try to export data into XML , You may end up in missing tags for some rows. If null value are present in the database, SSRS renderer will ignore those column. To avoid this, Follow this link.

2.If you try to export the data to Excel, Sometimes your excel column  width will be fixed and you may not able to resize it. If so, Remove all other element in the Tablix report and set Table cells "CanGrow" Property to true.

Happy Coding!

Friday, November 22, 2013

Duplicate Subscription in SSRS

If anyone experience duplicate subscription creation in SSRS while using SOAP API,Don't be panicked. It would be very difficult to troubleshoot this issue.There is a bug in SSRS. It might have caused the issue.

Subscriptions can be created using CreateSubscription() SOAP API . This API creates Subscription and returns SubscriptionId. If you want to update the Subscription, SetSubscriptinProperties() API is used. If you pass SubscriptionID and updated Subscription data, It will update specified Subscription.

If you create Subscription using CreateSubscription() SOAP API and  update the Subscription using the returned SubscriptionId, Intead of updating existing subscription, New Subscription will be created. You will end up in duplicate subscription.

The reason is that CreateSubscription() method returns SubscriptionId with alphabets in lower case. But Original Subscription in SSRS was created with Upper cased SubscriptionId. When You pass the lower cased  Subscription ID to update the existing Subscription, SSRS internally checks with out ignoring case. Since It doesn't find any subscription, It just Create a new one. Even though the MSDN document doesn't say anything about Subscription creation, new subscription is created. Since this API method returns null, You cannot get the SubscriptionID also!.

So always convert the SubscriptionId to upper case and then  pass this converted SubscriptionId to call SetSubscriptionProperties() method.



Wednesday, October 2, 2013

Why CSS hates IE?

 Creating Software Web product with attractive UI and Rich Client Application necessitates the heavier use of CSS. Number of CSS files and rules used in the application grows heavily in the modern day powerful web applications. Cross browser compatibility is a major challenge in web applications. Internet Explorer has specific challenges while handling CSS.  While designing the UI architecture, It is very important to consider some of the specific limitation with respect to IE .

Number of File Links per Page

Internet Explorer can accept only 32 file links per page. If you have more than 32 files, additional files will be just ignored. If you have more than 32 files, You may need to combine the CSS content to fewer files.  Normally, You can use some minifying/combining program to create single large file. But your ordeal will not end with this approach.  There is an another limitation that will hit you by this approach.

Number of Rules per Page

To make the web page render fast, Combining the files and Minification of JavaScript and CSS files are common practice. There are various advantage of CSS files Minification. Some of them are

  • Number of request from request from client to server reduces
  • Size of the File transfer reduces
  • IE limitation with number of CSS file per page can be handled
But IE has one more limitation. Number of CSS rule per page is limited to 4095.  If you have more styles, those styles will be ignored as usual.

When you write minification program, You need to Create multiple minified CSS files by considering 4095 rule!

IE accepts 32 files alone per page . At the same time, Maximum CSS rules allowed per page is 4095. CSS always hates Internet Explorer!

Wednesday, June 5, 2013

Reporting with SSRS in Multitenant Cloud Environment

As Increasing number of companies started to move towards cloud computing,  Most of the market leaders rushed to deliver cloud based software products to the market. Multitenancy is the key to become successful in the cloud based product business .

There are two areas become more of concern for the cloud based product providers and consumers . They are Reporting and Integration with other products.  Most of the existing reporting products are unusable in cloud or tied to their own cloud platforms. It is unwise to create reporting framework for each product from scratch. Generally challenges associated with Cloud Reporting are
  1. Database sits in remote location and connectivity will be the issue.
  2. ODBC and OLEDB based access from client network might have been restricted due to safety issues.
  3. Most of the applications are multitenant application. Often tenants share the same database server with other tenants. Each tenants should be restricted to view the data of other tenants.
  4. Need a 3-Tier or n-Tier architecture for Report Designing, Report Rendering and other functionalities such as scheduling.

Microsoft SQL Server Reporting server is one of the time tested product in Reporting.  It works well with .NET based products. Immediate choice for the Microsoft technology based companies would be SQL Server Reporting Server. There are several advantages with SQL Server Reporting Services.

  1. SSRS has full fledged reporting capabilities.(Tops in Gartner Report).
  2. Comes free with SQL Server.
  3. Three Tier Architecture.
  4. Customizable
  5. Load balance support
  6. SSL support.
  7. Provides C# based programmatic access.
  8. Microsoft technology - Works well with .NET and SQLServer.
  9. Regular feature addition and good support.
 In the upcoming articles, Let's see how we can overcome the challenges of cloud and Multitenancy with SSRS and discuss about various options available.


Friday, January 11, 2013

Pagination in SQL Server

Pagination is one of the intersting problem faced by all kind of applications. Pagination in earlier version of SQL Server is achieved by Common Table Expression(CTE). SQL Server 2012 integrated pagination syntax in most elegant and intutive way.

Let's assume the following sample table
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[test](
 [val] [int] NULL
) ON [PRIMARY]

GO
Fill the table with integer 1 to 100. Let's assume that we want to find the 5th page with page size of 5 records. That means we want record 20 to 25

Here is the simple syntax to achieve the pagination.

SELECT val FROM test ORDER BY val OFFSET 20 ROWS FETCH NEXT 5 ROWS ONLY

OFFSET specifies starting point and FETCH NEXT X ROWS specifies the PageSize. This feature will work only if you use orderby. MySQL has this feature long time back.This is one of the most expected feature from SQL Server.Finally SQL Server 2012 came up with this feature.


Happy Coding.

Monday, January 7, 2013

Microsoft ignored the Power of Report Model

When Microsoft announced the SQLServer 2012  features,  There was  a shock for   SSRS2008 or earlier version users. The bad news is that Microsoft is going to discontinue Report Model approach in SSRS 2012. There will be backward compatibility so that old report model will work fine. But you can't create new report model using SQL Server 2012 technologies. That means  Report Model feature will be discontinued in future.

 Report Model approach is  relatively least popular technology from SQL Server Reporting Services. Business users know what information they need and how their report should look, but they usually don’t have the technical skills necessary to create a rich report design, to understand real-world database schemas, or to use formal query languages such as SQL. In contrast, IT staffers understand report design, the technical aspects of the data source schema, and formal query languages, but they are not available on demand to analyze, design, and deploy urgent or one-time reports. Therefore, businesses need a reporting solution that enables information workers to understand and  create reports on demand in short term without the dependency of IT staff.

Report Model Approach creates  a metadata layer on top of the database schema and preparing it to present the most-frequently requested data in the most intuitive and accessible manner by using business taxonomy. The metadata layer will then translate report design, filtering, and parameters into the correct and optimized native queries against the underlying physical data source.

Since Report creation using Report model is well integrated into Report builder, This feature allows basic business user to create simple reports using report model and Experienced developer can create complex report using SQL from the same SSRS application.

Even though SSRS 2012 provided Web UI for SSAS Cube reporting, there is no user friendly solution for Report generation from RDBMS.

But real power of Report model technology in SSRS is from some other least known area. Let's see about it.

Report Creation in Cloud Environment

Now world is moving towards cloud . Application servers, Database servers etc, are moving to cloud. creating Report from cloud hosted Database Server is a major challenge  As SaaS is gaining popularity with multitenant architecture, Real world problem of report creation from multitenant cloud hosted database is unimaginable.

 In cloud hosted application, Reports needs to be created using some web app or through click once application. Fortunately SSRS provided Report Builder tool which is a click once application. All the access to SSRS happens through web services. It is possible to make the protocol as https.

One of the primary challenge is the access to the database from Report generation tool. Normally ODBC,OLEDB and other connectors connects SQLServer database using 1433 port.If the application is hosted in cloud and if it is shared by multiple applications/customers, It is not practically possible to open 1433 port . You cannot open the Database server to "Public". Most of the Reporting tools access the database using ODBC/OLEDB or other access through 1433.

As per Microsoft, SSRS provided 3 Tier architecture even for report creation. Client Application always contact SSRS App Server and SSRS Report server contact database. This is the architecture that we want. But It is not happening. SSRS issue in this architecture  is discussed well in this post.

Then how to make a non-1433 port access to design/create the report from Report builder. Here is the power of Report builder comes. All the calls made from Report builder to create Report Model approach requires http or https port alone. It doesn't require 1433 port access.

Even though Report Model creation needs some overhead in metadata creation and maintenance , At least this approach solves one major technical problem in cloud . Of course, There are lots of bugs and usability issues with Report model based Report creation , Because of the above advantage, lots of Cloud users tends to use Report model. With The release of SQLServer 2012, Microsoft  announced its intention to stop supporting Report Model without providing proper alternative for RDBMS based reporting.

It is the time for new vendor to come up with reporting product which can design/create report without 1433 port access. If someone comes with above feature with multi tenant RDBMS support, He will rule Reporting Products world in the future.