Desktop GA

February 24, 2015
by Samir Ghosh

I’m writing to give an update on WaveMaker Studio Desktop.   Thanks to everyone who’ve been patiently waiting.  We started our Desktop beta program end of November and have received great feedback.  We were way over subscribed to our Desktop Beta, so apologize to those who are still waiting.  We expect to release Desktop for GA in March.  We will send individual notices to those who requested Beta access when Desktop is released.

We have a lot of loyal users who think of WaveMaker synonymously with the desktop product.  However, after our big investments in WaveMaker, Studio is now one of three core pillars to the WaveMaker Platform – WaveMaker Gateway (our API Management software) and WaveMaker Cloud (our Docker-based private PaaS software).  Within Studio, Desktop is now one of various flavors, including our team enterprise edition WaveMaker Enterprise, and the online SaaS Studio with trial enterprise features at http://www.wavemakeronline.com/   Thanks for all of the encouraging and constructive feedback we’ve received!

We’ve worked very hard to modernize WaveMaker Studio, e.g., utilizing Bootstrap and AngularJS, simplifying the UI, adding API Designer, SmartLayouts for auto-responsive multi-device support, version control integration, multi-developer projects, database designer, and many more capabilities.

This resulted in some complexity in orchestrating the build, delivery and maintenance of our various versions.  Keep in mind, not only do we now provide WaveMakerOnline SaaS, but on-prem software in single user and team platform (enterprise) versions.  Getting this versioning and logistics ironed out took a bit longer than we’d hoped.  We’ve also been taking the time to refactor now for long term benefits.  For example, we’re painfully refactoring legacy REST API backend code just to improve the readability of the generated code.

The good news is that we will be releasing Desktop shortly, and will be working to evolve the Desktop into not just a stand-alone single developer install, but optionally an important option integrated with our WaveMaker Enterprise team platform, which is delivered as a virtual appliance.

If anyone is interested in trying WaveMaker Enterprise (all the WaveMakerOnline team capabilities but on-prem), please contact us.

And please do send us feedback as to why Desktop is so important to you.  We want to make sure we keep moving the Desktop edition in the right directions.

Making RAD good for developers

February 11, 2015
by Deepak Anupalli

Rapid Application Development (RAD) tools and platforms offer agility and enable development teams to jump start quickly onto a Project. Use of RAD methodology reduce the time and effort required to:
a) evaluate the technology stack and frameworks
b) design and implement boiler-plate CRUD code, SQL queries and UI-based forms
c) prototype and test with production data very quickly

In the past, the code generated by RAD tools in comparison with hand-written code was considered to be not readable, not maintainable and believed to offer very less customizations and abstractions. However, frameworks and technology stacks have matured over time, moving a lot of heavy lifting from developers and offering better tooling support. With the current generation RAD tools and platforms leveraging modern technology stacks, there is no noticeable difference between generated code and hand-written code.

WaveMaker Studio incorporates advanced code generation techniques with the right abstractions and design patterns, rather than generating code that just works. WaveMaker Studio provides niche application architecture by standardizing on open-source Application Stack, using some of the best-of-the-breed libraries like Spring, Angular, Hibernate and Bootstrap. Open standards application stack enables developers to freely distribute and modify the generated source code and doesn’t have any vendor lock-ins into the platform.

No platform lock-ins for built applications

While most of the Rapid Application Development platforms tend to lock-in applications within their own platform, like Force.com, BlueMix or Mendix, WaveMaker takes a radically different approach to use open-standards based generated code and 3rd party services integration through plug-n-play REST API based contracts. Developers have the liberty of moving the application built from the platform and deploying in their own custom infrastructure.

Studio app architecture
Fig 1. WaveMaker-built Application Architecture

Code generation with no trade-offs in design or performance

Angular JS library, built and maintained by Google, came into mainstream adoption only in the recent years. Angular is the key driver for WaveMaker front-end code generation, leveraging the abstractions provided by the framework to generate dynamic client-side application logic. Generated code extensively uses Angular concepts such as directives, re-usable components, data binding, routing and form validation.

Let us build a CRUD based application to take a closer look at WaveMaker Studio generated code for front-end and back-end artefacts. The following Fig 2. shows a simple application page design with separate sections for header, left navigation and content.

