Applying LAR and remote publishing capabilities on custom assets in Plugins

Liferay portal provides remote staging and publishing capability through which the users can select subsets of pages and data (both portal core assets and custom assets), and transfer them to the live site—that is, remote portal instance. Using this, we can export the selected data to the group of a remote portal instance or to another group in same portal instance.

The LAR exporting and importing features are used for remote staging and publishing. These features are implemented in the PortletDataHandler API. The intent of this API is to provide the portal core assets and custom assets with a useful API for importing and exporting application content to and from the portal in a database agnostic fashion. Abstracted from the book: Liferay Portal 5.2 Systems Development.

In addtion, the portal integrates workflow systems like jBPM or Kaleo on any assets, either core assets or custom assets; the portal provides a framework to add custom attributes or called custom fields to any Service-Builder generated entities at runtime, where indexed values, text boxes, and selection lists for input and dynamic UI are available; OpenSocial, Social Activity and Social Equity are available in Plugins; and CAPTCHA or reCAPTCHA would be available for custom assets; etc. As mentioned in following blogs posts, these features have been applied on custom assets in plugins.

When applying LAR and remote publishing capabilities on custom assets, following use cases come into picture.

  • Use case A: ability to archive custom assets, for example, Knowledge Base articles.
  • Use case B: ability to publish custom assets from staging to live remotely.

This article will address how to implement LAR and remote publishing capabilities on custom assets, for example knowledge base articles, in plugins. Of course, you can leverage the same mechanism to apply LAR and remote publishing capabilities on your own custom assets.

LAR – import and export

Data export and import generally revolve around the concept of storing data outside the portal permanently or temporarily. The portal does this by handling the creation and interpretation of the LAR files. The functions of data export and import are portlet-wise. Following screenshot shows capabilities to import and export Knowledge base articles.

Note that LAR is short for Liferay Archive. It includes all of the pages, their layouts, their configurations, their look and feel, their permissions, and so on. Importing a LAR file will overwrite any existing pages of a given group configured in the LAR file. And most importantly, target portal server, which is used to import LAR file, must have exactly same version as that of source portal server, which is used to export LAR file. That is, LAR should not be used for upgrade.

Custom Asset models – Knowledge Base

As shown in following figure, Knowledge Base articles are specified as entries: Article, Comment, and Template. The entry Article included columns: article Id as primary key, resource Prim Key, group Id, company Id, user Id, user Name, create Date, modified Date, parent resource Prim Key, version, title, content, description, priority, and so on; the entry Template included columns: template Id as primary key, group Id, company Id, user Id, user Name, create Date, modified Date, title, content, description and so on; while the entity Comment included columns: comment Id as primary key, group Id, company Id, user Id, user Name, create Date, modified Date, class Name Id, class PK, content, helpful, and more. As you can see, the entity Comment could be applied on either any core assets or custom assets like Article and Template by using class Name Id and class PK.Sure, you can find details in $PLUGIN_SDK_HOME/knowledge-base-portlet/docroot/WEB-INF/service.xml

Abstracted from the book: Liferay User Interface Development

When exporting / importing custom assets like knowledge base articles, first above models and their versions should be in picture. And moreover, following associations should be taken into account.

  • Attachments (as documents)
  • Documents (as links)
  • Images (if any)
  • Polls (if any)
  • Asset ratings
  • Asset view counts
  • Asset comments and votes on comments
  • Subscriptions
  • Addresses (if any)
  • Asset tags
  • Asset categories
  • Custom fields
  • Locks
  • Permissions

Solution Overview

Following diagram shows what’s happening to remote publish on custom assets.  Supposed that there is one staging server – one Liferay installation for internal users to build and review web content, and there is one remote live server - one Liferay installation for external users to view web content. Of course, you can have more than one live servers clustered.

By the way, the portal provides capabilities to have local staging and local live, that is, the live group and the staging group exist in the same portal instance. How does it work? You can refer to the book: Liferay Portal 5.2 Systems Development.

In general, there are three-step processes to remote publish assets, both core assets and custom assets.

  • Export assets – both core assets and custom assets – as internal LAR in staging server
  • Push exported LAR from Staging to Remote Live server through tunnel-web, both staging server and remote live server
  • Import assets - both core assets and custom assets – as internal LAR in remote live server;

Protecting tunnel servlet

Of course, you need to protect tunnel servlet.  In order to communicate with the remote server and, moreover, protect HTTP connection, we need to set up a tunnel web in portal-ext.properties. That is, add the following lines at the end of portal-ext.properties:

tunnel.servlet.hosts.allowed=127.0.0.1,69.198.171.104,69.198.171.105,64.71.191.145,SERVER_IP
tunnel.servlet.https.required=false

The preceding code shows a tunnel.servlet.hosts.allowed property with a list of allowed hosts, for example, 69.198.171.104, 69.198.171.105, and 64.71.191.145 – IPs of staging server and remote live servers, replacing them with IPs of your own servers. As stated above, we used these hosts as examples only. You can have your own real hosts. Meanwhile, it specifies the tunnel.servlet.https.required property. By default, it is set as a false value. You can set it as a true value if you want to use HTTPS.

Capabilities

Note that remote publishing function should be used to push content only – both staging server and remote servers must have exactly same version. That is, remote publishing feature should not be used for upgrade.

How to Implement LAR?

In following three steps, you should be able to implement LAR to archive knowledge base articles.

  • Add portlet-data-handler in $PLUGIN_SDK_HOME/knowledge-base-portlet/docroot/WEB-INF/liferay-portlet.xml like

