Blog

CMIS, SharePoint 2010, and file checkouts

by | May 25, 2011 | SharePoint | 8 comments

SharePoint 2010 is the first SharePoint with a CMIS adapter.  SharePoint 2010 offers a Web Part to request data from other CMIS servers (e.g. Alfresco and Documentum), and a CMIS producer to offer data to CMIS clients (e.g. Apache Chemistry).

Theoretically this means you can write ECM applications targeting SP 2010, Alfresco, and Documentum using only Chemistry (or some other CMIS application), the same as you can write database applications using only JDBC (and the vendor’s JDBC driver).  How well does it work in practice?

Actually, it seems to work pretty well, especially if your application needs can be expressed using the operations supported by CMIS… to some extent CMIS is a lowest common denominator.  The vendor’s specific tools (SharePoint Web Services, Alfresco Explorer and Share, Documentum DFC / DFS) certainly expose much more of the vendor’s unique functionality.  CMIS supports repository, navigation, object, versioning, multifiling, ACL, policy, discovery, and relationship services, via WSDL and REST bindings.

The CMIS standard defines the above services, and also defines bindings for WSDL, and REST (using the Atom protocol).  Apache Chemistry provides a unified API, such that you specify WSDL or REST when you connect to the repository, and then use the same Chemistry API either way.  Chemistry translates your API calls into the appropriate WSDL or REST requests.

For my project, I wanted to use the REST binding, since REST requests tend to be less verbose than WSDL, hence sending less traffic over the wire.  Also I have more experience with REST, since my project is using Spring MVC to publish REST services.