Page_Design
Fig 2. Application design canvas

Well designed and organized front-end artefacts

The content section has a 2-row grid layout, each row having different number of columns and widgets placed within. Following Fig 3. Shows the code generated by WaveMaker Studio for the above web page design.

Content_Markup
Fig 3. WaveMaker generated HTML markup

The generated markup has separate sections for header, topnav, leftnav & content area and for each widget its corresponding Angular directive gets generated. WaveMaker provides a comprehensive Angular based open source widget library, and the documentation is available here.

Frontend_Codegen
Fig 4. Generated artefacts for each page

For each designed web page, a well organized set of artefacts are generated for HTML, Javascript, Stylesheet & property files for variables defined within the scope of the page. Any event handling code or custom client-side logic should be written in the page-specific javascript file and the HTML markup can be edited directly by using the appropriate widget directive syntax.

Extending and customizing generated code

To control interaction between widgets and variables (service, live, java etc.), custom javascript code may need to be written in the javascript file generated for each page. For example, to enable navigation to a new page after submitting form data, custom javascript needs to be written for onSuccess event of a liveform.

The following example has a snippet of code, which uses custom javascript code to bind data provided through one widget as input to another widget or prefab. WaveMaker Studio’s javascript editor provides code completion and intellisense features to search and identify the available bindings within the scope.

Frontend_JS_binding
Fig 5. Javascript custom binding

Design thinking and Model-driven development (MDD) paradigm

WaveMaker Studio-built application’s back-end architecture leverages Spring framework and Hibernate for persistence.
Studio backend architecture       Backend_Codegen
Fig 6a. Spring framework based architecture, Fig 6b. Spring-based backend code generation

Spring framework is widely used by Java developers and offers a very flexible architecture, extensible and provides cleaner abstraction. WaveMaker Studio provides the right balance between generated code and any runtime libraries used, giving maximum control to the developer to customize and change the generated code.

Studio generates the following artefacts for application back-end:
1. Model Objects – Domain model objects are POJOs with standard JPA annotations
2. Services – CRUD operations and other business logic for model objects
3. Controllers – Spring REST web service controller

WaveMaker Studio adopts model-driven development (MDD) methodology, by importing from existing database schema or allowing developer to first design database schema using the database designer. After successfully importing the schema, for each database table, domain model objects and their corresponding services and controllers are generated. If there are any changes to the database schema, code is re-generated.

In the design mode, Studio supports hot deployment of changes and completely relieves developer from compilation and code-generation aspects. Internally, Studio uses Maven based application build process, which makes the necessary application runtime dependencies to be included in the POM file and provides an option to export entire Studio-built application as Maven project.

Designing the domain model

WaveMaker Studio provides a very comprehensive domain model or schema designer, which supports dialect mappings to the underneath database and provides modelling the relationships as well.

DB_Designer
Fig 7. Database schema designer

Domain model objects are auto generated from the database schema, with JPA annotations and respective database mappings. Getter and Setters are auto-generated with the corresponding column mappings, relationship and join column mappings. Domain model objects are plain POJOs without any dependency on WaveMaker runtime library.
Backend_ModelObjects
Fig 8. Generated code for Domain model objects

Separation of layers for extensibility and integration

Domain model, service and controller layers are separated out in the generated code for extensibility and readability. For every domain model object a Service class is generated, which provides CRUD operations and query execution with complete support for pagination, query filters etc. Service class depends on WaveMaker runtime library, which is open source and provides the persistence runtime logic based on Hibernate.

Backend_CRUD_Services
Fig 9. Generated code for database CRUD operations

API-centric approach as a first step to application design

For every domain model object web service controller is generated based on Spring REST, with appropriate path mappings. For database services, REST controller exposes CRUD operations and query execution methods automatically and the visibility of these APIs can be configured through API designer.

Backend_Controller
Fig 10. Spring RESTful Web Services controller

Summary

WaveMaker Studio generated code incorporates the best practices followed by professional Java or Javascript developers and guarantees best code quality, maintainability and extensibility for enterprise application use. With most of the application back-end code being auto-generated, developers can now focus more on User experience, custom business logic and any other 3rd party integrations.

