A new home for the Alfresco OpenCMIS Extension

The Alfresco OpenCMIS Extension is an addition to Apache Chemistry OpenCMIS. It provides read and write access to Alfresco aspects and aspect properties via CMIS.

We released a preview version about two month ago on Alfrescos public CMIS server. Today this project moved into its permanent home on Apache Extras: http://apache-extras.org/p/alfresco-opencmis-extension

From now on we will maintain the extension code there. Apache Extras is hosted by Google Code Project Hosting and we are using its code management system, bug tracking, Wiki and mailing lists.

There hasn’t been any code change compared to last preview release, but we have changed the license from LGPL to the Apache license 2.0. We will release new versions in irregular intervals – after we have fixed bugs or added new features. If you want to stay up-to-date, subscribe to the project mailing list.

Alfresco OpenCMIS Extension

About a week ago we made the “Alfresco OpenCMIS Extension” available for download. This extension provides easy read and write access to aspects and aspect properties through OpenCMIS. We are still testing and improving it but the feedback we received so far is very positive.

More information and the download package can be found here: http://cmis.alfresco.com:8080/alfresco-opencmis-extension.html

Spring Surf and OpenCMIS Integration Part 2

Back in March I wrote about a prototype integration between Spring Surf and OpenCMIS.

Spring Surf provides a scriptable approach to building web applications. OpenCMIS provides a Java client library for accessing any CMIS compliant content repository. By combining the two, we create a development platform for building CMIS enabled web applications.

Since that time, several enhancements have been made to the integration and also to the sample CMIS Browser web application.

In the video below, new CMIS Browser features are demonstrated such as property, relationship and rendition views, query invocation and support for connecting to multiple repositories at once. These features are shown against both Alfresco and IBM repositories at the same time.

Note: Select the HD version of the videos for a clear view of the text.

This is followed by a brief walkthrough of the CMIS Browser code changes required to support the above features.

Note: Select the HD version of the videos for a clear view of the text.

The Spring Surf and OpenCMIS integration is “a work in progress” with code still under development. Feedback is welcome.

Alfresco’s Interpretation of CMIS Renditions

A relatively unknown capability of CMIS 1.0 is Renditions. In the content management world, the term ‘renditions’ typically means a facility to generate and retrieve alternative representations of content or a document. CMIS formalizes only the retrieval of such alternative representations. Although this may seem limiting, it does standardize common use cases such as the preview of reduced fidelity representations (e.g a thumbnail), the discovery and retrieval of processed images and videos from a Digital Asset Management system, and the publishing of web compliant content from a Web Content Management system.

Alfresco has provided Renditions support since its inception, although it wasn’t until the recently released v3.3 that we actually called them Renditions. More on that later. In fact, anyone who has used Alfresco Share has used the Rendition capabilities of Alfresco. It powers the Thumbnail and Web Preview features of the Document Library.

Share Document Library Thumbnails

Share Document Library Web Preview

Alfresco v3.3 also implements the CMIS 1.0 specification including support for CMIS Renditions. This means that all Renditions generated by Alfresco are accessible through the CMIS bindings in a standardized way.

Lets take a look at how to retrieve an Alfresco Share Document Library thumbnail through the CMIS AtomPub binding.

curl -uadmin:admin

The response to the above HTTP GET request, which is the equivalent of issuing CMIS getObject(), includes additional information describing the ‘cmis:thumbnail’ rendition, the only rendition kind standardized by CMIS. A Repository may provide any number of other rendition kinds.

  <link rel="alternate" type="image/png" cmisra:renditionKind="cmis:thumbnail" length="4190" title="doclib"
        href="http://localhost:8080/alfresco/s/cmis/s/workspace:SpacesStore/i/ef7e9a9b-c847-4023-b527-17243c72ade6/content" />

Each rendition is described as a link and additional meta data such as its mime type, size and dimensions. You may have noticed the ‘renditionFilter’ argument on the GET request. This controls which renditions, if any, are to be included in the response and is expressed as a rendition kind or mime type, or list of either.

It’s good to know the nuts and bolts of the CMIS bindings, but it’s not really ideal to work with them directly. They are protocols after all. Developers need APIs. Lets take a look at how to retrieve the same rendition via the Apache Chemistry OpenCMIS Java client API.

