Integrating Alfresco through CMIS in Liferay

 In brief, you could integrate Alfresco in the portal in following approaches.

·         Web services, referring to the portlet Alfresco Content;

·         RESTful services  - OpenSearch, referring to the portlet Alfresco Content;

·         RESTful services - web scripts, using alfresco as direct repository of Liferay, referring to chapter 6 Customizing the WYSIWYG Editor of the book Liferay Portal 5.2 Systems Development;

·         CMIS – using CMIS document library hook;

·         Portlets – using alfresco web client as a set of portlets. Refer to integrating-alfresco-web-client-as-a-set-of-portlets-with-liferay

Abstracted from the book: Liferay Portal 6 Enterprise Intranets

This article will introduce how to integrate Alfresco through CMIS in Liferay.  

 

Introduction

 

Content Management Interoperability Services (CMIS) - a standards proposal consisting of a set of Web services for sharing information among disparate content repositories that seeks to ensure interoperability for people and applications using multiple content repositories. Alfresco, Day Software, Dennis Hamilton, EMC, FatWire, IBM, Microsoft, Open Text, Oracle and SAP have joined forces to propose CMIS.

From 6.0, Liferay provides CMIS hook to support CMIS (version 1.0). Refer to CMIS and Database Migration.

How to achieve it?

In five steps, you should be able to integrate Alfresco through CMIS.

  • Install Liferay portal 6.0 or above at $LIFERAY_HOME; here we use Liferay-Tomcat bundle $TOMCAT_AS_DIR; and $PORTAL_ROOT_HOME = $TOMCAT_AS_DIR/webapps/ROOT;
  •  Drop ${alfresco.war} and ${shared.war} to $TOMCAT_AS_DIR/webapps;
  • Create a database alfresco in MySQL.

drop database if exists alfresco;

create database alfresco character set utf8;

grant all on alfresco.* to 'alfresco'@'localhost' identified by 'alfresco' with grant option;

grant all on alfresco.* to 'alfresco'@'localhost.localdomain' identified by 'alfresco' with grant option;  

  • Create a file named portal-ext.properties at $PORTAL_ROOT_HOME/WEB-INF/classes and add following lines in portal-ext.properties.

dl.hook.impl=com.liferay.documentlibrary.util.CMISHook

cmis.credentials.username=admin

cmis.credentials.password=admin

cmis.repository.url=http://localhost:8080/alfresco/service/api/cmis

cmis.repository.version=1.0

cmis.system.root.dir=Liferay Home

That's it. You can start the portal now.

 

After integration

 

Going to Content->Document Library, create a folder "Liferay Home" and upload a document under this folder.

 Logging in Alfresco as "admin/admin", you would find the folder "Liferay Home" and the document.

 

Summary

 

CMIS allows for different CMS systems to interchange information. It is basically JSR-170 with two differences: not Java-specific and document-management-centric. This article showed an example to integrate Alfresco through CMIS. In fact, using CMIS hook we could integrate any CMS systems like Day Software, Dennis Hamilton, EMC, FatWire, IBM, Microsoft, Open Text, Oracle and SAP. 

Last but not least, I'd like to send special thanks to Alexander Chow who did an amazing job to make CMIS hook a reality. Also to everyone else that helped during development and providing feedback. 

Blogs
Very nice synopsis! Better than my one paragraph. emoticon

Also, thanks for helping to test it!
I tried this an received issues trying to run this example with regards to the deployment of Alfresco. Can I run this example against a pre-existing install of Liferay and a new Alfresco/Share war?

I was getting issues with Alfresco and the database as well as having to select default information for Hibernate.

Is there files that need to be changed for a mysql url that is not local to the box I am doing my Liferay/Alfresco install?

Thanks...jay
Hi Jay, thank you. CMIS integration is available for Liferay portal 6 only. Hope that it helps.
I'm getting following error when following these instructions with preview release. Any advise?:

16:25:29,329 ERROR [CMISHook:61] java.lang.NullPointerException
java.lang.NullPointerException
at com.liferay.portal.cmis.CMISUtil._verifyRepository(CMISUtil.java:403)

