Tuesday, March 09, 2010
Here is the video clip on Practical TDD - the virtual learning session series. It’s little over one hour presentation that I gave on 8th March, 2010
Alternatively, if for some reason you can’t see embedded player here or prefer to watch on Viddler then here is the direct link to the video
Direct Viddler Link to the video : http://www.viddler.com/explore/mdmavani/videos/1/
Sample solution used during the session can be downloaded from the link below
http://code.google.com/p/mahendrablog/source/browse/trunk/UnitTesting.rar
For further reading here are some useful links
Keep an eye here for more learning opportunities.
Till the next time… Happy coding
Monday, March 08, 2010
As Promised here is the link to join session.
1. Please join my meeting.
https://www2.gotomeeting.com/join/225879818
2. Use your microphone and speakers (VoIP) - a headset is recommended. Or, call in using your telephone.
Dial 712-338-7136
Access Code: 225-879-818
Audio PIN: Shown after joining the meeting
Meeting ID: 225-879-818
We will start the session March/9/2010 9:30 AM IST. Make sure your system meets the gotomeeting requirement.
To verify follow this link : http://www.gotomeeting.com/fec/online_meeting
Wednesday, March 03, 2010
Based on standard deployment practice that we follow at Headspring, our project too, has tarantino console deployer in place. This consoloe deployer is triggered by Cruise Control project. This set up enables our Product Owner team to push the button anytime they want to get latest version of application.
As I mention above, process of deployment involves manual trigger on cruise control web dashboard or through local tray client (Yes, we are using CruiseControl.Net). CCNet project then passes call to tarantino console deployer which in turn uses batch file to run nant script. This nant script read environment specific variable like database setting, destination path for web app and related schedule jobs etc. We abstracted this in single bat file which reads all these variable from environment variables. Hence the main batch file will just need to set bunch of environment variable before calling these common batch file. The main batch file looks like this:
1: SET variable1=somevalue
2: SET variable2=someothervalue
3:
4: CALL CommonDeploy.bat
And the common deploy batch file is:
1: nant\nant.exe -buildfile:deployment.build -D:variable1="%variable1%"-D:variable2="%variable2%"
So bottom line is , CCNet calls tarrantino app which passes call to Environment specific main batch file which in tern passes the call to common batch file( after setting required environment variables, of course).
Recently we started getting complaint from Product Owner team that some of the data is missing from testing environment. This was some meta data which gets generated as one of the later step during deployment. After looking at NAnt output from CCNet dashboard, I realize that failure from within common deployer batch file was not getting propagated to upper level and hence CCNet was happily showing status as green even after those inner failure. This failure then stopped execution of last step which generate meta data in question.
This was classic nested batch file problem. After googling here and there and experimenting my own idea, I got hint from Matt and boom we fixed it. Here is our solution. Our new batch files looks file this now:
Environment specific Main Batch file:
1: SET variable1=somevalue
2: SET variable2=someothervalue
3:
4: CALL CommonDeploy.bat
5: if "%ERRORLEVEL%"=="0" goto SuccessfullEnd
6: echo Failure: Failed while deploying Enhanced Version
7: exit /B %ERRORLEVEL%
8:
9: :SuccessfullEnd
10: echo Success: Both Enhanced and Basic Version are deployed successfully.
11: exit /B 0
Common Deploy batch file:
1: nant\nant.exe -buildfile:deployment.build -D:variable1="%variable1%" -D:variable2="%variable2%"
2: exit /B %ERRORLEVEL%
Key here was to report proper error level to your immediate parent. Do I need to say anything now:)
Till next time…..Happy coding
Monday, February 22, 2010
This is great. One more reason to love gmail. I don't think I have to explain anything. Picture tells the story:
Wednesday, February 10, 2010
Forms are one of the very common requirement, especially if you are dealing with any government body. With aspiration towards automation, everybody seems to be moving towards PDF Forms which you can print but doesn't let you save soft copy of it.
On my current project at Headspring, we came across such requirement. System under development deals with multiple organizational bodies. Part of the integration effort needed submitting forms which are in predefined format. Most of the information that needed to be filled in has already been captured by the system. Hence in order to reduce manual work burden and thereby avoiding potential human error (either by typo or due to repeated work burden), it is required to be filled in automatically at the time of generation. In other work, as user to the this system, I want to pick certain record and click on link to generate particular form which is pre-populated with values for current record. Again remember, the original source here is PDF Forms as defined out side the system by third party.
Since open source is heart of our core development effort at Headspring, our first and very natural reaction was to look for any existing open source solution. Our lead architect Kevin Hurwitz has mastery in this area. Given any problem of such nature, Kevin can either elegant open source solution or come up with one, in almost no time (Some day I would like to steal this skill from Kevin).
In this case Kevin has come up with “iTextSharp” library. Little bit experimenting with it here and there, and we concluded that it will meet our requirement perfectly fine. Ours being ASP.NET MVC application, we decided to extend ActionResult which can be hooked up with any application. Here is our approach:
Step one is, ofcourse, download iTextSharp library and take dependency on it. Next is following interface
1: public interface IFormBinder<TFormModel>
2: {
3: byte[] Bind(TFormModel model, string pdfFormTemplateFullPath);
4: }
This is very simple (generic) interface with just one method. Generic type defined here is Model for any given PDF form [Yes, like all our view page, here to we opted to go with one Model per Form convention.. very soon, we will understand, why]. Next we have abstract implementation for this interface, which will lift most of the burden of filling values to given PDF form. Here is the code for that class:
1: public abstract class BaseFormBinder<TReportModel> : IFormBinder<TReportModel>
2: {
3: public virtual void BindFormFields(TReportModel reportModel, AcroFields acroFields) { }
4:
5: public byte[] Bind(TReportModel reportModel, string pdfTemplateFullPath)
6: {
7: var memoryStream = new MemoryStream();
8:
9: PdfStamper pdfStamper = null;
10: try
11: {
12: var pdfReader = new PdfReader(new RandomAccessFileOrArray(pdfTemplateFullPath), null);
13:
14: pdfStamper = new PdfStamper(pdfReader, memoryStream);
15:
16: var acroFields = pdfStamper.AcroFields;
17:
18: BindFormFields(reportModel, acroFields);
19:
20: pdfStamper.FormFlattening = true;
21:
22: pdfStamper.Close();
23: }
24: finally
25: {
26: if (pdfStamper != null) pdfStamper.Close();
27: }
28:
29: return memoryStream.ToArray();
30: }
31: }
This base class reads source PDF form given path and uses iTextSharp library to fill in data to this form and finally returns filled pdf form as byte array.
Next step is creation of custom ActionResult as follow:
1: public class PdfFormResult<TFormModel> : ActionResult
2: {
3: public PdfFormResult(TFormModel model, string formTemplate)
4: {
5: Model = model;
6: FormTemplate = formTemplate;
7: }
8:
9: public TFormModel Model { get; private set; }
10: public string FormTemplate { get; set; }
11:
12:
13: public override void ExecuteResult(ControllerContext context)
14: {
15: var pdfFormTemplateFullPath = HttpContext.Current.Server.MapPath("/PdfForms/" + FormTemplate);
16:
17: var formBinder = ObjectFactory.GetInstance<IFormBinder<TFormModel>>();
18:
19: var content = formBinder.Bind(Model, pdfFormTemplateFullPath);
20:
21: var result = new FileContentResult(content, "binary/octet-stream");
22: context.HttpContext.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", FormTemplate));
23:
24: result.ExecuteResult(context);
25: }
26: }
This is yet another generic class, which takes report model as it’s type. Main point worth highlighting here is line 17, which uses IoC container to resolve instance of IFormBinder. To me, this is classic example of leveraging IoC to it’s full capacity and simplifying your code. For my case, IoC is StructureMap and all I have to do to configure it for above need is, define following Structuremap registry: [I defer any further explanation about this to my buddy, Jimmy]
1: public class MyRegistry : Registry
2: {
3: public MyRegistry()
4: {
5:
6: Scan(cfg =>
7: {
8: cfg.Assembly("PdfFormGenerator");
9: cfg.With<DefaultConventionScanner>();
10: cfg.ConnectImplementationsToTypesClosing(typeof(IFormBinder<>));
11: });
12: }
13: }
Once all these in place, for any new pdf form, all I have to do now is
1) Define Report Model
2) In my controller write action that returns PdfFormResult<ReportModel>
3) Define FormBinder that extends BaseFormBinder<GivenReportModel>
For Completion here is code for all three steps above, for a sample 2 field pdf form
Report Model:
1: public class SampleFormModel
2: {
3: public string Name { get; set; }
4: public string Gender { get; set; }
5: }
Controller Action:
1: public PdfFormResult<SampleFormModel> PdfForm()
2: {
3: var model = UseSomeServiceToGetThisData();
4: return new PdfFormResult<SampleFormModel>(model, "SampleForm.pdf");
5: }
FormBinder:
1: public class SampleFormBinder : BaseFormBinder<SampleFormModel>
2: {
3: public override void BindFormFields(SampleFormModel reportModel, AcroFields acroFields)
4: {
5: acroFields.SetField("Name", reportModel.Name);
6: acroFields.SetField("GenderMale", reportModel.Gender);
7: acroFields.SetField("GenderFemale", reportModel.Gender);
8: }
9: }
That’s it. Yes..you are done. Don’t believe me? Here is the sample app, download and play with it yourself .
Till next time…Develop smartly…
Monday, February 08, 2010
Some level of Reporting is very much integral to any web application now a days. Traditionally we have been writing special html page to achieve this result. This page is specially formatted to fit reporting requirements (like printer friendly view) which is achieved by mean of CSS magic. There is nothing wrong with the approach except the fact that it violates DRY [Hey, isn’t same content available in some other html page as well which is not suitable for direct printing??]
The violation of DRY comes with it’s own technical debt. Now every time you have some change to the page, you need to ensure same changes must be applied to the corresponding reporting page as well. Other issue I have with this kind of reporting pages is, they are neither very good fit as saving soft copy for later use nor they are mean to be shared easily with others.
We, at Headspring, are married to idea of least possible technical debt. Having separate print page just for the sake of formatting is something that clearly goes against our principle. For the very same reason, we opted for “HTML to PDF Conversation” approach. Hence we are not duplicating same content in two html page rather uses same html fragment on browser view as well as PDF view. Looking at available option we found “Prince” is very good fit for our requirement and hence we made Buy decision over Build and trailed Prince library for our need which in this case is ASP.NET MVC web application.
In very simple terms, Prince works as filter on response stream, intercepting browser response just before it is about to be rendered. Once html response is handed over to prince, rest magic happens inside prince which understands CSS 3 and formats your html into nice looking PDF document. Prince has very rich formatting support which includes repeating header, footer on each page and repeating caption row for table when table content span across multiple pages.
Here is solution for putting prince to work for you.
Create and HttpModule like this
1: public class PrinceModule : IHttpModule
2: {
3: public void Init(HttpApplication context)
4: {
5: context.BeginRequest += context_BeginRequest;
6: context.EndRequest += context_EndRequest;
7: }
8:
9: public void Dispose() { }
10:
11: private void context_EndRequest(object sender, EventArgs e)
12: {
13: var httpApplication = (HttpApplication)sender;
14:
15: if (IgnoreRequestForPrinceFilter(httpApplication.Request))
16: return;
17:
18: httpApplication.Response.AddHeader("Content-Type", "binary/octet-stream");
19: httpApplication.Response.AddHeader("Content-Disposition", "attachment; filename=Report.pdf;");
20: }
21:
22: private void context_BeginRequest(object sender, EventArgs e)
23: {
24: var httpApplication = (HttpApplication)sender;
25:
26: if (IgnoreRequestForPrinceFilter(httpApplication.Request))
27: return;
28:
29: httpApplication.Response.Clear();
30:
31: AttachPrinceFilter(httpApplication);
32: }
33:
34: private static bool IgnoreRequestForPrinceFilter(HttpRequest req)
35: {
36: return (req.Params["ViewAsPDF"] == null);
37: }
38:
39: private static void AttachPrinceFilter(HttpApplication httpApplication)
40: {
41: var configuration = ObjectFactory.GetInstance<IConfiguration>();
42: var path = configuration.GetPrincePath();
43: var prince = new Prince(path);
44: prince.SetBaseURL(httpApplication.Request.Url.AbsoluteUri);
45: prince.SetLog("prince.log");
46: prince.SetInsecure(true);
47:
48: httpApplication.Response.Filter = new PrinceFilter(prince, httpApplication.Response.Filter);
49: }
50: }
Next step is to register it with your web.config, under httpModule section
<httpModules>
<add type="Cuc.Jcms.UI.ViewPage.PrinceModule,Cuc.Jcms" name="PrinceModule" />
</httpModules>
Let’s look bit closely at the code snippet above. Notice two important points here
1) Module has real work to do only when request was made with parameter namely “ViewAsPdf”.
2) AttachPriceFilter method is reading prince path from configuration (which in this case is hidden behind Interface and I am using IoC to get concrete instance of it).
So once this module is hooked up with your website, all you have to do is add ViewAsPdf=1 at the end of url and see any page as PDF document. [Prince however has requirement that the source html page should be valid xHtml page. Since we are building website that is ADA, Section 508 compliance, every single page in my app is xHtml compliance. And yes we do have mechanism in place to validate this automatically. ]
Approach, I have highlighted above comes with a side benefit of supporting easy UI testing in automatic fashion. We uses WatiN/Gallio/MBUnit combination for automatic UI testing which now also includes not only generating PDF report pages but also asserting on it’s content through native WatiN library support, just like how you would do it for any other html page. After all these PDF report pages are html page only and we can get html response when we request original URL after removing “ViewAsPdf=1” .
Till next time, Code smartly…
Thursday, October 15, 2009
As the month of October proceed, 1 billion people from all around the world are busy preparing for their grand festival; The Diwali. It’s bit of misfortune for some of my friends here in America, that they have no idea about what 1 in every 6 person on the earth, is busy celebrating with. Why not to take this as opportunity to tell them about social as well as spiritual significance behind the festival? There is my 2 cents :)
Diwali, which is also known as Deepavali, is a festival of lights. These light signifies enlightenment, joy of victory of Dharma(implies as truth or good) over Adharma (implies as darkness, bad or evil). The day of festival also mark end of year as per Vikram Samvat Calendar, one of the oldest calendar in the history of man kind.(The Vikram Samvat was founded by the emperor
Vikramaditya of
Ujjain[1] following his victory over the
Sakas in 56 BC. More accurately, this calendar is 56.7 years ahead (in count) of the solar calendar).
Deepavali is Sanskrit word which means “row of light” (Deep means light and Avali means row). It teach us to drive way darkness by spreading light of knowledge. Spiritually, it is the day when Lord Ram returned to Ayodhya after completing His 14 year of exile (referred as Vanvas in Indian literature) and His victory over Ravana. Full of joy, people of Ayodhya welcomed their king by lighting rows(avali) of lamps(deep) and hence the name Deepavali. Just as we celebrate birth of oneself, Deepavali is for celebration of inner light which outshines all darkness or ignorance and awakening us to know our true nature; far far away from just physical existence.
To celebrate the occasion, people light oil lamps in and around their house and set off firecrackers. People paint and clean their homes, buy new clothes and distribute sweets to their relatives and friends. By spreading light in every corner of our premises, we try to destroy the reign of darkness, on the night of Diwali. People decorate their premises with diyas, electric bulbs and other decorative electric lighting fixtures, to make their surroundings filled with colorful light and to make it bright and beautiful. Many interesting rituals and traditions have been attached to the celebrations of Diwali. Fire crackers are burst and people enjoy wearing new clothes, on the auspicious day.
Diwali is a five-day long festival, which is celebrated with fun and fervor.
The first day of Diwali is known as 'Dhanteras' which is the thirteenth lunar day of Krishna Paksha, of the Hindu month of Kartik. Lord Dhanwantari came out of the ocean with Ayurvedic on this day for the welfare of the mankind. People renovate, decorate their houses on this day and make traditional 'Rangoli' on the entrance, to welcome Goddess Lakshmi. Lamps and candles are lit throughout the night. It is considered auspicious to buy gold and silver on this day. Many people opt for buying new utensils on this day.
The second day of Diwali is Narak Chaturdashi.Lord Krishna killed the demon Narakasur on this day to make the mankind free from his fear. It is a tradition to massage the body with oil and to bathe on this day. According to an interesting saying it is believed that those who do not bathe on this day go to the Narak (hell).
The third day is the main day of the Diwali festival.On this day, people wear new clothes and share gifts and sweets with their friends and relatives. Women prepare delicacies and whole house is illuminated with 'diyas' and candles. Fireworks and crackers are the kids' favorites on this day. This day signifies end of year.
The forth day is new year day (as per Vikram Samvat). Day starts very early for all devotees as they get ready in their new cloths, visit temple, chant to the GOD, and then wish each other “Sal Mubarak” (i.e. happy new year)
The fifth day of the diwali is Bhai Dooj, the time to honour the brother-sister relationship. On this day, sisters invite their brothers and their family to their homes and treat them with delicacies. In turn, brothers offer them with gifts and sweets. Legends have it that in the Vedic era, Lord Yamaraj (the God of death) visited his sister Yamuna on this day and blessed her with a boon that if brothers visit their sisters on this day then they will be liberated from all their sins. Since then it is a tradition that brothers visit their sisters on this day and the sisters sweeten their mouths with variety of sweets. The celebration of the Bhai Dooj marks the end of the five days long festivities of Diwali.
For the benefit of my American brothers and sisters:
US President Barack Obama has joined the this grand movement by participating in ceremonial Diwali lamp at white house. Although it was Bush era back in 2003 when Diwali celebration began at white house, Obama was the first American president who had fortunate opportunity to personally inaugurate the ceremony.
Finally, for the geeks in Austin, there is great opportunity to personally attend the celebration and thereby know more about the festival. Barsanadham temple is celebrating grand festival on this Saturday, Oct, 17th 2009 beginning at 5:00 PM. Here is the published schedule:
5:00 pm Dinner prasad
6:00 pm Temple tour (in prayer hall)
7:00 pm Temple tour (in prayer hall)
7:30 pm Temple program – State Representatives & community leaders lighting the dias ceremony, kirtan, pravachan, arti
9:00 pm Grand fireworks display
9:30 pm Ras Garba – Live garba singers: Sur Sangam of Hurst, TX
Address: Barsana Dham
(SW of Austin on FM 1826, 7 miles from Hwy 290)
400 Barsana Rd.
Austin, TX 78737
(512)288-7180
I am there along with my friends and family. Be there and be part of “The Light”.
Monday, September 28, 2009
Jack has great write up on 7 s/w waste. I couldn’t kind index page which provides easy access to all of them. With all due respect to Jack Milunsky, here is my humble try
Disclaimer:- None of above is my own creation and full credit goes to Jack for it.
Wednesday, September 23, 2009
Over this weekend, I facilitated workshop on Refactoring. My company was kind enough to host the screencast for me. Earlier I posted link for ppt and demo application download here.
If you rather prefer to watch it directly at screencast site, here is the direct link
http://www.screencast.com/t/gI7XXQMQ95S
Thanks to Jeffrey Palermo, for the big favor and editing and uploading the screencast.
Monday, September 21, 2009
We at Headspring uses Tarantino for database change management. Earlier I have blog it’s ability to skip certain script file and how to use this feature.
As per the standard Headspring practice, we develop our project in the environment that facilitate close collaboration with customer. Which implies that our customer is seating next to developer team and will test user story as and when it gets completed by development team. This unique setup enable early feedback to hone the end product. Since customers are continuously testing system, they need to maintain right set of data that represent real life scenario. While testing specific scenario, customer will enter some supplemental data and perform transactions which again ends up modifying core data. This obviates need of resetting database to known state to perform further testing.
With Tarantino, deploying your application to staging environment is automatic. (If you aren’t aware of this feature of Tarantino, go and read it from here.) Hence if can capture script (both schema and data) that represent current version of database at any given time, then later on resetting database back to known state is simply mean recreate your database from this script.
Catering to this need, I have put together utility which will generate schema and data script for given database instance (Works only with SQL Server, any version as it uses SMO library which is specific to SQL Server)
We have been using this utility for over more than month and it make our database resetting step easy enough for us to forget about that step at all.
If you are curious and have similar need, you can grab the utility from the following SVN repository. You need svn client to download it. If you haven’t got it already, get one from here.
http://svn2.xp-dev.com/svn/mdmavani-DbSnapTaker/