Monthly Archives: January 2009

Consuming CMIS WSDL in Visual Studio

As indicated previously, I’ve uploaded a CMIS v0.5 sample to EDN. This sample works with EMC Documentum CMIS EA2.

This CMIS sample is intentionally similar to a sample produced previously for DFS 6.5 SP1. The intent is to help you compare and contrast one set of service contracts from the other. In doing so, please keep in mind that CMIS is focused on basic library services for content management–common features across supporting repositories–while DFS is focused on the broader richness of the EMC Documentum ECM Platform.

It’s worth noting that in the case of its CMIS Repository service interaction, this sample EXE was also used by IBM during this week’s TC meeting against their P8-based WSDL endpoint–requiring only a binding configuration change (i.e. zero code changes).

I mentioned that the CMIS AtomPub service (introspection) document for EA2 is accessible as follows: <code>http://host:port/resources/cmis</code>. Let’s say your EA2 installation is running at localhost on 8080, then a request for this document will return the following type of response:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:service xmlns="http://www.w3.org/2005/Atom" xmlns:ns2="http://www.cmis.org/2008/05" xmlns:ns3="http://www.w3.org/2007/app">
  <ns3:workspace ns2:id="dfs">
    <title type="text">dfs</title>
    <ns2:repositoryInfo>
      <ns2:repositoryId>dfs</ns2:repositoryId>
      <ns2:repositoryName>dfs</ns2:repositoryName>
      <ns2:repositoryDescription>dfs</ns2:repositoryDescription>
      <ns2:vendorName>EMC</ns2:vendorName>
      <ns2:productName>Documentum</ns2:productName>
      <ns2:productVersion>6.5.0.033</ns2:productVersion>
      <ns2:rootFolderId>0c00302180000105</ns2:rootFolderId>
      <ns2:capabilities>
        <ns2:capabilityMultifiling>true</ns2:capabilityMultifiling>
        <ns2:capabilityUnfiling>false</ns2:capabilityUnfiling>
        <ns2:capabilityVersionSpecificFiling>true</ns2:capabilityVersionSpecificFiling>
        <ns2:capabilityPWCUpdateable>false</ns2:capabilityPWCUpdateable>
        <ns2:capabilityPWCSearchable>false</ns2:capabilityPWCSearchable>
        <ns2:capabilityAllVersionsSearchable>true</ns2:capabilityAllVersionsSearchable>
        <ns2:capabilityQuery>both</ns2:capabilityQuery>
        <ns2:capabilityJoin>inneronly</ns2:capabilityJoin>
        <ns2:capabilityFullText>fulltextandstructured</ns2:capabilityFullText>
      </ns2:capabilities>
      <ns2:cmisVersionsSupported>0.5</ns2:cmisVersionsSupported>
    </ns2:repositoryInfo>
    <ns3:collection href="http://localhost:8080/resources/cmis/repositories/dfs/objects/0c00302180000105/children" ns2:collectionType="root-children">
      <title type="text">root-children</title>
    </ns3:collection>
    <ns3:collection href="http://localhost:8080/resources/cmis/repositories/dfs/objects/0c00302180000105/descendants" ns2:collectionType="root-descendants">
      <title type="text">root-descendants</title>
    </ns3:collection>
    <ns3:collection href="http://localhost:8080/resources/cmis/repositories/dfs/types" ns2:collectionType="types-children">
      <title type="text">types-children</title>
    </ns3:collection>
    <ns3:collection href="http://localhost:8080/resources/cmis/repositories/dfs/types" ns2:collectionType="types-descendants">
      <title type="text">types-descendants</title>
    </ns3:collection>
    <ns3:collection href="http://localhost:8080/resources/cmis/repositories/dfs/checkedout" ns2:collectionType="checkedout">
      <title type="text">checkedout</title>
    </ns3:collection>
    <ns3:collection href="http://localhost:8080/resources/cmis/repositories/dfs/queries" ns2:collectionType="query">
      <title type="text">query</title>
    </ns3:collection>
  </ns3:workspace>
</ns3:service>

Your repository name and object identifiers will likely differ from the example references above, but hopefully you get the gist of the response payload.

Comparing the RESTful AtomPub binding to the SOAP binding in CMIS, one has to make two service requests to yield the same repository information (i.e. the block of data represented by <code>repositoryInfo</code> above) as follows:

repositories = repositoryService.getRepositories();
foreach (cmisRepositoryEntryType repository in repositories)
{
  cmisAnyXml repositorySpecificInformation;
  string repositoryId = repository.repositoryID,
         repositoryRelationship,
         repositoryDescription,
         vendorName,
         productName,
         productVersion,
         rootFolderId,
         cmisVersionsSupported;
  cmisRepositoryCapabilitiesType capabilities;
  XmlAttribute[] AnyAttr;
  XmlElement[] Any;
  repositoryService.getRepositoryInfo(ref repositoryId, out repositoryRelationship,
         out repositoryDescription, out vendorName, out productName,
         out productVersion, out rootFolderId, out capabilities,
         out cmisVersionsSupported, out repositorySpecificInformation,
         out Any, out AnyAttr);
  . . .
}