at com.liferay.portal.cmis.CMISUtil.verifyRepository(CMISUtil.java:146)
at com.liferay.documentlibrary.util.CMISHook.<init>(CMISHook.java:54)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
It seems that CMIS of ALfresco integration is not set properly. Do you follow above steps? Which Alfresco version are you using?
liferay-portal-tomcat-6.0.0.zip
Liferay 6.0 (Preview Release)

alfresco.war and share.war downloaded from http://liferay.cignex.com/palm_tree/book/0387/chapter12/cmis/ as indicated above

portal-ext.properties in liferay-portal-6.0.0\tomcat-6.0.24\webapps\ROOT\WEB-INF\classes\ with following contents (liferay and tomcat are running on port 8083):

dl.hook.impl=com.liferay.documentlibrary.util.CMISHook
cmis.credentials.username=admin
cmis.credentials.password=admin
cmis.repository.url=http://localhost:8083/alfresco/service/api/cmis
cmis.repository.version=1.0
cmis.system.root.dir=Liferay Home
Perhaps something was neglected about how you create Liferay Home on the alfresco repository in a way that it's accessible from http://localhost:8083/alfresco/service/api/cmis

Currently that url only lists following:

<?xml version="1.0" encoding="utf-8"?>
<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200901" xmlns:alf="http://www.alfresco.org">
<workspace cmis:repositoryRelationship="self">
<atom:title>Main Repository</atom:title>

<cmis:repositoryInfo>
<cmis:repositoryId>5902e906-4be2-4653-adab-0a377bc94225</cmis:repositoryId>
<cmis:repositoryName>Main Repository</cmis:repositoryName>
<cmis:repositoryRelationship>self</cmis:repositoryRelationship>
<cmis:repositoryDescription></cmis:repositoryDescription>
<cmis:vendorName>Alfresco</cmis:vendorName>
<cmis:productName>Alfresco Repository (Enterprise)</cmis:productName>
<cmis:productVersion>3.2.0 (304)</cmis:productVersion>
<cmis:rootFolderId>http://localhost:8083/alfresco/service/api/path/workspace/SpacesStore/Company%20Home</cmis:rootFolderId>
<cmis:capabilities>
<cmis:capabilityMultifiling>true</cmis:capabilityMultifiling>
<cmis:capabilityUnfiling>false</cmis:capabilityUnfiling>
<cmis:capabilityVersionSpecificFiling>false</cmis:capabilityVersionSpecificFiling>
<cmis:capabilityPWCUpdateable>true</cmis:capabilityPWCUpdateable>
<cmis:capabilityPWCSearchable>true</cmis:capabilityPWCSearchable>
<cmis:capabilityAllVersionsSearchable>false</cmis:capabilityAllVersionsSearchable>
<cmis:capabilityQuery>bothcombined</cmis:capabilityQuery>
<cmis:capabilityJoin>none</cmis:capabilityJoin>
<cmis:capabilityChanges>none</cmis:capabilityChanges>
<cmis:changesIncomplete>false</cmis:changesIncomplete>
<cmis:capabilityACL>none</cmis:capabilityACL>
</cmis:capabilities>
<cmis:cmisVersionSupported>0.61</cmis:cmisVersionSupported>
<cmis:repositorySpecificInformation></cmis:repositorySpecificInformation>
</cmis:repositoryInfo>

