- Andrew Kos
- Bill Burlein
- Bryan Williams
- Christian Vozar
- Jeff Brown
- John Kraus
- Joseph Mak
- Josh Durbin
- Mark Daugherty
- Matt Van Bergen
- Melissa Geoffrion
- Michael Kang
- Michael Chan
- Michael Hodgdon
- Mike Motherway
- Molly McDaniel
- Nadia Maciulis
- Pat McLoughlin
- Paul Michelotti
- Puru Hemnani
- Rohit Srinath
- Ryan Lunka
- Tom Kelly
Alfresco Integration with JBoss Portal
Wednesday, April 8, 2009
A common use case we see is clients wishing to integrate Alfresco ECM with or within their existing portal products. In the past, the most common way to do this was to place the entire Alfresco WAR within a portal container and deploy the product as a portlet. Although this approach works, it is not useful in many cases as you are limited in the customization of the look and feel with the rest of the portal. Plus, the repository itself is now tied directly to the portal container in terms of scalability.
With the release of Alfresco v3.x a few months ago, the options for integrating with a portal or other custom web application have greatly increased. I will discuss a few of the approaches that are now available as well as my thoughts on the benefits and drawbacks of each. To be sure we are on the same page, I am using Alfresco 3.0.1 Enterprise Edition and JBoss Enterprise Portal Platform 4.3.
1. Alfresco Presentation Web Script and JSR-168 Portlet
With this approach, you call an Alfresco “web script” from within a portlet. The web script is hosted in Alfresco’s repository, which can be local / remote from portal container. Before I go any further, a quick summary on web scripts:
A web script is Alfresco’s terminology for what is basically a RESTful request to the repository over HTTP. A web script can return XML, HTML, JSON, etc. Alfresco comes with some web scripts out of the box and as of v3.0, that number has greatly increased. Alfresco refers to a web script that returns HTML as a”presentation web script” and if it returns raw data in XML or some other format, it is a “Data Web Script”. More on web scripts. You can also write your own web scripts as needed.
In my example, I called a provided web script that returned HTML and displayed the HTML in the portlet. Here is the gist of the code needed:
And here is a screen shot of the resulting portlet running:
- Easy with quickly had something to show. I had this running with something to show in less than 20 minutes.
- Portal developer has almost no control over the look-feel. Of course the web script can be customized, but that work must be done in the Alfresco environment, not the portal. This can be a pro or a con depending upon your work environment and preference for portlet development tooling. Do you want to use JSP or some of the web frameworks that are standard across portals or do you want to use Alfresco’s approach and create presentation web scripts with FreeMarker?
- The paging and links do not stay within the portlet. This is because the HTML is generated outside of the portlet rendering life-cycle. I am not sure if this could be routed through some sort of portlet-bridge to make it part of the life-cycle. I did not spend much time investigating beyond the JSR-168 portlet proxy class Alfresco provides (see mention of this in my Summary below).
2. Alfresco Data Web Script and JSR-168 Portlet
Like the approach above, this option also calls a web script from a portlet. The web script can be hosted on a local or remote Alfresco instance. In this case, the web script returns some format such as XML or RSS. The portlet developer is then responsible for formatting the data as desired within the portlet itself.
- Data can be formatted as desired and even placed in some sort of web framework used to produce the other portlets – IE: Grails, Seam, Struts, plain JSP, etc.
- Loose coupling between portal and Alfresco. No Alfresco code has to be deployed to the portal, which I see as a good thing.
- Need to code custom parsing of web script responses in portlet. Because there is no standardization in web scripts, the author can form the XML in any manner. That means, the portlet developer may have to write custom parsing logic for each web script they call. This is probably controllable in most environments, so not a huge deal and something to be aware of.
- I like this approach better than #1 for sure, but things can get better.
3. CMIS & Seam Portlet
The direct web script access as described in options #1 or #2 both also have a potential drawback in that they are both proprietary to Alfresco. If you ever switch or add an additional content management system to the mix, you would be starting from scratch.
However, the very good news is that Alfresco v3.0 introduced one of the first CMIS implementations and I see it is now available as a technology preview in Alfresco v3.1. Content Management Interoperability Services (CMIS) is a specification developed by EMC, IBM, Microsoft, and a few other vendors including Alfresco. The purpose of CMIS is to allow developers to use a common API to access any content management system that offers as CMIS implementation. This is a bit like using SQL to access any relational database – really a no-brainer I think.
Alfresco implements their CMIS API on top of both web scripts, which we discussed above, and SOAP web services. So, you have a choice to use CMIS via RESTful or SOAP web services. Per the specification, the RESTful binding uses the ATOM Publishing Protocol. For my purposes, I chose to use the REST/ATOM binding.
I mentioned that Alfresco based their CMIS REST binding on top of their web scripts platform. However, unless you look under the covers, you really don’t know or care that this is the case. As a client, you deal only with the CMIS API. This means your client portlet code is not tied to Alfresco. It will work with any system that provides a CMIS implementation. Further, using CMIS means your XML parsing can be standardized and re-usable since it must follow the ATOM protocol. You are no longer tied to parsing whatever XML the web script author decided to deliver.
In my example, I decided to use a Seam application to act as the Alfresco client using the CMIS REST/ATOM binding. I then exposed the Seam application as a portlet within the JBoss Portal. I chose Seam because I knew I was going to need the paging, caching, and session management it provides and I did not want to write or worry about all that – I had my hands full coming up to speed first on the CMIS specification and then on the ATOM/APP protocol. I used JBoss Enterprise Portal Platform 4.3 which contains a tech preview the required JSR-301 portlet bridge to expose the Seam application as a portlet. This should also work in the latest JBoss Community portal or as a standalone web application running in JBoss, Tomcat, or any of the other major app vendors.
For the Seam portlet application, I used Java and Apache Abdera to assist with the binding/parsing of the ATOM XML. If I had to do it again, I would maybe look to using Groovy inside the Seam application instead of Java. For the simple reason that I was mainly dealing with XML parsing, which I think Groovy excels at.
Here are a couple screen shots showing the portlet. I basically took the same approach (read: blatantly copied) that my co-worker Shane Johnson took with his CMIS Explorer project. To date, I have only implemented the getRepository(), getTypes(), and the 1st level on the getChildren() CMIS operations. However, that was enough for a POC and also proved to me that this was the approach to take.
Note in the screen shots I have paging and sorting. These were some of the things I wanted to get from using Seam instead of writing myself. I also cached the repo and type data in Seam’s Session context since that is very static data. Right now I have the actual browser tab data in Seam’s conversational session, but I may take that out and not cache the children info at all so it remains 100% real-time.
- I like this approach because it can work against any content management system that has a CMIS implementation, not just Alfresco. This is a big deal, because many of our clients have a mix of CMS systems in their enterprise. With this approach, the same portlet can access them all with the same code base.
- You will need to become familar with CMIS, ATOM/APP, and then Abdera if you choose to use it.
- This is new technology so that introduces some risk. CMIS is only at 0.5 version and will probably change a bit. It is also not supported by Alfresco as part of the enterprise edition and only provided as a preview. Note that the Seam approach I took is supported by RedHat as part of their Tech Preview, but does not have an SLA attached.
- CMIS is only intended to cover the common CMS use cases. You may need to do things that are not covered or not yet covered by CMIS. In that case, I would use direct data web script access and write them to return the ATOM protocol. This way your approach remains as close as possible to the CMIS-covered use cases.
- In my opinion, the benefits of having a solution that can cross CMS vendors outweighs the risks of adopting a new technology.
4. Other Options
Even though I would recommend #3 above, there are other options for portal integration that I will mention:
- With Alfresco 3.x, they WebScript framework was split from the UI code. So, it is possible to host just the webscripts code inside the portal and access web scripts using Alfresco’s JSR-168 proxy portlet as described here. I am not crazy about this approach because you still end up putting quite a bit of Alfresco code into your portlet and what you need exactly is not documented from what I could find. I started down this path and added the Webscript framework.jar and then started adding missing Spring JARs, etc on a trial and error basis, until I finally gave up. Alfresco makes a point that they split this out to allow WebScript Runtimes, yet they do not document what is required for actual client deployment? Maybe I am just missing something obvious so if anyone knows where this is documented, let me know.
- You could stick with the “old” approach of deploying the entire Alfresco WAR as a portlet. This may make sense if you truly need to reproduce the Alfresco Explorer web app inside your portal.
The CMIS approach outlined in #3 is by far my favorite. If you or the organization is not comfortable using that new technology, then #2 will certainly work. For #2, you can access most of the data web scripts Alfresco provides OOB with the ATOM format, so you can still standardize your client code as long as you can control that format is also used for any custom web scripts you may need.
I hope to get a chance to complete a few of the other CMIS operations for the Seam portlet. If I do, I will post an update here.
Thanks to my colleagues Shane Johnson and Sten Anderson for putting up with my barrage of CMIS-related questions. I would recommend you take a look at some of the leading work they have done with CMIS.
For more than 19 years, Jeff has been developing well-designed, high-quality software products to meet business needs across many sectors, including: retail, government, insurance, education, and manufacturing. He has expertise in distributed messaging systems, service-oriented architecture design and implementation, and most recently has worked extensively with content management systems.
- Descriptive JMX Beans in AEM/CQ
- Invisible requirements within Business requirements
- Building a better Options Predicate
- Extensionless URLs with Adobe Experience Manager
- The Life of a Tester in Adobe CQ World!
- Limitations of the CQ Parsys Model and the Implementation of a Nested Paragraph System
- Using Apache FOP to generate a PDF document based on a form submission data
- Configuring SAML in AEM 5.6