In a follow up post, we’ll discuss the extensions provided from an application developer’s perspective for customization and tweaking the generated code. We will discuss details related to form validation, styles and themes, Spring bean customization and application security integration. Stay Tuned!

The Rapid Application Delivery (RAD) Reality

January 5, 2015
by Jay Pullur

Traditionally RAD has referred to Rapid Application Development, a way of building applications that contrasts with the more formal Waterfall model. As you would expect, RAD produced results quickly using tools that generated the application code from a high-level description or definition (in other words ‘software design specification’). Readjusting the design specification meant the application could be regenerated, thus saving time needed to rebuild the application to accommodate business changes. So, as a corollary, RAD supported Enterprise Agility.

Shortcoming of Rapid Application Development

Such code (re)generation from a model or specification was done using code-generating tools* that focused on database applications – and that includes a lot of applications. The generated code was rarely as good as the code written by a skilled human programmer. But really, many applications did not need hand-crafted code.
The perceived need for highly performant code confined RAD tools to protoyping, and away from final production (real-life) applications. The generated code was hardly readable and very difficult to maintain. Neither could such code be taken into professional development tools (the modern day IDE) for enhancement. This was a real blocker for writing production-grade applications.
Code-generation was really a tradeoff between how quickly one can hack an application together and the resources it needed at runtime. Indeed, the need for constant business innovation was changing the speed at which enterprise applications were being thought up and written.

RAD for live apps gaining acceptance

Two important factors have started to tilt the balance in favor of RAD or generated code: (1) consumerization of IT or increasing importance of user interface (experience), and (2) adoption of the cloud model or scaling through commodity hardware.
1. UX Factor. Good UX can be the main difference between a hugely successful app and a complete failure of an app in the hands of intended users.
Good UX balances amazing looks, engaging experience, and ease of use. These are not easy for developer teams to build into apps, neither is it natural for them. But with the changing profile of employees and customers, most enterprises are realizing the importance of front-end focused applications, and tools that could help achieve good results quickly.
2. Cloud model. Crashing cost of compute and storage means the primary concern of software development is no longer hardware scarcity and optimized resource utilization. Cloud platforms built on commodity hardware and horizontal-scaling designs have further relaxed the need for handcrafted and highly performant code.Figure 3.2

Rapid Application Delivery is the new RAD

The factors that lead to increasing acceptability of Rapid Application Development (RAD) point us to the inclusion of Rapid Application Deployment as an important supplement. This changes RAD to Rapid Application Development and Deployment (RADD), or simply Rapid Application Delivery (the new RAD).
This renewed interest in RAD is reducing time to deliver new apps – the time between when a business feels the need for an app and the time it is ready to use. A successful RAD platform may have to focus on all 3 elements involved in delivery of applications: Development, Integration and Deployment. Also, RAD tools need to assist in getting the UX to finish.
* Quoted from the book “Code Complete” By Steve McConnell. More here at Chapter 30.

WordPress on WaveMaker Enterprise

December 18, 2014
by Anurag Parashar

WaveMaker hosts applications for thousands of users built using wavemakeronline.com. Keeping promise of free hosting upto 300 days wasn’t a very easy target. Even the smallest of VMs would not have been economical enough. This is when, a year and half ago, we explored containerization and saw that Docker was trying to provide very usable tools for containerization.  We were able to break instance in smaller partitions using container technologies and accommodate many more users on the same infrastructure.  Also as containers provide a lighter form of virtualization and can be launched in a few milliseconds, we could start the whole container on a user web request.  This led us to further optimize the deployments by passivating the application not being used.

Building this platform provided us a lot of learning, which we want to get to the enterprises. Docker based infrastructure provides containers, which can be shipped to different environments with minimal effort and configuration. Though, enterprise finds it challenging to leverage these technologies as these are still scattered.

WaveMaker Enterprise, provides an enterprise solution, which can help enterprises save this complexity and achieve advantages including simplified and automated application delivery, optimized resource utilization along with other enterprise features including monitoring on all levels, role based access control, release management, data backup and recovery etc…

 

What WaveMaker Cloud offers

For an idea on what WaveMaker Cloud offers you, take a quick look at the WaveMaker Cloud page.  Let me list down the top features for the sake of completeness of this post