Comparing CMIS Repository service WSDL consumption with DFS Search service WSDL consumption, the same DFS-based consumer code is as follows:

Repository[] repositories = searchService.getRepositoryList(null);
foreach (Repository repository in repositories)
{
  . . .
}

To be clear, these examples are not provided for me to argue that one approach is better than another but rather to show how approaches differ based on domain model, use cases, etc.

I’ll leave it as an exercise for the reader to perform similar comparisons where query support and object support is concerned between DFS and CMIS. :-)

Perhaps it’s also useful to comment on how WS-Security header information is passed to CMIS WSDL endpoints, since CMIS WSDL doesn’t currently declare headers explicitly in the service contract.

This sample injects WS-Security headers via app.config-based declaration (versus programmatically):

<extensions>
  <behaviorExtensions>
    <add name="usernameToken" type="SecurityMessageInspector.UsernameTokenBehaviorExtensionElement, SecurityMessageInspector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </behaviorExtensions>
</extensions>
<behaviors>
  <endpointBehaviors>
    <behavior name="UsernameTokenBehavior">
      <usernameToken username="Administrator" password="emc" passwordType="PasswordText"/>
    </behavior>
  </endpointBehaviors>
</behaviors>

Right away, understand that this is a sample–you will likely want to take a more secure approach to managing user credentials. Certainly, if you employed this approach, you should employ a secure transport (i.e. SSL). Please see the sample solution’s README file for more details if a more programmatic approach is desired (with or without SSL).

There are other ways to "wire" WS-Security header creation and passing into applications. This particular sample takes a more subtle (less in-your-face) approach to accomplish this concern. Regardless, implicit SOAP headers in a contract require extra coding on the part of a consumer.

OASIS CMIS TC f2f

Earlier today, John Newton posted a nice summary of what the OASIS CMIS Technical Committee (TC) accomplished this Monday through Wednesday. Anyone interested in the CMIS progress will want to read John’s post.

Earlier this week, EMC released its second Early Access bits that support both bindings in the current draft specification.

It was great to spend time focusing on technical issues and discussing proposals to resolve them. Sometimes there simply isn’t a substitute for working with others in the same room! It was also nice to catch up with prior colleagues–John and Dave Caruana–and establish new report with others in the Enterprise Content Management industry.

In particular, I appreciate the effort made by TC’ers from EMC and IBM to get our bits–both REST and SOAP–interoperating together. We did make demonstrable progress–however difficult the technical environment (i.e. lack of viable network onsite) proved to be. (I’ll post my WCF test client (CMIS WSDL endpoint consumer) separately.)

(By the way, if you ever test MTOM content transfer while outputting messages to a console window, think twice about logging all HTTP traffic. I think that folks in the lobby of building 40 thought my laptop was a bomb when I rushed to leave the TC meeting after I couldn’t get my computer alarm to silence or stop–until a hard power-down action was applied. :-) )

Update 1/31/2009: Thanks to Dennis Hamilton, here is a group photo of those physically present at the TC meeting:

090128 OASIS CMIS TC group photo

EMC Documentum CMIS EA2

Earlier today, the second Early Access (EA2) release of EMC Documentum ECM Platform support for the proposed CMIS standard (i.e. current v0.5 draft) was made publicly available via EDN Labs.

EA2 features support for both bindings in the proposed draft standard: SOAP and AtomPub.

  • CMIS EA2 WSDL endpoints are available as follows:
    http://host:port/services/cmis/service?wsdl
    (e.g. http://localhost:8080/services/cmis/RepositoryService?wsdl)
  • CMIS EA2 AtomPub service document is available as follows:
    http://host:port/resources/cmis
  • CMIS EA2 WADL for the AtomPub resources (not covered by the CMIS specification):
    http://host:port/resources/application.wadl

You’ll find more deployment details in the associated guide.

EMC is committed to CMIS and the standards process. Just as there was an EA1 before this update, there will be subsequent EA releases in the future. Hopefully by making CMIS support available to you as the proposed standard develops and matures, you will consider exercising the draft bindings and submitting your feedback. Thanks in advance!

Update 1/27/2008: Pie (Laurence Hart) has posted about AIIM’s intention to demonstrate CMIS-based interoperability at its upcoming Expo via a prototype. EMC is looking forward to participating in this effort, which will provide a nice proof point for ECM customers, partners and vendors all.

Big Men on Content

Hopefully you’ve already been reading the musings of Lee Dallas and Marko Sillanpaa over at their Big Men on Content blog. If not, I recommend that you give them a read; I do, regularly.

Anyway, this post is a belated acknowledgment of the fact that both Lee and Marko are EMC colleagues now. Marko joined EMC last quarter and is focused on enabling strategic SI’s to develop solutions on top of the CMA platforms. Marko also writes for CMSWire. Although not a package deal–“might have exceeded weight limitations,” to quote Marko*–, Lee joined around the same time and is part of the same group supporting our system integration partners.

So, welcome Lee and Marko to the EMC team!

* Reference the BMoC tagline and about panel for context, please. :-)