<collection href="http://localhost:8083/alfresco/service/api/path/workspace/SpacesStore/Company%20Home/children" cmis:collectionType="rootchildren">
<atom:title>root collection</atom:title>
</collection>
<collection href="http://localhost:8083/alfresco/service/api/path/workspace/SpacesStore/Company%20Home/descendants" cmis:collectionType="rootdescendants">
<atom:title>root collection</atom:title>
</collection>
<collection href="http://localhost:8083/alfresco/service/api/checkedout" cmis:collectionType="checkedout">
<atom:title>checkedout collection</atom:title>
<accept>application/atom+xml;type=entry</accept>
</collection>
<collection href="http://localhost:8083/alfresco/service/api/unfiled" cmis:collectionType="unfiled">
<atom:title>unfiled collection</atom:title>
<accept>application/atom+xml;type=entry</accept>
</collection>
<collection href="http://localhost:8083/alfresco/service/api/types" cmis:collectionType="typeschildren">
<atom:title>type collection</atom:title>
</collection>
<collection href="http://localhost:8083/alfresco/service/api/types" cmis:collectionType="typesdescendants">
<atom:title>type collection</atom:title>
</collection>
<collection href="http://localhost:8083/alfresco/service/api/query" cmis:collectionType="query">
<atom:title>query collection</atom:title>
<accept>application/cmisquery+xml</accept>
</collection>

</workspace>
</service>
I think issue has to do with

<cmis:cmisVersionSupported>0.61</cmis:cmisVersionSupported>

instructions above reference 1.0 in hook

however when i change it to 1.0 I get a different error:

20:57:29,377 ERROR [CMISHook:61] java.lang.IllegalArgumentException: local part
cannot be "null" when creating a QName
java.lang.IllegalArgumentException: local part cannot be "null" when creating a
QName
at javax.xml.namespace.QName.<init>(QName.java:214)
at javax.xml.namespace.QName.<init>(QName.java:261)
at org.apache.abdera.parser.stax.FOMElement.getAttributeValue(FOMElement
.java:423)
at com.liferay.portal.cmis.model.CMISObject.getPropertyValue(CMISObject.
java:246)
at com.liferay.portal.cmis.model.CMISObject.getBaseType(CMISObject.java:
52)
at com.liferay.portal.cmis.CMISUtil._getEntry(CMISUtil.java:314)
at com.liferay.portal.cmis.CMISUtil._verifyRepository(CMISUtil.java:422)

at com.liferay.portal.cmis.CMISUtil.verifyRepository(CMISUtil.java:146)
at com.liferay.documentlibrary.util.CMISHook.<init>(CMISHook.java:54)
Here's what i've tried with no success yet..
1) Followed above instructions.
2) If I leave cmis version at 1.0 I get first exception.
3) If I change cmis version to 0.61 sevencogs hook reports error on startup but it reports:
[CMISHook:57] CMIS Service is running version 0.61
But everything works same as 5,6,7,8
4) If I don't apply cmis config info to portal-ext.properties and start up system first without cmis then after shutting down and starting up with cmis config then I don't get any error.
5) If after 3 or 4 I a) create "Liferay Home" I don't see the Liferay Home directory
6) If I try to delete file then from liferay I get: INFO [CMISHook:57] CMIS Service is running version 0.61
on console and Liferay home shows up in alfresco
7) if I then recreate "Liferay Home" that works on liferay but if I try to delete it again I get second exception
8) If I try to create file in Liferay Home it doesn't show up in Alfresco and I can't then delete that file either
After a little more struggle I gave up with following instructions and tried to use http://process.alfresco.com/ccdl/?file=release/community/build-2440/alfresco-community-war-3.2r2.zip instead and this worked...

r2 supports 1.0 of cmis spec!!!

However now it works I don't quite see the point.. Although it's cool what's happening I don't see how in real life this integration would be used because of following:

When you add a file in liferay the file does end up in alfresco but with a filename corresponding to the version.

It doesn't appear to be an alfresco version since if you update it another separate file is created in alfresco.

If you want to use alfresco as the document management system i suspect you would want to do some document management there too.. So

1) on alfresco you would want to know the file name and view the versioning history from a single file perspective.
2) You might want to run wcm workflows to modify and maintain the files
3) Currently when I create a file in Liferay Home on alfresco it doesn't show up as a document in that directory on Liferay so it's not bi directional.
4) All it currently appears to be is a storage mechanism for liferay so data is saved external to liferays own db.

As such the feature leaves a lot to be desired although however a good proof of concept.. Of course perhaps i'm missing something.
Hi Garpinc, congratulation! You did get it working. I will update this blogs with Alfresco E 3.2 RC2 shortly.
@ K Boyce: Hi, thanks for helping me notice I wasn't using r2 emoticon, I was wondering if you tried to attach files from wiki or blogs