OperationContext context = session.createOperationContext();
CmisObject doc = session.getObjectByPath("/Sites/ren/documentLibrary/Spring Surf and OpenCMIS Integration", context);
List<Rendition> renditions = doc.getRenditions();
for (Rendition rendition : renditions)
   System.out.println("kind: " + rendition.getKind());
   System.out.println("mimetype: " + rendition.getMimeType());
   System.out.println("width: " + rendition.getWidth());
   System.out.println("height: " + rendition.getHeight());
   System.out.println("stream id: " + rendition.getStreamId());

This outputs:

kind: cmis:thumbnail
mimetype: image/png
width: 100
height: 100
stream id: workspace://SpacesStore/ef7e9a9b-c847-4023-b527-17243c72ade6

The stream id is important as it allows retrieval of the rendition content via the CMIS getContentStream() service. Remember, the above code is applicable to all CMIS repositories, not just Alfresco.

Now, lets incorporate the above code into Spring Surf

<#list renditions as rendition>
  <td><a href="<@cmisLib.cmisContextUrl conn.name/>/rendition/${object.id}/s/${rendition.streamId}">${rendition.kind}</a></td>
  <td><#if rendition.length != -1>${rendition.length?c}</#if></td>

…to display the list of renditions available for a document in a Web Application (Note: the full source of this application is available in the Spring Surf and OpenCMIS prototype integration).

Spring Surf and OpenCMIS view of Renditions

Now we’ve seen how to retrieve renditions in a standardized way, lets dig deeper into Alfresco’s rendition capabilities. Alfresco v3.3 introduces a new Rendition service that combines the best of the existing Thumbnail and Transformation services with the existing WCM forms rendering capability, providing a consistent way to generate renditions from any content in the Alfresco repository. Of course, extensions may be plugged into the Rendition service to create any kind of rendition. Used in conjunction with Alfresco Rules, the rendition service provides the basis for many types of content management application including DAM and WCM.

Lets set up a rule to transform all images that are added to a folder in an Alfresco Share Document Library…

Rule to execute Image Swirl script

Image Swirl script

Image Swirl script

Each rendition definition that’s exposed or created through the Rendition service is mapped to a CMIS rendition kind. Therefore, retrieving a rendition generated through the Alfresco Rendition Service is exactly the same as retrieving a Share document library thumbnail or web preview. Here’s the CMIS AtomPub HTTP GET request:

curl -uadmin:admin

and its response:

  <link rel="alternate" type="image/jpeg" cmisra:renditionKind="swirl" length="56572" title="swirl"

… and the Spring Surf / OpenCMIS Web Application shows…

Swirl Rendition Definition

Swirl Rendition Definition

Swirl Image

Swirl Image

Renditions were introduced into CMIS v1.0 quite late into its development where other features were postponed, but as you can see, the standardization of this capability allows for all kinds of use cases, in particular where a system requires integration with a DAM or WCM repository.

All the samples in this article are supported by Alfresco Community 3.3g which is to be released imminently and http://cmis.alfresco.com (our hosted CMIS repository for development purposes). The Spring Surf and OpenCMIS prototype integration is available at https://anonsvn.springframework.org/svn/se-surf/branches/DEV_CMIS_2/.

For more information on Alfresco’s CMIS offering visit http://wiki.alfresco.com/wiki/CMIS.

CMIS 1.0 is Ready for Use in Alfresco 3.3

I’ve been working on CMIS at Alfresco for a very long time. After more than two years of specification definition, product development and preview releases, I can finally say “go ahead, build your applications on Alfresco CMIS, it’s ready for use”.

A few weeks ago, we released Alfresco 3.3 Community which introduced CMIS 1.0 among many other fine features. The specification itself is very close to becoming an official OASIS standard.

So, what do we provide? In a nutshell, an LGPL-licensed CMIS Repository with full support for the 1.0 specification including:

  • AtomPub and Web Service Bindings
  • CMIS Query Language for searching the repository
  • Navigation services for browsing the repository
  • Object services for create, update and delete of meta-data and content
  • Relationship services for creating and traversing associations
  • Versioning services for checkout / checkin and history
  • Type Definition services for describing meta-data and content
  • Access Control services for examining and applying permissions
  • Rendition services for accessing alternate views of content
  • Change Log services for determining what’s changed in the repository

