Monday, January 30, 2012

Creating Objects Using Factory Methods

Consider static factory methods instead of constructors

Normally when we use constructor methods(new key word) to create instances of a class. And in post i am going to explain another way of create object which is static factory methods.For an example we can take one of factory method implemented in java.lang.Boolean.
 
public static Boolean valueOf(boolean b){
 return b? Boolean.TRUE : Boolean.FALSE;
}

Providing factory method to create objects rather than using constructors has both advantaged and disadvantages.
Advantages of having Factory methods to create instances 

  • Factory methods have a valid name 
Imaging you have a Shape class and it has a constructor which accept one int parameter which is the number of edges.If parameter is 3 it returns a triangle.So the client code which use this constructor is not too clear since constructor method does not make a sense about the object which is going to retrieve. But if we have a static factory method called getTriangle() which returns a triangle shape instance, it would be more readable than having a constructor method. 

  • Do not need to create new object in each time 
This is the implementation of singleton pattern. This technique is very useful is cases of cost of creating an instance is too high and where we can share a single object. One of the advantage of using this concept is we don't need equals( ) method for comparisons and we can simple check the equality by == operator.

  • Factory methods can returns any sub type of their return type 
One application of this flexibility is that an API can return object without making their classes public.For an example look at the java.util.Collections. In this case interfaces provide return types for static factory methods. And those static factory methods are put in a non instantiable class. 

  • Reduce the overhead of creating parameterized type instances 



Instead of this kind of constructor methods we can have a factory method which can be reusable with less effort. 



Disadvantages of having Factory methods to create instances 
  • It is hard to distinguish factory static method form other available static methods
  • Non public classes cannot be sub classed(If we have factory method to create instance then we can make that class a private) 

Thursday, January 19, 2012

Continuous Integration( Part Four) : Deploy Web Application to a Remote machine Using MSDEPLOY

As I mentioned in my previous blog bost  there is a better option for deploy a web application in to a IIS location through MSDeploy command line tool rather than using XCOPY. In this post I am going to brief the issues I encounter during web deployment phase and the steps I followed to overcome them.

Issue 1:
When I package my web application from my local machine it creates a MVC-Client.deploy.cmd file which is referring MSDepoly path as :
                 MSDeployPath="C:\Program Files\IIS\Microsoft Web Deploy V2\"
But In the build server machine (Locate in same network) it creates a MVC-Client.deploy.cmd file which has MSDepoly path as
                MSDeployPath="C:\Program Files (x86)\IIS\Microsoft Web Deploy\"

And I have both versions of MS Web Deploy installed on both machines. But there was an issue when I try to deploy web application to the the web server from the build server machine.
                MVC-Client.deploy.cmd /y /M:es-websrv01/MSDeployAgentService
Reason is it refers version 1 instead of version 2. And I can garentee you that I have same MSBuild versions in both my local machine and build server machine. I dig a bit about this issue and I found that we need to install VS2010 service pack one to generate the working MVC-Client.deploy.cmd file. In my development machine i had it and on the build server machine it has not installed. Installing VS2010 service pack 1 fixed this issue.

Issue 2:
Permission Issue
In my case Jenikings is running as a windows service which initiates by a local user(Not In the Active Domain) in the build server machine(Windows NT ). But in order to do the remote deployment that user should have admin privileges in the target remote machine(es-websrv0). So what I did is just add a user in to the AD with the admin privileges for es-websrv0 and did the deployment

Another permission issue I encounter is we cant do the remote deployment from the Programs files folder in C:/ since it has special permission level.  

Issue 3:
Required Softwares which should be installed in target web server machine.
As I notice there are two ways of do the remote deployment as follows make sure that you have installed corresponding soft-wares on the destination machine.
M: Destination server name or Service URL
    If this flag is not specified, the package is installed on the computer where the command is run. The Service URL can be in the following format:
        https://:8172/MSDeploy.axd
    This format requires that IIS 7 be installed on the destination server and that IIS 7 Web Management Service(WMSvc) and Web Deployment Handler be set up.


    The service URL can also be in the following format:
        http:///MSDeployAgentService
    This format requires administrative rights on the destination server, and it requires that Web Deploy Remote Service (MsDepSvc) be installed on the destination server. IIS 7 does not have to be installed on the destination server.

