New Tutorial: Getting Started with CMIS

I’ve written a new tutorial on the proposed Content Management Interoperability Services (CMIS) standard called, “Getting Started with CMIS“. The tutorial first takes you through an overview of the specification. Then, I do several examples. The examples start out using curl to make GET, PUT, POST, and DELETE calls against Alfresco to perform CRUD functions on folders, documents, and relationships in the repository. If you’ve been dabbling with CMIS and you’ve struggled to find examples, particularly of POSTs, here you go.

I used Alfresco Community built from head, but yesterday, Alfresco pushed a new Community release that supports CMIS 1.0 Committee Draft 04 so you can download that, use the hosted Alfresco CMIS repository, or spin up an EC2 image (once Luis gets it updated with the new Community release). If you don’t want to use Alfresco you should be able to use any CMIS repository that supports 1.0cd04. I tried some, but not all, of the command-line examples against the Apache Chemistry test server.

Once you’ve felt both the joy and the pain of talking directly to the CMIS AtomPub Binding, I take you through some very short examples using JavaScript and Java. For Java I show Apache Abdera, Apache Chemistry, and the Apache Chemistry TCK.

For the Chemistry TCK stuff, I’m using Alfresco’s CMIS Maven Toolkit which Gabriele Columbro and Richard McKnight put together. That inspired me to do my examples with Maven as well (plus, it’s practical–the Abdera and Chemistry clients have a lot of dependencies, and using Maven meant I didn’t have to chase any of those down).

So take a look at the tutorial, try out the examples with your favorite CMIS 1.0 repo, and let me know what you think. If you like it, pass it along to a friend. As with past tutorials, I’ve released it under Creative Commons Attribution-Share Alike.

[Updated to correct typo with Gabriele’s name. Sorry, Gab!]