Unfortunately, Aspects did not make it into the CMIS 1.0 specification. Alfresco wouldn’t be Alfresco without Aspects, so we decided to expose Aspects via the extension mechanism of CMIS, allowing the bindings to play with Aspect coolness. Hopefully, Aspects will appear in CMIS 2.0.

We also map many other Alfresco features through CMIS such as:

As has always been the case since our first CMIS release back in 2008, we’re already receiving lots of great feedback on Alfresco 3.3 CMIS which I thank everyone for. We’ll be releasing a follow-up to Alfresco 3.3 Community in May primarily to introduce the Google Docs integration, but this will also contain CMIS bug fixes and minor enhancements. A hosted version of Alfresco CMIS is continually updated to the latest “in development” version at http://cmis.alfresco.com.

CMIS specifies a set of protocols, not a programming API. To make it as simple as possible to build applications on CMIS, the Apache Chemistry project provides a CMIS Java Client API, named OpenCMIS. You can think of it as the JDBC of CMIS. As well as contributing to OpenCMIS, we’re also currently working on incorporating OpenCMIS into Spring Surf to provide a development environment for building CMIS based Web Applications. Of course, this environment can be used with Alfresco 3.3.

With all this in place, you can go ahead, build your applications on Alfresco CMIS, it’s ready for use.

Spring Surf and OpenCMIS Integration

The video below demonstrates a prototype integration between Spring Surf and OpenCMIS.

Spring Surf provides a scriptable approach to building web applications. OpenCMIS provides a Java client library for accessing any CMIS compliant content repository. By combining the two, we create a development platform for building CMIS enabled web applications.

In the video, a simple web application called the CMIS Browser is shown against both Alfresco and eXo CMIS repositories. This is followed by a walkthrough of the CMIS browser code illustrating how Spring Surf and OpenCMIS are used. As you’ll see, it doesn’t require many lines of code.

Note: Select the HD version of the video for a clear view of the code.

The Spring Surf and OpenCMIS integration is “a work in progress” with code still under development. As new capabilities are added, I’ll follow up with updated videos. Feedback is welcome

Alfresco CMIS Implementation – Now and Next

While we’re closing the last few tasks for our imminent Alfresco Labs 3.2 release, I thought I’d give another status update on our Draft CMIS Implementation.

The Now

Alfresco Labs 3.2 will include our next official CMIS drop. Those of you following SVN HEAD already know we’ve been busy and thanks must go to you for continuing to build great integrations with our CMIS repository and reporting issues, which have now been resolved.

In summary, we offer all mandatory CMIS v0.61 capabilities and most of the optional pieces too. Not just surface capability, but deep compliance of CRUD, type system, versioning, relationships, allowable actions and query for both Web Services and AtomPub bindings all mapped to Alfresco’s underlying Java content services. CMIS bells and whistles such as paging, property filters, include allowable actions and relationships flags are also included. Not only is it complete, it’s solid too, as experienced by an ActiveVOS engineer, who simply commented “Alfresco CMIS Service just works”. We started implementing CMIS back in early 2008. During that time it’s been heavily tested by ourselves and by the wider Alfresco community. On the subject of testing, our CMIS client test harness, which may be used against any CMIS provider, is still growing, and currently contains over 100 tests covering all aspects of the spec including schema validation. The test harness is something I’d like to contribute to Apache Chemistry now I have commit rights.

One feature I’d like to elaborate on is Query. The 3.2 release offers for the first time full CMIS SQL query language capabilities (with the exception of optional Joins) as well as a new Alfresco FTS language which may be embedded in the SQL contains() clause. We provide these new query languages in all Alfresco search APIs, not just via the CMIS bindings. The Alfresco FTS language may be used stand-alone too. We’re excited about this as developers now have simple query languages in their toolbox – think SQL with added multi-valued properties, FTS and hierarchical support. These languages are implementation independent (no Lucene leakage in sight) so it also allows us to evolve the repository query engine in future releases without affecting query clients. More on that later. As an added bonus we’ve also implemented some Alfresco specific query language extensions. Our favorite being the ability to query Alfresco Aspects via CMIS SQL as if they’re were tables, and joining them to Types if required.