Sunday, January 15, 2012

Continuous Integration( Part three) Things That can be done from the Build Server Side


Note : If you are interested in installing jenking build server for .Net applications I found an interesting post which has a good step by step explanation. 
Before going through this blog post I would recommend you to go through following blog post which gives you knowledge which is useful to understand the things mention in this post.
As I mentioned in above CI-Part Two we can create a IIS deploy-able packages with different configurations on the built server machine.

 Requirement : 
 "Automate the deployment process on IIS location for every successful  build.Moreover I need to automate multiple deployment with different configurations."

If I breakdown above requirement further, it is obvious that my first task is to create multiple packages with different configurations if and only if the build process is successful. In this case I may need some support of build server side to trigger me after a successful build. Once build server trigger me I have to think of creating packages with different configs. First question arise is as follows.

Me : Hey Jenkings, Do you have a plugin which you can trigger me after a successful build ? 
Jenking : Yes. I do have many which you can get your job done.
Me : Thank god. Then I will be surviving..... :) 

There is a good plugin to get this job done which is called Jenkins post built task plugin. By using above file I can execute any command line operation by checking the status of the build server build report. So what can I do is searching through the build report and find the build status. And then if it successful then execute a batch file or simple command line operation for the deployment. By ticking on the post built task you can get the following post build task. (In this example it runs the script if the build is failed)












So now we have a way to trigger a batch command if the build is successful.Then the next task is to find a way to do deployment automation.First I need to think about a way of creating packages with different configurations.I found following possible approaches of doing the packaging.
  • Assign Multiple jobs to jenkins server for different configurations :
In project configuration section you may find the build task. Here you can explicitly tell jenkins build server the configuration you want to build and package.(Simple it accepts MSBuild external parameters)


In this comamnd line argument section you can pass /t:package /p:buildsever and then it package web project which has the build server configuration. Similarly what you can do is assign new job to the jenkings server and in that job in the build section pass other configuration which you want to create the package.(eg: Live Server Configurations)
  • Build the package with multiple configuration by using a single Jenkings job:
Only change is in the command line argument section you can add two configuration which separated as follows.
              /t:package /p:buildsever;liveServer
But in order to get this job done you need some changes in the sln/csproj file which you are referring in the build server. This post will helps you to get this project file configuration done. 

     
At this point we are almost done with the packaging process.Next remaining thing to be done is deployment process of multiple package.Here I would suggest following approaches to to do it.

  • Use XCOPY command to copy the newly build package in to IIS location :
In this approach what you need to do is execute XCOPY command in Script section in post build plugin section.
 cd to project location in build server          
 XCOPY Views \\ES-WEBSRV01\Library\Views /e /y /i
 XCOPY packages.config \\ES-WEBSRV01\Library /y  


Similarly you need to copy all required folders in to IIS location.
\\ES-WEBSRV01\Library is the place where we deploy our IIS application.If your IIS location is on a another machine rather than the build server machine you need to share the location with the build server machine as above.But here we have a tricky problem. As i mentioned in my previous blog post there is a issue with the web.config file.So what we need to do is go to the project\obj\release\TransformWebConfig\transformed in the build server and get the transformed web.config file and then XCOPY it in to IIS location.(here release means you configuration)

Note : You need to do this for all packages built by the build server
  • Deploy using msdeploy command line tool ;
You can find your installed msdeply.exe in C:\Program Files\IIS\Microsoft Web Deploy