26 comments

  1. jpotts says:

    I haven’t seen any clients choose to use the web services binding yet, but it is still early. I’m sure there will be cases where it makes sense.

    Jeff

  2. Martin Wildam says:

    I was trying to get into CMIS and I noticed that there are only XML bindings – is that right? Or is there the option (at least for Alfresco) to get the response in a different format (e.g. JSON)?

  3. jpotts says:

    Martin,

    CMIS compliant servers must implement two bindings. One is the Restful AtomPub Binding. The other is the Web Services binding. The current spec doesn’t provide for any other bindings (such as JSON).

    Jeff

  4. Noel Sharpe says:

    Thanks for the Tutorial Jeff. One aspect i am struggling to get working is querying against categories. How do I do this?

  5. jpotts says:

    From page 475 of the Alfresco Developer Guide…

    Category searches use the PATH field, but you construct a path using the classification hierarchy. Suppose that sample-a.pdf is classified under “Languages/German”, and sample-b.pdf is classified under “Languages/German/Swiss-German”. Now consider the following two searches:
    PATH:”/cm:categoryRoot/cm:generalclassifiable/cm:Languages/cm:German/*”
    PATH:”/cm:categoryRoot/cm:generalclassifiable/cm:Languages/cm:German//*”
    The first search will return sample-a.pdf because it is classified as “German” and the “Swiss-German” category. sample-b.pdf won’t be returned because sample-b.pdf is under a subcategory, “Swiss-German”. The second search uses double slashes (“//”) at the end to denote that matches should include “German” as well as anything classified under a subcategory. It returns both documents and the “Swiss-German” subcategory.
    So the category searches, as shown above, will return both objects that have been categorized (“members”) and also the category nodes. If what you want are only documents and not categories, you can use “member” as follows:
    PATH:”/cm:categoryRoot/cm:generalclassifiable/cm:Languages/cm:German/member”
    PATH:”/cm:categoryRoot/cm:generalclassifiable/cm:Languages/cm:German//member”
    The first search would return only sample-a.pdf, while the second search would return sample-a.pdf and sample-b.pdf.

    A handy little hack to get the Lucene full-text search query syntax is to use the web client to build your search, then save the search, then use the Node Browser to go look at the search string Alfresco saved.

    [UPDATE: I just realized you posted this comment regarding the CMIS tutorial so this answer isn’t going to help you at all. CMIS queries don’t support categories, so, unfortunately, if you’re using CMIS, you’re out-of-luck for now].

    Hope that helps,

    Jeff

  6. Nikesh says:

    Hi Jeff,

    I have created Axis2 client and able to access different CMIS services (Alfresco).

    I want execute different features like createDocument, createFolder etc.

    Can you guide me how to set properties using web service client?

    I have generated stub classes using Axis2 ADB option.

  7. Igor Blanco says:

    Jeff, thanks very much for (another) great tutorial.

    Please correct the namespace errata in page 25. CMIS namespace is missing and ending /. I lost 2 days until I did find the error.

    Definitively copy&paste is the worst enemy of the programmer.

  8. jpotts says:

    Totally agree on the copy and paste comment. Yes, screwing up those namespaces can really foul things up. The snippet on page 25 is missing a trailing slash. Instead of:

    "http://docs.oasis-open.org/ns/cmis/core/200908"

    It should read:

    "http://docs.oasis-open.org/ns/cmis/core/200908/"

    The actual downloadable source code does not have this problem.

    Jeff

  9. chrisw says:

    This CMIS has been good stuff to have found. Is there a trick to passing the Drupal user name to Alfresco to limit access to spaces?

  10. jpotts says:

    In a nutshell, you need to do single sign-on between Drupal and Alfresco to make this happen. So, instead of configuring CMIS to use a “system” ID to connect (like “admin” for Alfresco) you can configure it to get a session using the creds already in the Drupal header. Unfortunately, this isn’t a simple checkbox config. We may show this working at DrupalCon (no promises). Maybe we can post more details on it for those that can’t attend.

  11. SAlvador says:

    I’m trying to follow our tutorial but, when trying to create a document, with testCreateSampleA.atom.xml I get an error
    Invalid typeId D:sc:whitepaper.

    However, if I use cmis:document

    then it works.

    Can you explain that?

  12. jpotts says:

    That type, D:sc:whitepaper, is a custom type that does not come with Alfresco out-of-the-box. You have to deploy it as part of a custom content model. You can use your own custom types instead or use the “SomeCo” examples from my blog and/or book. Does your custom content model include a custom content type called sc:whitepaper?

    Jeff

  13. umesh gahlot says:

    hiiiii,I want to migrate from twiki to alfresco(migrate twiki format documents to alfresco)…can u please help?

  14. Rutaveej Shah says:

    Hello jeff!
    I am trying yo create a folder with aspect.But i got the error like ‘Prefix can not be null or empty’.I have added all properties specified by you.I am using alfresco community edition 4.0d.
    Can you have any idea why i getting this kind of error.

  15. jpotts says:

    Rutaveej,

    I cannot really provide any advice unless you include the code you are using to create the folder.

    Jeff

  16. Rutaveej Shah says:

    Hello jeff!
    I have raise the question like prefix can not be null or empty error while creating a folder with aspects.
    My code for that is:
    private Session getSession(String serverUrl, String username, String password)
    {
    SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
    Map params = new HashMap();
    params.put(SessionParameter.USER, username);
    params.put(SessionParameter.PASSWORD, password);
    params.put(SessionParameter.ATOMPUB_URL, serverUrl);
    params.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
    params.put(SessionParameter.OBJECT_FACTORY_CLASS, “org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl”);
    List repos = sessionFactory.getRepositories(params);
    if (repos.isEmpty()) {
    throw new RuntimeException(“Server has no repositories!”);
    }
    return repos.get(0).createSession();
    }
    public void createFolder()
    {
    String servalUrl=”http://localhost:8080/alfresco/cmisatom”;
    String userName=”admin”;
    String password=”admin”;
    Session session=getSession(servalUrl, userName, password);
    Map properties = new HashMap();
    properties.put(PropertyIds.OBJECT_TYPE_ID, “cmis:folder,P:cm:titled”);
    properties.put(PropertyIds.NAME,”TESTFOLDER2″);
    properties.put(PropertyIds.CREATED_BY, “admin”);
    properties.put(“cm:title”, “Title”);
    properties.put(“cm:description”, “Desc”);

    AlfrescoFolder root=(AlfrescoFolder) session.getRootFolder();
    System.out.println(“The Name:”+root.getId()+root.getName());
    AlfrescoFolder newFolder=(AlfrescoFolder) root.createFolder(properties);
    System.out.println(newFolder.getName());
    }
    I have not used alfresco SDK.
    I just used the jar of alfresco open cmis and create code for creating a folder with aspects.
    Please provide me any suggestion on this.
    Thanks

Comments are closed.