So we tried connecting to SP2010 using Chemistry’s REST bindings.  This was no trouble, as soon as we figured out the right URL to use (something like this: https://<sp2010_url>/_vti_bin/cmis/rest/<list_or_library_guid>?getRepositoryInfo).  Chemistry’s cookbook page was a big help.  Then we tried querying the repository, listing folders, listing folder contents, creating files, and retrieving files.  Everything worked great!  CMIS looked really awesome!

Then we tried checking out a file.  Wham!  We ran into a brick wall here.  SP2010 always returned an HTTP 400 “bad request”, no matter what we tried.  I traced the REST request Chemistry sent to SP2010, and used the excellent Firefox REST Client to send different versions of that request; no matter what, even when I sent invalid XML, I always got the same “bad request” response.

Time to work with Microsoft Support.  They reproduced the error, and are still working on the issue.  However, my support contact tried checking out over WSDL, and it worked fine!  I tried it myself; after jumping over a few hurdles to use Chemistry against SP2010 via WSDL, it worked fine!  So for now, we are stuck using the more-verbose WSDL protocol.  My MS support contact is still working with the REST support though.

As for the hurdles, Chemistry’s cookbook page came to the rescue again; the main issue is you have to download the WSDL from the SP2010 site yourself, and give Chemistry a file-based URL to the downloaded WSDL.  As far as I can tell, you can’t point Chemistry straight to SP2010’s WSDL; I always get a “401 Unauthorized” error.  It might be possible to use a normal HTTP client to download the WSDL locally, then point Chemistry to the dynamically-downloaded WSDL; I haven’t gotten that far yet.

I did make one change to Chemistry’s recipe; the cookbook page says to use Chemistry’s NTLM authentication module.  As far as I can tell, this requires the app server running your Chemistry-based application to run as a Windows domain user known to the SP2010 server.  But I want the app server to run on any Tomcat-supported OS.  Happily, it turns out you can use Chemistry’s standard authentication provider, and just provide a username and password like normal… obviously you would want to run such a connection over HTTPS!

Below is the code snippet I used to verify I could check out from SP2010 using CMIS (specifically Apache Chemistry) over WSDL:

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.chemistry.opencmis.client.api.Document;
import org.apache.chemistry.opencmis.client.api.ObjectId;
import org.apache.chemistry.opencmis.client.api.Repository;
import org.apache.chemistry.opencmis.client.api.Session;
import org.apache.chemistry.opencmis.client.api.SessionFactory;
import org.apache.chemistry.opencmis.client.bindings.CmisBindingFactory;
import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
import org.apache.chemistry.opencmis.commons.SessionParameter;
import org.apache.chemistry.opencmis.commons.enums.BindingType;
import org.junit.Test;

/**
*
* @author millerd
*/
public class SharePointWSDLTest
{

@Test
public void connectViaWsdl() throws Exception
{
String cwd = System.getProperty(“user.dir”);
System.out.println(“Working dir: ” + cwd);
// Default factory implementation of client runtime.
SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
Map parameter = new HashMap();

// User credentials.
parameter.put(SessionParameter.USER, “some-domain\\some-user-account”);
parameter.put(SessionParameter.PASSWORD, “some-password”);

// getting the wsdl via http doesn’t work – 401 Unauthorized.
//String wsdl = “https://some-host/_vti_bin/cmissoapwsdl.aspx?wsdl”;

// relative file-based URL works fine so long as you give it the
// right relative path… ie. you have to know what the current
// working directory is.
String wsdl = “file:target/classes/acmv2-sharepoint.wsdl”;
// Connection settings.
parameter.put(SessionParameter.BINDING_TYPE, BindingType.WEBSERVICES.value());
parameter.put(SessionParameter.WEBSERVICES_ACL_SERVICE, wsdl);
parameter.put(SessionParameter.WEBSERVICES_DISCOVERY_SERVICE, wsdl);
parameter.put(SessionParameter.WEBSERVICES_MULTIFILING_SERVICE, wsdl);
parameter.put(SessionParameter.WEBSERVICES_NAVIGATION_SERVICE, wsdl);
parameter.put(SessionParameter.WEBSERVICES_OBJECT_SERVICE, wsdl);
parameter.put(SessionParameter.WEBSERVICES_POLICY_SERVICE, wsdl);
parameter.put(SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE, wsdl);
parameter.put(SessionParameter.WEBSERVICES_REPOSITORY_SERVICE, wsdl);
parameter.put(SessionParameter.WEBSERVICES_VERSIONING_SERVICE, wsdl);

parameter.put(SessionParameter.AUTHENTICATION_PROVIDER_CLASS, CmisBindingFactory.STANDARD_AUTHENTICATION_PROVIDER);

// Create session.
Session session = null;

// This supposes only one repository is available at the URL.
List repositories = sessionFactory.getRepositories(parameter);
for ( Repository rep : repositories )
{
System.out.println(“Rep name: ” + rep.getName() + “; id: ” + rep.getId());
if ( “Unapproved Files”.equals(rep.getName()) )
{
session = rep.createSession();
Document doc = (Document) session.getObjectByPath(“/2011/05/03/10/31/19/log4j_103124.properties”);
System.out.println(“Doc ID: ” + ( doc == null ? ” *NOT FOUND* ” : doc.getId()));
if ( doc != null )
{
ObjectId co = doc.checkOut();
System.out.println(“Checked out doc ID: ” + co.getId());
}
}
}
Repository soleRepository = sessionFactory.getRepositories(parameter).get(0);
session = soleRepository.createSession();

}
}

 

Stay tuned for my post CMIS, Sharepoint 2010 and File Check-ins

Categories

Need a bit more info on how Armedia can help you?

Feel free to schedule a 30-minute no-obligations meeting.

8 Comments

  1. Colin Stephenson

    From my experience using the SP2010 and CMIS, I had opted to use WSDL over REST. I was unsure if there were problems in SP2010’s implementation of the REST bindings or if OpenCMIS was still a little buggy in this area or maybe both.

    I also faced the same issue of requiring the WSDL to be local. Again, is this OpenCMIS or SP2010 causing problems?

    Cheers,

    Reply
  2. David Miller

    Colin – I adapted my test case for Alfresco. Using Chemistry I can checkout a document via the ATOM binding no problem: no muss, no fuss. Also, I can connect via WSDL without having to download the WSDL first, and I can checkout files via WSDL too. In short: Alfresco’s CMIS implementation doesn’t suffer the SP 2010 issues I outlined above.

    Reply
  3. Colin Stephenson

    Yip, using Chemistry with Apache with both bindings was straight forward. It gets more interesting when trying to use the same src code to communicate with SP2010, Documentum and Alfresco.

    I have not used Documentum’s GA’ed implementation of CMIS (released with 6.7 but should work fine with 6.6), all “playing” was carried out with an EA version.

    Reply
  4. David Miller

    Colin – sounds like you have a story to tell! What are the most interesting aspects of supporting these 3 repositories with the same code base?

    Reply
    • Colin Stephenson

      Dave, my initial approach for CMIS with supporting the minimum 3 repos (DCTM, Alfresco and SP) was the Lord of the RIngs approach. One src code to interact with them all.

      The interesting parts are, as you have noted in later blogs, are how have each vendor interpreted and implemented the CMIS spec and how OpenCMIS is evolving as a client API.

      Reply
  5. charles v

    Do you guys have any advice or references pages to setup SP2010 with CMIS.

    We’ve been able to connect to SP2010 with CMIS, but our unit test failed after that while trying to create Folder/documents with error 405. I’ve searched all day and try multiple solutions on the net without success!

    Reply
    • charles v

      After improving my request layer, i finally got the full response from SP2010 and realized that I just could not create file/folder on the root. I tried to create in an existing folder and it worked…

      I just have to figure out why I can’t create things on the root folder, maybe I’m using the wrong service

      Reply
      • dmiller

        In principle there’s no reason why you shouldn’t be able to create a folder under the root folder. Perhaps the folder permissions are different? Using native SharePoint and the same login, can you create a folder? Basically I suspect a difference in folder permissions between the root folder (where you cannot add a subfolder) and the existing folder (where you were successful).

        Reply

Submit a Comment

Your email address will not be published. Required fields are marked *