Once build server created the web package you can see a windows batch file named projectName.deploy  in Project\obj\release\Package. In the post built plugin script section what you need to do is run this batch file and it does the deployment.For that you need to go to the file where you can find msdeploy.exe and then run that batch file as follows.
C:\Program Files\IIS\Microsoft Web                               Deploy>H:project\obj\release\Package\MVC-Client.deploy.cmd /T 
It will deploy you web application in to the IIS location with the correct configurations which you want to deploy.

Note : You need to do this for all packages built by the build server


Saturday, January 14, 2012

Continuous Integration( Part Two) :Web Config Transformation


Note : In this post I will use Microsoft based technologies. But the main concept describes in a general manner.

In my previous post I mentioned that a build server should run the tests with its configurations(eg: data base connection strings) and if the test are successful then it should deploy working packages in to many web container location according to your requirement.For an example it should deploy a working package in to productions server as well as in to the live server with their specific configurations.(both application are pointing their own data bases)

production server => production database with tests data for QA guys
Live Server => live data base with the actual data 

In order to do this, build server has to create several packages with different configurations and deploy them in to required locations.There are many packaging tools which facilitate configuration transformation functionality.In this post I will use MSBuild command line tool to create IIS deployable packages.Before Moving on we need to know a bit detail knowledge about web config transformation.

If you have a close look in to your web.config file which created by VS2010 you will notice that there are two config files which named as web.Debug.config and web.release.config. Those two files default files which offer by VS2010.If you want your own you can add since VS2010 provides you an extensible configuration setting environment.

                          Build =>Configuration Manager  => Add your own configuration 

Lets assume we have created configuration for our production server which I mentioned above.Till you cant see it your latest configuration setting appears on web.config file. In order to set it you should do following step.

                         right click the original web.config file and click the context menu command “Add Config Transforms” 
In the Web.BuildServer.config file you can write specific settings which is specific to the build Server settings. Following is the way we do the we web.config transformation. 

 

    
      
     
   

You can see here we have used XML Transformation Engine which does the actual task when we package our project with build Server configurations.Followings are the some of functionality offer by transformation engine.


Other than the xdt:Transform tag you can see we have used a locator which refer the original web.config configurations. 
And following is the MSBuild command which we can transform web.config which has the build server configurations. 

                   /t:TransformWebConfig /p:Configuration=BuildServer" 

Also you can create your web deployment package with the build server settings by following MSBuild command.

           "ProjectName.csproj" /T:Package/P:Configuration=BuildServer;

It creates a ZIP file which has batch file which can be executed from MSDepoly command line tool.And also we can see transformed and original web.config files. Here we have a small problem.That is if we manually unzip this created zip file and then manually copy to the IIS location . then build server specific settings are not applying to it.Since in web.config file refers the transform elements from a external XML file which is used by the MSDeploy command and it is the task of MSDeploy tool to read the external XML property file and replace the matching tokens. So if you do the deployment manually I recommend you to copy the transformed web.config and replace the existing web.config file in the package.Then you can manually copy  package in to the IIS location and your app will work since now you have the build server configurations.

Ok.Now we should back to our main topic again which is Continuous Integration. If we can use above concept in the build server side (through a build server job) we can create a package in build server machine with its specific configurations and then deploy it. Also we can use same strategy for multiple deployment with many configurations.And my next post will describe how we can achieve this task. I hope to use jenkins build server and some of its plugins to do it. 


Continuous Integration( Part One) :Build server

why we need a build server ? 

Before moving in to the today's topic I would like to explains the typical scenario of the software development with out using continuous integration. Suppose that your project team is using a source controller where you save all source files in a shared location for the collaborative development process. How it works is simply a developer implements a feature of your product and then do the testing on developer's environment. If the testing  is successful he/she push the new changes in to the source controller. Following diagram explains it briefly.
Here the developer must do the modification such that the latest version is build on every other developers environments. Here what I am trying to notice is that it is not sufficient the latest version build successful in one machine.Lets say another developer get the latest update and it is not working in his machine.Reason is there may be some configuration which you forget to commit and it leads to errors in the latest version of the software in other's machines. Those are things that the software engineers had to spend much time to fix which reduce the productivity of your team.