– Docker architected private cloud with Optimized Resource Utilization

– Micro-service Architecture for application deployment with easier versioning and upgrades of application and platform.

– IT Certified Software Stacks provisioning and configuration

– Continuous Delivery with reusable Software Stacks with minimum configuration.

– Comprehensive monitoring and management of applications, containers and infrastructure

 

How does it all work?

usecase

In a Micro Service Architecture based application deployment scenario, these are typically the steps followed:

 
1. IT Administrator creates the private cloud environment either using infrastructure from their data center or from IAAS providers.

2. Enterprise Architect defines the various micro services and their software dependencies for deployment.

3. DevOps Engineer then is responsible for hardware provisioning from the private cloud for all the services defined by the Enterprise Architect and deploy services.

 

In the world of WaveMaker Enterprise Cloud, the above steps translate into the following steps…

 
1. The IT Administrator easily creates a Docker based Private Cloud infrastructure using WM Cloud’s DIY based cloud management console.- He will create shards, to represent dev, staging & production environments,- Add physical instances to it, where containers get provisioned. The shards are available for selection when the applications are getting deployedShards

2. Enterprise Architect creates an Application Stack which represents the collection of configuration details of all the micro services (Services). The Service itself would have been created by either by the EA or a team of app developers working on that particular micro service.  The service configuration can contain one or more software components called Packages, that defines it.  For example, a web service can have the packages of Apache Tomcat and Java run time.

3. DevOps will use the service configurations and the package definitions are snapshotted as a Docker Image which is stored in a Private Enterprise Registry. DevOps is also responsible for configuring the provisioning requirements for each of the service.  These requirements range from selecting the size of container (viz. XL, L, M, S) to the number of containers per service for scalability.
 

In the action with WordPress application

In this post we will see how to quickly setup deployment of a WordPress application and replicate them consistently with minimal effort and configuration.

Let’s start with some terminologies.

 

Application Environment

Any application can be deployed to one or more environments referred as Application Environment. These can be configured for different stages of application delivery e.g. staging, production etc.. or these can also be some other environment as customer dedicated environment etc..

appEnvs

 

Application Stack

Application Stack represents a reusable deployable application with all its services in a logical group. This can be deployed on more than one application environments expediting application delivery. Minimum configuration is required for deploying an existing Application Stack on different environments. An Application Stack may consist of multiple services.

 appStacks

  

Services / Images

A Service (Image) represents a micro-service in the deployment of an application. E.g. MySql , Apache2 can be 2 different services in an application stack.  A service is based on an Image which consists of multiple packages. Image actually maps to a DockerFile.  It requires may require some configuration variables which can be supplied when the Application Stack is configured in a new Application Environment.


Packages

A service consists of multiple packages. E.g. a Tomcat service will need Java and Tomcat packages. Other than that a package in WaveMaker Enterprise can also specify the configuration variables needed at runtime. The values of configuration variables can be provided when Application Stack is deployed on specific environment.

A Package can easily be configured with a few scripts in WaveMaker Enterprise.  Existing scripts can be used to create a package.


Base Images and Private Image Registry

A service (Image) can be created on the top of one of the base images. Base images are Docker images hosted in private image repository in an enterprise. A new base image can be downloaded from Docker repository, or can also be created and uploaded to private image registry.

 

Illustrative Example using WordPress Application

 

In this example we will take a simple case of deploying a WordPress application on WaveMaker Enterprise. We will simplify it to use only one service consisting of packages Apache2 with PHP, MySQL, and WordPress. You need to have WaveMaker enterprise installed and need to register as a valid user to it.

Let’s create the packages first.

 

MySQL Package

MySQLPkgDfn

Provide information including name of the package, version. Other than this vendor and OS which will run this package can be provided.

MySQLPkgInstall

You can specify the files needed for the installation, configuration and start of this package. These files can be the script files that you need to execute, of the other required files for the package. They will be uploaded to a directory with the name /wm/<packagename>, where packagename is the name of the package you specified in the previous step.

 

Other than this we need to provide the commands to add these packages. The following are the commands

Installation Commands [Executed during installation]

chmod 777 /tmp && apt-get -y install mysql-server-5.6 mysql-client-5.6

 