In some ways, we’re done implementing the Alfresco CMIS Repository. Of course, the CMIS specification is not yet complete and each week the CMIS TC is busy resolving spec issues. In fact, the spec will soon grow to include namespaces, change log, ACLs and Renditions (note, the CMIS TC is very close to freezing the scope of the spec). As updated spec revisions are released, we’ll keep our CMIS repository in sync, but as of now, we’re complete for v0.61.

The Next

All of this means we’re ready to invest in CMIS clients and tools. There are many roads we can take here. For example, we’re investigating the use of CMIS in our Records Management application currently being developed. But, as you know, Alfresco v3 introduced Share, a new SURF based client that combines collaboration and content management. It includes a smart document library employing the latest HTML and client-side Javascript technologies to provide a really smooth UI experience. Our intent is to implement a version of the document library that talks CMIS. The neat thing is we can also support Share’s thumbnail and web-ready document preview capabilities now that Renditions are to be included in the CMIS specification. The best way to understand the document library is to see it.

Everything shown in the video is catered for in the CMIS specification. When we CMIS enable the document library, teams will be able to collaborate in Alfresco Share sites against content stored in Alfresco, EMC, IBM, MS, Open Text… if we do the job properly, you’ll be able to embed the same document library in your own applications and easily customise it now we’ve dumped the impenetrable JSF for scripting and template languages in SURF. This is definitely something to look forward to.

Back to the present, Alfresco Labs 3.2 is fast approaching. You can keep up-to-date via SVN HEAD and read more details about our implementation and CMIS in general at wiki.alfresco.com/wiki/CMIS.

Update on Alfresco’s Draft CMIS Implementation

Alfresco’s Draft CMIS Implementation has been publicly available for 4 months. In that time, things have moved on (e.g. the first OASIS CMIS TC face-2-face was held recently), so I thought I’d give an update on where we are with our implementation and what’s happening next.

Before that, I want to thank everyone who has taken the time to download the Alfresco Draft CMIS Implementation, try it out, give us feedback, create examples, provide training, built integrations or just spread the word. This allows us to improve our implementation and also provide further feedback to the CMIS TC, which in turn, helps everyone.

Alfresco Repository as a CMIS Provider

We provide CMIS Web Service and AtomPub bindings on top of the Alfresco Repository. Approximately 80% of the current CMIS specification is covered so you can perform CRUD operations, navigate, query, checkout/in etc. There are still TODOs in the implementation, but we’ll get to those.

Here’s a high level view of the implementation…

Both bindings utilize a CMIS Abstraction API which encapsulates the mapping between CMIS and Alfresco concepts, in particular, the mapping between the CMIS data model and Alfresco’s. Apache CXF has been introduced to support the CMIS Web Service binding, while Alfresco’s own Web Scripts framework is used to implement the CMIS AtomPub binding. We’ve integrated Apache Abdera into the Web Scripts framework to allow native support of AtomPub. CMIS extends AtomPub, and Apache Abdera provides a neat extension capability, so we’ve also built an Abdera CMIS extension for parsing and building CMIS AtomPub documents.

The CMIS query language is implemented on top of the Alfresco query engine (which itself is based on Apache Lucene and Hibernate).

Content that’s managed in Alfresco Explorer and Share can be accessed and modified via the Alfresco Repository CMIS APIs.

CMIS Tests

One of the difficulties of implementing any specification is to ensure you comply with it. Tests obviously help, so we’ve built several CMIS test harnesses to assist:

  • JUnit tests for the CMIS AtomPub binding
  • JUnit tests for the CMIS Web Services binding
  • NUnit tests for the CMIS Web Services binding

The aim is to provide implementation independent tests, so although we use them to test Alfresco’s CMIS  implementation they can also be used to any other implementation. We’ve tried to make it as easy as possible to launch the CMIS AtomPub test harness; every Alfresco CMIS Repository exposes it at http://<host>:<port>/alfresco/service/api/cmis.html…

Enter the Repository CMIS Service Document location and hit ‘Test’.

Alfresco SURF Experiments

One advantage of hooking AtomPub support (and the CMIS extension) into Web Scripts is that the same APIs can be used in SURF UI Components. This allows a SURF component to construct CMIS requests and parse CMIS responses from any CMIS compliant provider using Javascript and Freemarker. In our HEAD branch of the Alfresco SVN repository you’ll find some very simple CMIS Share Dashlets for query and browsing of any CMIS compliant provider.