Solution for this issue is to introduce a third party built environment which is isolated from developers' specific setting. It should be an environment which user its own configurations (eg : database configurations)


Simple you can configure your build server such that it runs in an isolated environment and runs all unit testing and UI testing(Selenium). If it fails also build server can configure such that it sends a mail to developers with the build error message.

Following are few of available build servers in today's software industry.
http://hudson-ci.org/
http://jenkins-ci.org/
In my next blog posts I will use jenkins server for explanations.

Followings are the basic tasks which we expect from the build server side to make a end to end Continuous Integration.

  • Get the latest updates from source controller and run all unit tests/UI tests(Selenium)
  • If the tests are successful then automate the deployment process. There can be multiple deployments take place.Eg: Live deployment,Production deployment
  • Create a package which can deploy on your web container and save it with the version.Simple its like keeping working copies of software packages for each working changes.

Thursday, January 12, 2012

Add Java ,XML code snippets in to blogger posts

Most of time I found that writing a XML tags in a web page (Specially in blogger) is a really tricky task. There are some thrid party java scripts and css files which allow us this functionality. But since they are hosted in remotely there may be a risk of losing our blog data.for an example you can try . Here you can specify any programming language syntax as well as XML syntax.But if we have an option to keep our own CSS then the stability of our blog is higher than the previous case. I found following way of doing blog postings for XML syntax files.
Post
 Following is a sample of XML file i create using the css content mention in above post.
 


  
    
  


 

Where We Need Dependency Injection

Recently I was working with a .Net project which uses Entity Framework .It has a layered architecture where we can find following separate layers.

 Service layer (Eg: Order Services)
 Domain Layer (Eg: Domain entities like book,Order)
 Infrastructure Layer (Repositories, DBContexts,Unit of work pattern Impl) 
 MVC3 Client (Presentation Layer)

 In my case Service methods are called in controller classes in MVC3 client package(according to the mvc pattern). MVC3 client package and Service layer are implemented by two developers .In this case MVC3 client project does not know much details about Service package and all he knows about the service package is that he can get some services by passing values to the service method.

 Eg: Lets say in service package we are having BookService class which is offering borrow book functionality. Then from the controller’s point of view what he wants to do is borrow a book by just passing the book id. Simply the controller doesnot want to know the underline functionality of Bookservice class (DBcontext,repositories,unitofworks)

 But according to the implementation of the BookService class it has only one constructor which has all its dependencies which are unknown by controller (MVC3 client project). Then when it comes to instance creation of BookService class we may end up with big issue. To solve this issue we need to inject dependencies of BookService by using a third party which knows about object creation of BookService class. This is called contractor dependency injection .Actually what controller wants to know is how to use bookservice object instead of knowing how to create BookService object.

Following are the structure of CSharp classes  I was explaining above.

  
public class BookService : IBookService
{
       public IBookRepository _bookrepository;
       public IUnitOfWork _unitOfWork;
    public BookService(IBookRepository bookRepository,IUnitOfWork unitOfWork)
    {
         _bookrepository = bookRepository;
         _unitOfWork = unitOfWork;
     }
    public Book BorrowBook(int bookId)
   {
         //Logic Goes Here
    }
}

Public class BookController
{
   IBookService _bookService;
    public BookController(IBookService bookService)
   {
           _bookService = bookService;
    }

   //Borrow book HTTP POST 
   public void BorrowBook(int bookId)
   {
        _bookService.BorrowBook(bookId);
    }
}

Here We can see we have not create object of BookService so BookController does not need to know about BookService dependencies. In order to get this working we need to use third party dependency injection tools. For .Net project i would recommend winsor container which is more flexible to use. Following tutorial illustrate how to use winsor for dependency injection.

http://stw.castleproject.org/Windsor.MainPage.ashx