Configuration Commands [Executed during configuration, uses the value configured for configuration variables during Application Environment creation, e.g. MYSQL_ROOT_PASSWORD]


#Permit Root User to Login
sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnf
/usr/bin/mysqld_safe &
sleep 10
#change root password, the password value is taken from env property named MYSQL_ROOT_PASSWORD
mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION";
mysql -uroot -e "UPDATE mysql.user SET Password=PASSWORD('$MYSQL_ROOT_PASSWORD') WHERE User='root'";
mysql -uroot -e "FLUSH PRIVILEGES";


Startup Commands [Executed to start the package component. E.g. MySQL in this case.]

             /usr/bin/mysqld_safe &

MySQLPkgConfNStart

 

MySQLPkgConfigVarsNPorts

In this step you specify the ports that needs to be exposed for this service to be consumed. Also the configuration variables required by the package needs to be added in the Required field. E.g. MYSQL_ROOT_PASSWORD in the screenshot above.

Exposed configuration variables are those set by this package and can be consumed by other packages in the service. E.g. JAVA_HOME can be configured by installation of Java package and can be consumed by the dependent packages.

Apache2 with PHP

Installation Commands

# apache installation
apt-get -y install apache2 libapache2-mod-php5

#PHP installation
apt-get -y install php5-mysql pwgen php-apc php5-mcrypt

Configuration Commands


sed -i "s/KeepAliveTimeout 5/KeepAliveTimeout 300/g" /etc/apache2/apache2.conf

 

Start Commands


/usr/sbin/apache2ctl start

Specify port Http/80 and https/443 on the configuration page.

 

WordPress Package

Installation Commands

# Install WordPress
wget -O /tmp/wordpress.zip https://wordpress.org/latest.zip
cd            /var/www/html
unzip /tmp/wordpress.zip

 

Configuration Script

cd /var/www/html/wordpress
# db creation for wordpress requires env properties such as MYSQL_ROOT_PASSWORD, WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD
mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "create database wordpress";
mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "CREATE USER wordpress@localhost IDENTIFIED BY 'wordpress123';"
mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "GRANT ALL PRIVILEGES ON wordpress.* TO wordpress@localhost;"
mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "FLUSH PRIVILEGES;"
cp wp-config-sample.php wp-config.php
sed -i "s/database_name_here/wordpress/g" wp-config.php
sed -i "s/username_here/wordpress/g" wp-config.php
sed -i "s/password_here/wordpress123/g" wp-config.php
cd /var/www/html
chown -R www-data.www-data *
mkdir wordpress/wp-content/uploads

 

 

All Packages

AllReqdPacks

Now we need to create Service /Image with these packages.’

Let’s create image with name wordpress choosing base image of Ubuntu 14.04 and provide it a version 1.0.

Image1

 

Now add packages we created to this Image and order the packages in the right order by simple drag and drop. WordPress Package is kept in the end as it will depend on the other 2 packages.

 

Image21

 

ImageScript

You can see the DockerFile generated for the Image. Also other scripts involved can be looked at.

 

ImageLogs

You can see the logs of Docker Image build and push.

 

Service

After this we can configure a service from an Image providing the default values for the configuration properties. These properties can be modified later while configuring the environment.

 

Now let’s create a reusable Application Stack

AppStackCreate

You can create an Application Stack by selecting the services you need to add. We are adding WordPress Service we just created here.

 

Instantly provision Environment with the WordPress Application Stack

Env1

Provide a version, application stack, and shard to which we need to deploy WordPress application. As we saw earlier shards were configured by the IT Administrator for logical slicing of the enterprise cloud. Please select the default shard here.

 

Env2

Also we need to provide number of nodes and the strategy for balancing the load. I am choosing simple Round Robin strategy.  Container type will decide the size of resources available to WordPress application.

We can configure the server URI for application deployment.

Values of configuration variables can be modified here for environment specific values.

 

Ready with WordPress Application

Access the application on https://wordpress.demo.nwie.net/wordpress/index.php

Online

 

Summary

We saw in this blog, how simple it is to create a reusable application stack and deploy it in any environment with minimum configuration. This really provides great optimization and continuous deployment of enterprise applications saving long release cycles.  Please contact info@wavemaker.com for demonstration and more information.

Integrating third-party UI widgets into Studio using Prefabs