I'm getting an error that says im trying to create a file e.g wiki/1234 as file name, like it can't tell it is a folder

And ye, your suggestions would be nice, I think if there would be a way to use more friendly names when saving files, that would be a great advance
hi,

TY for posting this! got it with the alfresco-community-war-3.2r2 solution from k.boyce working. even got the same things to criticize: files not named correctly in alfresco, folders are strange..
but i think it's on a good way. best solution yet i think

The only feature from alf i miss in the new LR 6 is to make rules on content e.g. to place it in specific folders. Is there something on the way?

every time i tryed to upload s.th. in document library i got following exeption:
------------------------------------------------------------
16:05:30,155 ERROR [jsp:157] com.liferay.portal.security.auth.PrincipalException: /de/alf?p_auth=p6T8PMsu&p_p_id=20&p_p_lifecycle=1
&p_p_state=pop_up&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=3&doAsUserId=fcnH1YVcI7g%3D&_20_struts_action=%2Fdocument_library
%2Fedit_file_entry&_20_cmd=add&_20_newFolderId=0&_20_communityPermissions=ADD_DISCUSSION&_20_communityPermissions=VIEW&_20_inputPer
missionsViewRole=Community%20Member
at com.liferay.portal.struts.PortletRequestProcessor.process(PortletRequestProcessor.java:166)
at com.liferay.portlet.StrutsPortlet.processAction(StrutsPortlet.java:188)
at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:72)
at com.liferay.portal.kernel.portlet.PortletFilterUtil.doFilter(PortletFilterUtil.java:50)
at com.liferay.portlet.InvokerPortletImpl.invoke(InvokerPortletImpl.java:639)
at com.liferay.portlet.InvokerPortletImpl.invokeAction(InvokerPortletImpl.java:672)
at com.liferay.portlet.InvokerPortletImpl.processAction(InvokerPortletImpl.java:361)
at com.liferay.portal.action.LayoutAction.processPortletRequest(LayoutAction.java:738)
at com.liferay.portal.action.LayoutAction.processLayout(LayoutAction.java:548)
at com.liferay.portal.action.LayoutAction.execute(LayoutAction.java:217)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
at com.liferay.portal.struts.PortalRequestProcessor.process(PortalRequestProcessor.java:152)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at com.liferay.portal.servlet.MainServlet.callParentService(MainServlet.java:625)
at com.liferay.portal.servlet.MainServlet.service(MainServlet.java:602)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
------------------------------------------------------------
i don't know what i've changed. now it works

THX

Liferay 6.0.1 RC
Tomcat 6.0.26
MySQL-Client-Version: 5.0.51 Server Version: 5.0.51
alfresco-community-war-3.2r2
jdk1.6.0_20
Nice, it works for you. Thank you, Thomas.
Very nice to see that integration with alfresco is getting in shape. The issues that K Boyce reported (non-versioning and non-bidirectionality from alfresco -> liferay) could presumably be related to using 3.2 instead of 3.3. It would be nice to know if anyone tries it with the latest community alfresco release

cheers and keep up this great work
Hi Charles, Thanks. Hope that your question would get answered in new blogs:

http://www.liferay.com/web/jonas.yuan/blog/-/blogs/alfresco-3-3-delivers-cmis-support-integration-with-liferay-6.
[...] Liferay Portal using Alfresco documents accessed using CMIS: http://www.liferay.com/web/jonas.yuan/blog/-/blogs/integrating-alfresco-through-cmis-in-liferay [...] Read More
Hi ,

Trying to integrate Liferay 6.2 with Alfresco 4.2...Can someone help.?
Hey Jonas,

I'm trying to integrate Alfresco using the WAR method above. Is it possible to copy the alfresco.war and share.war files from the Community Edition of Alfresco or are the Enterprise editions required?

From this site it seems Enterprise is required but wanted to see if anyone has done it through community edition.
http://docs.alfresco.com/4.0/tasks/dlp-install-config.html

Thanks,