CMIS is the OASIS specification for content management interoperability. It allows client and servers to talk together in HTTP (REST with JSON, AtomPub or SOAP) using a unified domain model. The latest published version is CMIS 1.1.

Nuxeo supports CMIS through the following modules:

  • The Apache Chemistry OpenCMIS library (an Apache project to which Nuxeo is a contributor), which is a general-purpose Java library allowing developers to easily write CMIS clients and servers,
  • Specific Nuxeo OpenCMIS connector bundles, allowing the Nuxeo Platform to be used as a CMIS server with the help of OpenCMIS. The CMIS connector is included in the Nuxeo Platform by default.

Usage

The following documentation uses http://localhost:8080/nuxeo as the URL of the Nuxeo server but you can replace it with http://NUXEO_SERVER/nuxeo if you have another instance available.

You can access the different services from the following URLs:

  • Browser Binding root URL: http://localhost:8080/nuxeo/json/cmis
  • AtomPub service document: http://localhost:8080/nuxeo/atom/cmis
  • SOAP WSDL for the repository service: http://localhost:8080/nuxeo/webservices/cmis/RepositoryService?wsdl

JSON

The Browser Binding (JSON) endpoint is recommended, as it is faster and has more features than the other two endpoints.

You can use a CMIS 1.1 Browser Binding (JSON) client and point it at http://localhost:8080/nuxeo/json/cmis.

If you want to check the JSON returned using the command line, this can be done using curl or wget:

curl -u Administrator:Administrator http://localhost:8080/nuxeo/json/cmis | json_pp

This will give you the description of the default repository:

{
   "default" : {
      "cmisVersionSupported" : "1.1",
      "productName" : "Nuxeo OpenCMIS Connector",
      "productVersion" : "8.10",
      "vendorName" : "Nuxeo",
      "repositoryName" : "Nuxeo Repository default",
      "repositoryDescription" : "Nuxeo Repository default",
      "repositoryUrl" : "http://localhost:8080/nuxeo/json/cmis/default/",
      "thinClientURI" : "http://localhost:8080/nuxeo/",
      "repositoryId" : "default",
      "rootFolderId" : "fe7944e0-3d44-4abc-90d4-64e0e07c63c7",
      "rootFolderUrl" : "http://localhost:8080/nuxeo/json/cmis/default/root",
      "latestChangeLogToken" : "42",
      "capabilities" : {
         "capabilityChanges" : "objectidsonly",
         "capabilityVersionSpecificFiling" : false,
         "capabilityMultifiling" : false,
         "capabilityContentStreamUpdatability" : "pwconly",
         "capabilityQuery" : "bothcombined",
         "capabilityACL" : "manage",
         "capabilityRenditions" : "read",
         "capabilityPWCSearchable" : true,
         "capabilityOrderBy" : null,
         "capabilityPWCUpdatable" : true,
         "capabilityGetDescendants" : true,
         "capabilityUnfiling" : false,
         "capabilityAllVersionsSearchable" : true,
         "capabilityGetFolderTree" : true,
         "capabilityJoin" : "none"
         "capabilityNewTypeSettableAttributes" : { ... },
         "capabilityCreatablePropertyTypes" : {
            "canCreate" : []
         },
      },
      "aclCapabilities" : {
         "propagation" : "propagate",
         "supportedPermissions" : "repository",
         "permissionMapping" : [ ... ],
         "permissions" : [ ... ]
         ]
      },
      "changesIncomplete" : false,
      "changesOnType" : [
         "cmis:document",
         "cmis:folder"
      ],
      "principalIdAnyone" : "Everyone",
      "principalIdAnonymous" : "Guest",
      "extendedFeatures" : [
         {
            "description" : "Adds an additional DateTime format for the Browser Binding.",
            "commonName" : "Browser Binding DateTime Format",
            "versionLabel" : "1.0",
            "id" : "http://docs.oasis-open.org/ns/cmis/extension/datetimeformat",
            "url" : "https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=cmis"
         }
      ]
   }
}

To do a query you can do:

curl -u Administrator:Administrator "http://localhost:8080/nuxeo/json/cmis/default?cmisselector=query&succinct=true&q=SELECT+cmis:objectId,+dc:title+FROM+cmis:folder+WHERE+dc:title+=+'Workspaces'" | json_pp

Which returns:

{
   "numItems" : 1,
   "hasMoreItems" : false,
   "results" : [
      {
         "succinctProperties" : {
            "cmis:objectTypeId" : "WorkspaceRoot",
            "cmis:objectId" : "96e9e7b9-75be-4123-888d-ca89af7c8da3",
            "dc:title" : "Workspaces"
         }
      }
   ]
}

AtomPub

You can use a CMIS 1.1 AtomPub client and point it at http://localhost:8080/nuxeo/atom/cmis.

(Since Nuxeo 7.10, a legacy CMIS 1.0 AtomPub endpoint is also available at http://localhost:8080/nuxeo/atom/cmis10 . This is provided for old clients that cannot be upgraded.)

If you want to check the AtomPub XML returned using the command line, this can be done using curl or wget:

curl -u Administrator:Administrator http://localhost:8080/nuxeo/atom/cmis

To do a query you can do:

curl -u Administrator:Administrator "http://localhost:8080/nuxeo/atom/cmis/default/query?q=SELECT+cmis:objectId,+dc:title+FROM+cmis:folder+WHERE+dc:title+=+'Workspaces'&searchAllVersions=true"

You should probably pipe this through tidy if you want a readable output:

... | tidy -q -xml -indent -wrap 999

Notes

  • The searchAllVersions=true part is mandatory if you want something equivalent to what you see in Nuxeo (which often contains mostly private working copies).
  • In order to fetch custom metadata, you must restrict the selection to document types that contain the metadata. For example, if you have a metadata "custom" in a document type "mytype", then your query would be something like:

    curl -u Administrator:Administrator "http://localhost:8080/nuxeo/atom/cmis/default/query?q=SELECT+cmis:objectId,+mytype:custom+FROM+mytype&searchAllVersions=true"
    

SOAP

The following SOAP endpoints are available:

  • http://localhost:8080/nuxeo/webservices/cmis/RepositoryService?wsdl
  • http://localhost:8080/nuxeo/webservices/cmis/DiscoveryService?wsdl
  • http://localhost:8080/nuxeo/webservices/cmis/ObjectService?wsdl
  • http://localhost:8080/nuxeo/webservices/cmis/NavigationService?wsdl
  • http://localhost:8080/nuxeo/webservices/cmis/VersioningService?wsdl
  • http://localhost:8080/nuxeo/webservices/cmis/RelationshipService?wsdl
  • http://localhost:8080/nuxeo/webservices/cmis/MultiFilingService?wsdl
  • http://localhost:8080/nuxeo/webservices/cmis/ACLService?wsdl
  • http://localhost:8080/nuxeo/webservices/cmis/PolicyService?wsdl

Authentication is done using Web Services Security (WSS) UsernameToken.

Here is a working example of a SOAP message to the DiscoveryService:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://docs.oasis-open.org/ns/cmis/messaging/200908/">
  <soapenv:Header>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <UsernameToken>
        <Username>Administrator</Username>
        <Password>Administrator</Password>
      </UsernameToken>
    </Security>
  </soapenv:Header>
  <soapenv:Body>
    <ns:query>
      <ns:repositoryId>default</ns:repositoryId>
      <ns:statement>SELECT cmis:objectid, dc:title FROM cmis:document WHERE dc:title = 'Workspaces'</ns:statement>
      <ns:maxItems>20</ns:maxItems>
      <ns:skipCount>0</ns:skipCount>
    </ns:query>
  </soapenv:Body>
</soapenv:Envelope>

CMIS Clients

Several free clients for CMIS 1.1 are available. The most complete is the CMIS Workbench, part of OpenCMIS.

Developers can use the Chemistry libraries to produce their own client (Java, Python, PHP, .NET). Documentation and sample for using OpenCMIS libraries can be found on the OpenCMIS developer wiki with also example code and how-to guides.

From Java Code Within a Nuxeo Component

To create, delete or modify documents, folders and relations just use the regular CoreSession API of Nuxeo. To perform CMISQL queries (for instance to be able to perform JOIN that are not supported by the default NXQL query language) have a look at the page Using CMISQL from Java.

Capabilities

The Nuxeo OpenCMIS connector implements the following capabilities from the specification:

Navigation Capabilities
 Get descendants supportedYes
 Get folder tree supportedYes
 Order By supportedCustom
Object Capabilities
 Content stream updatesPWC only
 ChangesObject IDs only
 RenditionsRead
Filing Capabilities
 Multifiling supportedNo
 Unfiling supportedNo
 Version-specific filing supportedNo
Versioning Capabilities
 PWC updatableYes
 PWC searchableYes
 All versions searchableYes
Query Capabilities
 QueryBoth combined
 JoinsNone
(Inner and outer if org.nuxeo.cmis.joins=true)
Type Capabilities
 Create property typesNo
 New type settable attributesNone
ACL Capabilities
 ACLsManage
 ACLs propagationPropagate
 Supported permissionsRepository

Model Mapping

The following describes how Nuxeo documents are mapped to CMIS objects and vice versa.

  • Only Nuxeo documents including the "dublincore" schema are visible in CMIS.
  • Complex properties are not visible in CMIS by default, as this notion does not exist in CMIS. However, if the server is configured to do so, they can be exposed as JSON-encoded strings (since Nuxeo 7.1, see NXP-14474).
  • Dynamic facets are visible as CMIS 1.1 secondary types (since Nuxeo 7.1, see NXP-15070).
  • Proxy documents are visible in CMIS if the system property org.nuxeo.cmis.proxies=true (since Nuxeo 8.3 / Nuxeo 7.10-HF08 (default true since Nuxeo 9.1, false in previous versions), see NXP-17313 and NXP-21828).
  • Secondary content streams are not visible as renditions. Only the Nuxeo thumbnail and renditions explicitly made available through the Nuxeo RenditionService are visible.
  • Documents in the Nuxeo trash (those whose nuxeo:lifecycleState is deleted) are not visible in CMIS, unless an explicit query using the nuxeo:lifecycleState property is done.

This mapping may change to be more comprehensive in future Nuxeo Platform versions.

Nuxeo-Specific System Properties

In addition to the system properties defined in the CMIS specification under the cmis: prefix, the Nuxeo Platform adds some additional properties under the nuxeo: prefix:

  • nuxeo:isVersion: To distinguish between archived (read-only revision) and live documents (that can be edited).
  • nuxeo:lifecycleState: To access the lifecycle state of a document. By default only document in non deleted state will be returned in CMISQL queries unless and explicit nuxeo:lifecycleState predicate is specified in the WHERE clause of the query.
  • nuxeo:secondaryObjectTypeIds: Makes it possible to access the facets of a document. Those facets can be static (as defined in the type definitions) or dynamic (each document instance can have declared facets).
  • nuxeo:contentStreamDigest: The low level, MD5 or SHA1 digest of blobs stored in the repository. The algorithm used to compute the digest is dependent on the configuration of the BinaryManager component of the Nuxeo repository.
  • nuxeo:isCheckedIn: For live documents, distinguishes between the checked-in and checked-out state.
  • nuxeo:parentId: Like cmis:parentId but also available on Document objects (which is possible because the Nuxeo Platform does not have direct multi-filing).
  • nuxeo:pathSegment: The last path segment of the document (ecm:name in NXQL).
  • nuxeo:pos: The position of an object in its containing folder, if that folder is ordered, or null otherwise.

All these properties can be used as regular CMIS properties and in a CMISQL query (in a SELECT, WHERE or ORDER BY clause where relevant), except for nuxeo:contentStreamDigest which can only be read in query results or by introspecting the properties of the ObjectData representation of a document.

Resources

Use Case Video

Watch this 15 min video presenting a case-processing application leveraging CMIS.

 

Source Code

Documentation

Slide Decks

Blog Posts

2 days ago Solen Guitter Don't show excerpt 'upgrade-9.2-drop-change-token' and add comment
a year ago Lise Kemen 80
a year ago Solen Guitter 79
a year ago Solen Guitter 78
a year ago Manon Lumeau 77
a year ago Florent Guillaume 76 | proxies visible in CMIS
2 years ago Florent Guillaume 75 | details
2 years ago Florent Guillaume 74 | NXP-18219 AtomPub CMIS 1.0
2 years ago Florent Guillaume 73
2 years ago Solen Guitter 72
2 years ago Solen Guitter 71 | Add use case video and reorganize resources section
3 years ago Solen Guitter 70
3 years ago Manon Lumeau 69
3 years ago Manon Lumeau 68
3 years ago Manon Lumeau 67
3 years ago Manon Lumeau 66
3 years ago Manon Lumeau 65
3 years ago Manon Lumeau 64
3 years ago Manon Lumeau 63
3 years ago Manon Lumeau 61
3 years ago Manon Lumeau 62
3 years ago Manon Lumeau 60
3 years ago Florent Guillaume 59 | complex props, secondary types
3 years ago Solen Guitter 58 | Replace demo.nuxeo.com with online trial, update URLs and format toc
3 years ago Florent Guillaume 57
3 years ago Florent Guillaume 56 | ACLs/Joins capabilities
3 years ago Florent Guillaume 55
3 years ago Florent Guillaume 54 | Added nuxeo:pos
3 years ago Florent Guillaume 53
3 years ago Florent Guillaume 52
3 years ago Solen Guitter 51
3 years ago Solen Guitter 50 | typo
3 years ago Alain Escaffre 49
3 years ago Alain Escaffre 48
3 years ago Florent Guillaume 47
4 years ago Michaël Vachette 45
4 years ago Michaël Vachette 46
4 years ago Solen Guitter 44
4 years ago Solen Guitter 43 | Removed obsolete information
5 years ago Florent Guillaume 42
5 years ago Florent Guillaume 41
5 years ago Solen Guitter 39
5 years ago Solen Guitter 40 | Migrated to Confluence 4.0
5 years ago Florent Guillaume 38
5 years ago Florent Guillaume 37 | Note that complex properties are not exposed.
6 years ago Florent Guillaume 36
6 years ago Florent Guillaume 35 | hg -> github
6 years ago Florent Guillaume 34 | added 5.5 nuxeo:isCheckedIn and nuxeo:parentId
6 years ago Florent Guillaume 33
6 years ago Florent Guillaume 32
6 years ago Olivier Grisel 31
6 years ago Olivier Grisel 29
6 years ago Olivier Grisel 30
6 years ago Olivier Grisel 28 | link to CMISQL from within Nuxeo
6 years ago Olivier Grisel 27
6 years ago Olivier Grisel 26
6 years ago Olivier Grisel 25
6 years ago Olivier Grisel 24 | format
6 years ago Olivier Grisel 23 | added section on nuxeo specific system properties
6 years ago Olivier Grisel 22
6 years ago Florent Guillaume 21
6 years ago Florent Guillaume 20
7 years ago Florent Guillaume 19
7 years ago Florent Guillaume 18 | doesn't belong here
7 years ago Florent Guillaume 17
7 years ago Julien Carsique 16 | add webengine admin url for cmis
7 years ago Florent Guillaume 15
7 years ago Florent Guillaume 14
7 years ago Florent Guillaume 13 | Updated for OpenCMIS
7 years ago Florent Guillaume 12
7 years ago Jane Zupan 11
7 years ago Florent Guillaume 10
7 years ago Stéfane Fermigier 9
7 years ago Stéfane Fermigier 7
7 years ago Stéfane Fermigier 8
7 years ago Florent Guillaume 6
7 years ago Solen Guitter 5 | formatting and typos
7 years ago Eric Barroca 4
7 years ago Eric Barroca 3
7 years ago Florent Guillaume 2
8 years ago Admin name placeholder 1
History: Created by Admin name placeholder