Auto Vaadin Add On Deployment

Introduction

In my last blog post, I closed with the following:

If you have the Vaadin 7 Control Panel installed and you've deployed the LazyPagedContainer Add On, you can download and deploy the vaadin-sample-portlet-1.0-SNAPSHOT.war file directly from this blog.

This is not completely correct.  The Vaadin 7 Control Panel includes functionality to deploy Vaadin Add Ons at deployment time.

Originally I added this feature to support deployment of Vaadin 7 portlets from the Liferay MarketPlace.  I want to be able to distribute Vaadin 7 plugins without giving the user a whole list of dependencies that have to be satisfied to use the plugin.  With this feature, deploying the plugin into the environment would also deploy the Add On, recompile the widgetset and the portlet would be ready to go.  The only requirement would be the Vaadin 7 Control Panel.

This feature has another use case that is valuable for enterprises - artifact deployment to multiple environments.

Imagine you're a developer and you've just completed development of your next enterprise Vaadin 7 portlet.  It works great in your local development environment, but to implementent all of the requirements you needed to use some additional Add Ons that are not currently in your environment, namely the Lazy Paged Container.

In your enterprise, you have a bunch of environments - testing environments, QA environments, production environment in a cluster...  Normally before your portlet could get deployed to those environments, you'd have to ensure the Add On was deployed, the widgetset compiled, etc., and then your portlet could be deployed.  Some of these environments you might have access to deploy the Add On to, but others may involve a separate Operations group that will look at pushing out the Add On as a deployment of it's own.

Well, the same feature to auto deploy Add Ons for MarketPlace plugins will also help in this environment.  Using the auto Add On deployment feature, you would augment your portlet to push the Lazy Paged Container during your portlet deployment - whatever your enterprise deployment process, the deployment of your Vaadin 7 portlet will deploy your Add On too.

In the remainder of this blog post we'll adapt the vaadin-sample-portlet project to handle the auto deploy of the Lazy Paged Container Add On.

Preparation

The Vaadin 7 Control Panel comes with a service jar that you will need in your project.  You should install the jar to your local Maven repository or deploy it to your local Nexus repository so it can be included in your project.  If you navigate to the vaadin7-control-panel-portlet/WEB-INF/lib directory on your app server, you'll find the vaadin7-control-panel-portlet-service-version.jar file (where version will be the version number for the service jar).

To install the jar to your local Maven repository, run the following command from this directory:

mvn install:install-file -Dfile=vaadin7-control-panel-portlet-service-version.jar \
  -Dgroupid=com.dnebinger.liferay -DartifactId=vaadin7-control-panel-portlet-service \
  -Dversion=version -Dpackaging=jar

Replace version with the version from the filename, note that there are two instances in the command line.

To deploy the jar to your local Nexus repo, your command line will be:

mvn deploy:deploy-file -Dfile=vaadin7-control-panel-portlet-service-version.jar \
  -Dgroupid=com.dnebinger.liferay -DartifactId=vaadin7-control-panel-portlet-service \
  -Dversion=version -Dpackaging=jar -Durl=http://user:pswd@nexus
Again the version number needs to be entered in the command line and the url should be changed to your local repository URL.
 

Project Changes

The first change will be in the pom.xml file.  We'll be adding a dependency on the service jar and removing the provided scope for the Lazy Paged Container artifact.

The new dependencies, based upon my local version, are:

<dependency>  <groupId>com.dnebinger.liferay</groupId>  <artifactId>vaadin7-control-panel-portlet-service</artifactId>  <version>1.0.1.0</version> </dependency> <dependency>  <groupId>org.vaadin.addons</groupId>  <artifactId>lazy-paged-container</artifactId>  <version>1.0.0</version> </dependency> 

Because we removed the provided scope from the pom.xml file, Maven will include the jar in the war's WEB-INF/lib directory.  Since the portal may not have the Add On jar (if it hasn't been deployed before), we will remove it as a portal dependency jar.  Also, since we're using the Vaadin 7 Control Panel service jar, we'll add it as a required deployment context so the portlet will not load unless the Vaadin 7 Control Panel is deployed and ready.  Below is the updated liferay-plugin-package.properties file:

name=vaadin-sample-portlet module-group-id=liferay module-incremental-version=1 tags= short-description= change-log= page-url=http://www.vaadinonliferay.com author=Vaadin On Liferay licenses=LGPL 
# First the vaadin jars, then spring jars. portal-dependency-jars=\  vaadin-server.jar,vaadin-shared.jar,guava-vaadin.jar,atmosphere-runtime-vaadin.jar,jsoup.jar,\  streamhtmlparser-jsilver-vaadin.jar,vaadin-slf4j-jdk14.jar,json-java.jar,\  commons-beanutils.jar,commons-collections.jar,commons-lang.jar,commons-io.jar,commons-pool.jar,commons-configuration.jar,commons-digester.jar,\  spring-core.jar,spring-asm.jar,spring-context.jar,spring-context-support.jar,spring-expression.jar,spring-transaction.jar,spring-web.jar,spring-aop.jar 
# We are dependent upon the Vaadin 7 Control Panel since we use the service jar. required-deployment-contexts=vaadin7-control-panel-portlet 

The next change is to add a startup action class extending one from the Vaadin 7 Control Panel service jar.  It's really a simple class, so it is below:

package com.dnebinger.liferay.vaadin.sample; 
import com.dnebinger.liferay.vaadin.startup.AbstractVaadinAddonDeployStartupAction; 
import java.util.ArrayList; import java.util.List; 
/**  * class LazyPagedContainerDeployStartupAction: A startup action class to deploy the Lazy Paged Container Vaadin Add On.  */ public class LazyPagedContainerDeployStartupAction extends AbstractVaadinAddonDeployStartupAction {  private static final String LPC_JAR = "LazyPagedContainer.jar"; 
 /**  * getAddonNames: Returns the names of all jars from the WEB-INF/vaadin/addons directory that should be deployed.  * @return List The list of jar filenames.  */  @Override  protected List<String> getAddonNames() {  List<String> names = new ArrayList<String>(1); 
 names.add(LPC_JAR); 
 return names;  } 
 /**  * getAddonVersion: Returns the encoded version for the Add On jar with the given name.  *  * Version is encoded without periods but complete enough so updates will be deployed correctly.  * For this example, Lazy Paged Container is verison 1.0.0 so the value we will return is 100. That way if a  * 1.1.0 or 1.0.1 or 2.0.0 version comes out, we can follow the version coding to get 110, 101, and 200 and  * trigger the update deployment.  *  * @param addonName Name of the Add On to get the version for.  * @return int The encoded version number.  */  @Override  protected int getAddonVersion(String addonName) {  // you should be returning a version number for every Add On that you're hoping to deploy.  if (LPC_JAR.equals(addonName)) {  return 100;  }   return 0;  } } 

When the startup action is invoked, the named Add On must be found in the portlet's WEB-INF/vaadin/addons directory and match the given name.  So create a WEB-INF/vaadin/addons directory and copy the Add On jar(s) to this directory.

The final change is to add the pieces so Liferay will handle our startup action.  We will do this by adding a hook to the portlet to add the portal properties for the startup action.

First we need to add the src/webapp/WEB-INF/liferay-hook.xml file:

<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd"> 
<hook>  <portal-properties>vaadin-sample-portlet-hook.properties</portal-properties> </hook>

We also need to create the src/resources/vaadin-sample-portlet-hook.properties file:

# # vaadin-sample-portlet-hook.properties - Properties for the hook to add the app startup action. # 
application.startup.events=com.dnebinger.liferay.vaadin.sample.LazyPagedContainerDeployStartupAction

That's it!

Conclusion

With these changes in place, when you build and deploy the portlet, when it is started in the application container the startup action will process the LazyPagedContainer.jar file.

If it has either not been deployed before or if the version is greater than the currently installed version (considered an Add On upgrade), the jar will be copied to the portal's WEB-INF/lib directory, it will be added as a selected Add On (will show as checked in the Vaadin 7 Control Panel), and the widgetset will be rebuilt including the jar.

If it has already been deployed or the version is less than or equal to the deployed version, nothing happens (since it's already included).

So this eliminates the prework involved with getting all of the required Add Ons out of the way so you're back to just deploying your snazzy new Vaadin 7 portlet.

0