A simple SURF component for browsing a CMIS compliant Repository…

Community Resources

We continue to update the Alfresco CMIS WIKI which is now taking shape as a ‘go to’ place for all resources related to CMIS.  For example, you’ll find a list of known CMIS provider implementations in development.  There’s also the CMIS Forum for asking questions.

Community Activity

So, what have folks been doing with Alfresco’s Draft CMIS Implementation. My favourites of the day…

1. Joomla Integration…

2. Drupal Integration…

3. Flex Client

4. JavaFX Client

What’s Next?

1. Continue to contribute to the OASIC CMIS TC. There’s now an agressive proposed timeline, so we expect rapid updates to the specification in the short term.

2. Update to the Draft CMIS Implementation in our Labs 3E release which will fix issues raised by early adopters, complete the remaining TODOs and of course, adjust to the latest CMIS specification at the time. Code changes are being made to our HEAD branch in SVN, so if you can’t wait till 3E, you can get work in progress at any time. Some of the short term enhancements include:

  • Deeper CMIS SQL support (sorting, paging, full text language, some joins)
  • Access to custom sub-types and properties across AtomPub and Web Services bindings
  • Allowable Actions support
  • Apache Adbera extension to cover all aspects of CMIS
  • Further coverage in Test Harnesses

3. Expect to see new CMIS client samples ranging from Java code, .NET code, SURF UI Components and potentially Flex too.

4. Development of proprietary extensions for accessing all of Alfresco’s model including Aspects.

5. We hope to host Alfresco’s Draft CMIS Implementation for people to try out without downloading and to execute our CMIS Test Harnesses against other providers.

6. Assist AIIM’s validation of CMIS.

As you can see, there’s a lot going on. Hopefully I’ve given you a picture of where we are and where we’re going. You can keep up-to-date via this blog, twitter, and svn.

Have fun.

UPDATE 2/12/09: Flex Client link updated and screen shot added

UPDATE 2/13/09: Steve Reiner is also building a CMIS Flex Client based on his excellent FlexSpaces

Introducing the Draft CMIS Implementation

Last week, Alfresco released Labs 3B on the same day that EMC, IBM and Microsoft announced the publication of CMIS.  This was no coincidence.

Labs 3B includes the first publicly available and open source implementation of CMIS v0.5 as used in the recent “Plugfest” where IBM, EMC, Microsoft, Open Text, Oracle, SAP and Alfresco got together to test the interoperability of their servers and clients via CMIS.

Alfresco has been a contributing member to the specification for some time.  Since the beginning we felt it best to provide feedback and push forward the specification by actually building an implementation against the specification, to test how feasible it is to map to an existing content repository and for developing test clients that support the primary use cases.  Within Alfresco, the implementation is known as Project Seamist.  We had to use a code name as keeping stuff secret was not easy for an open source company built on transparency!

The Draft CMIS implementation in Alfresco Labs 3B provides:

  • Support for the CMIS REST and Web Services bindings allowing client applications to connect to, navigate, read, and create content against the Alfresco content repository. The CMIS REST binding is built upon Alfresco’s Web Scripts with extensions for Atom / AtomPub.  It’s a natural fit.  It’s something we’ve anticipated for a while.  The CMIS Web Services binding is built upon Apache CXF.
  • Support for the CMIS Query Language providing SQL-like querying of the repository including location, properties, and full-text.
  • A CMIS Test Suite to allow compliance compatibility testing against any CMIS compliant REST Binding.

This is really just the beginning for CMIS.  A draft TC charter has been submitted to OASIS and we look forward to the time when CMIS becomes an OASIS standard.  Between now and then, there’s plenty to discuss.  I expect a cross-section of ECM, Web Service and RESTful expertise to join in.  That’s why we’re providing the Draft CMIS implementation; to foster discussion, to provide a learning tool to gain hands-on experience and to ensure a robust, implemented specification.

We’ll keep the implementation fresh as the specification moves forward.  The following resources will help keep you up-to-date:

This blog will continue to provide information on the CMIS specification, Alfresco’s Draft CMIS Implementation, and how CMIS contrasts with JCR, so subscribe now, and have fun with the Draft CMIS Implementation.