December 16, 2014
by Karthick Viswanathan

A common request among WaveMaker Studio developers is to integrate third-party UI widgets inside WaveMaker Studio and make them available as drag-and-drop  components.  This task becomes especially challenging when we consider the fact that the WaveMaker Studio uses AngularJS technology for defining its widgets and the third-party widget may be using another technology like jQuery.  In this blog post, we will take a use case-based approach to see how a jQuery-based third-party widget is integrated with WaveMaker Studio.  For achieving this, we will leverage Studio’s very own superstar component  – Prefab – and demonstrate its power of customization.

Use case

Lets take Lightbox image viewer widget and see how users can integrate this widget into WaveMaker Studio using Prefabs.   This widget is jQuery-based and this link gives the details about how to use the Lightbox widget in general.

Steps to integrate Lightbox widget into WaveMaker Studio

The detailed steps to create this Prefab, export it and use it any WaveMaker Studio project are given below.

1.  Get the widget library source code: Download the Lightbox resource files from here and unzip it into a folder

Lightbox Resource Filess

Fig-1: Lightbox Resource Files

2. Import the relevant js, css and image files into WaveMaker Studio.  In case of Lightbox widget, the details are given in the step-1 of “How to use” section in the Lightbox project home page.

ImportResource

Fig-2:Import Resource

The imported files can be seen under the folders js, css and image.

Imported Lightbox resource files

Fig-3: Imported Lightbox resource files

3. Set the Bindable Properties for the Prefab: Go to the newly introduced “Prefabs Properties” section under the project “Settings” and add references to the imported js under script section, css under the style section and an icon  file.  Add the bindable properties that are needed for this Prefab. In this example, we have added  “image” and “title” properties that represent the location and title of the image to be displayed.

Prefab Properties

Fig-4: Prefab Properties

These properties will appear in the properties panel of the Prefab, once it is drag and dropped into the WYSIWYG canvas.

Checkout the WaveMaker Prefabs documentation to get complete details about this new feature.

4. Design the Prefab UI: Drag and drop the “picture” widget to display the image thumbnail  and bind the “Hint” and “Source” attributes to the “title” and “image” properties respectively that you had defined in the previous step.

Design your prefab

Fig-5: Design your prefab

And finally, step-2 of “How to use” section of Lightbox documentation instructs the user to embed the images inside an anchor tag(<a>…</a>) & also add a “data-lightbox” attribute, to activate the widget.  In the Studio we can do this by adding the above details in the “Markup” section, as shown below.

ActivateLightbox

Fig-6: Activate Lightbox

5.  Export the Prefab using the Export menu item in Studio (see Fig-7).  Make sure you have tested the Prefab before you export it.

Export the prefab

Fig-7: Export the prefab

6. Import the Prefab and use it as any other component inside an app.  To demonstrate the Lightbox Prefab usage, lets  create a demo app called “ImageViewer” and import the Lightbox Prefab.  Once it is imported you can spot the LightboxPrefab in the Prefabs accordion section.

Lightbox prefab imported

Fig-8: Lightbox prefab imported

7. Perform the following customary steps in the Studio to integrate the LightboxPrefab:

a. Import the sample DB provided with WaveMaker Studio
b. Drag and drop a Live-List widget into the canvas and bind it to the dataset of “HRdbEmployeeData” live variable that got created automatically after import of sample DB.
c. Delete the  “panel1” created under the “listtemplate1”.
d. Drag and drop the lightbox prefab into the “listtemplate1” and bind the image “Source” property to “Variables.HrdbEmployeeData.dataSet.picurl” and the title to “Variables.HrdbEmployeeData.dataSet.firstName”

We are all set now.  Run the application and see how the Lightbox image viewer functionality executes successfully.

ImageViewer app execution

Fig-9: ImageViewer app execution

The above approach of using Prefabs can be applied successfully to integrate any third-party UI widgets into WaveMaker Studio instantly, providing the needed customization inside Studio.

Try it out with your widget of choice and let us know how it went.  Send your experience of integrating your custom widget to feedback@wavemaker.com.

References
Lightbox: http://lokeshdhakar.com/projects/lightbox2/

Karthick Viswanathan
Product & Customer-Success Manager