<portlet-data-handler-class>com.liferay.knowledgebase.admin.lar.AdminPortletDataHandlerImpl</portlet-data-handler-class>

  • Extend com.liferay.portal.kernel.lar.BasePortletDataHandler as com.liferay.knowledgebase.admin.lar.AdminPortletDataHandlerImpl.

Note that com.liferay.portal.kernel.lar.BasePortletDataHandler implements com.liferay.portal.kernel.lar.PortletDataHandler. Thus we can say, com.liferay.knowledgebase.admin.lar.AdminPortletDataHandlerImpl implements com.liferay.portal.kernel.lar.PortletDataHandler.

com.liferay.portal.kernel.lar.PortletDataHandler has following interface.

public interface PortletDataHandler {
public PortletPreferences deleteData(PortletDataContext portletDataContext, String portletId, PortletPreferences portletPreferences) throws PortletDataException;
public String exportData(PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences) throws PortletDataException;
public PortletDataHandlerControl[] getExportControls() throws PortletDataException;
public PortletDataHandlerControl[] getImportControls() throws PortletDataException;
public PortletPreferences importData(PortletDataContext portletDataContext, String portletId, PortletPreferences portletPreferences, String data) throws PortletDataException;
public boolean isAlwaysExportable();
public boolean isPublishToLiveByDefault();
}

com.liferay.portal.kernel.lar.BasePortletDataHandler has following interfaces:
public PortletPreferences deleteData(
 PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences)
public String exportData(
 PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences)
public PortletDataHandlerControl[] getExportControls()
public PortletDataHandlerControl[] getImportControls()
public boolean isAlwaysExportable()
public boolean isPublishToLiveByDefault()
public PortletPreferences importData(
 PortletDataContext portletDataContext, String portletId,
 PortletPreferences portletPreferences, String data)

protected PortletPreferences doDeleteData(
 PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences)
protected String doExportData(
 PortletDataContext portletDataContext, String portletId, PortletPreferences portletPreferences)
protected PortletPreferences doImportData(
 PortletDataContext portletDataContext, String portletId,PortletPreferences portletPreferences, String data)

  • Implement methods doDeleteData(), doExportData() and doImportData() in com.liferay.knowledgebase.admin.lar.AdminPortletDataHandlerImpl.

In method doDeleteData(), remove articles, comments and templates  by group.

in methods doExportData() and doImportData(), export / import following items:

custom assets: Articles, Comments, Templates

custom assets’ associations: attachments (as documents), images (if any), polls (if any), asset rating, asset view counts, asset comments and votes on comments, subscriptions, address (if any), asset tags, asset categories, custom fields, permissions, etc.

That's it. This is useful, isn’t it?

Summary

In brief, import/export and remote publishing features are available for custom assets in plugins. You can use import/export feature to archive your custom assets (Use case A), and remote publishing feature to push custom assets from staging server to remote live servers with one simple click (Use case B). Especially, you can schedule remote publish processes as well. Let’s address scheduling feature later.

By the way, you can have a closer look at the knowledge base source code (revision 69840) with LAR and remote publishing features in

knowledge-base-portlet-6.1.0.1.war

Last but not least, I'd like to send a ton of thanks to Liferay development team and Liferay community, who made a lot of good stuff.

Blogs
Hi Jonas,
Good blogs.
As you have stated that we can use kaleo or jBPM with any core as well as custom asset, can you provide some link to convert a custom asset to workflow enabled one using kaleo in LR -6. I tried it and can see my portlet under workflow Configuration screen but don't know what changes should I made in my view.jsp for enabling complete workflow. I followed your blog http://www.liferay.com/web/jonas.yuan/blog/-/blogs/how-to-add-workflow-capabilities-on-knowledge-base-articles-or-any-custom-assets
Its very good but I am not able to understand what changes should I make in my portlet's view.jsp page to show the submit for publish button with its action same as which knowledge-base portlet uses. I am newbie in LR. I tried knowledge-base portlet but its code is very complex. So can you please help me by giving some link or steps for converting a jsp plugin portlet to workflow enabled portlet using kaleo-web in LR 6.
Thanks in advance.
Hi Roshan, thanks.

You can refer to knowledge-base-portlet-6.1.0.1.war (see above download link), where workflow capabilities are available as well.
Thanks for your reply. I referred the same knowledge-base-portlet and now can see my own portlet on Workflow Configuration screen in control panel. But can not understand what exactly to do in jsp page in my portlet to call this work flow. I have plugin portlet with fields firstName, lastName, leaveDate and a submit button. This leave should be approved by the manager. Can you please guide me how to write jsp for this. I have made all the things workflow handler, impls and definition files except jsp for workflow.
Thanks in advance.
Hi Roshan, You can use KB as a example, and try to modify JSPs in your local host. You will see the beauty of Liferay.

Hope that it helps,

Thanks

Jonas
Hi Jonas Yuan,
Thanks for this useful content.

I am new to liferay world. I have a problem in exporting data to lar file.
Issue is I have a custom portlet, to export its data in lar file i used custom portlet data handler. i am able to export its data successfully. I imported this lar file in other database. Data inserted properly in new database as well . Now if try to update entry of custom portlet it is showing exception as its related workflow is not exported.
Jonas, can u please point me a sample example where i can export data as well as kaleo workflow data in one lar file.

Thanks