Content Management Interoperability Services (CMIS) is the preferred API for writing code against Alfresco. This presentation explains how to get started using CMIS and covers some of the gotchas and limitations you should be aware of before you commit to CMIS for your project. This presentation was originally delivered at Alfresco Summit 2013 in Barcelona and Boston.
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
Getting Started With CMIS
1. First Steps with CMIS &
Alfresco
Jeff Potts
@jeffpotts01
http://ecmarchitect.com
#SummitNow
2. You’ve been handed a project
Your Favorite Language/Framework
What Goes Here?
#SummitNow
#SummitNow
3. You’ve been handed a project
Your Favorite Language/Framework
#SummitNow
#SummitNow
4. CMIS gives developers a standard
API for working with content
repositories like Alfresco
#SummitNow
#SummitNow
5. First Steps with CMIS
1. Choose CMIS as your preferred API
2. Use the OpenCMIS Workbench as a
learning tool
3. Set up your development environment
4. Watch out for gotchas/limitations
5. Take advantage of additional learning
resources
#SummitNow
#SummitNow
6. Why CMIS?
Preferred API for working with Alfresco
Open standard, managed by OASIS
Many vendors support it
Plenty of examples
Client libraries for many languages
• Java, Python, .NET, PHP, ObjectiveC, Android
#SummitNow
#SummitNow
10. Explore the Alfresco repo
CRUD objects
Inspect/change properties
Run queries
Run scripts using the Groovy console
See the content model
#SummitNow
#SummitNow
11. The Workbench is great for…
Testing queries
Inspecting the data dictionary
• Including whether or not a property is
read/write or queryable
Can I do _____________ with CMIS?
#SummitNow
#SummitNow
12. Alfresco CMIS Service URLs by Version
Alfresco
Version
CMIS Service URL
3.2r2 - 3.4
http://localhost:8080/alfresco/service/cmis (ATOM)
http://localhost:8080/alfresco/cmis (SOAP)
4.0
http://localhost:8080/alfresco/cmisatom
http://localhost:8080/alfresco/cmis (SOAP)
4.2.d/4.2
Enterprise
http://localhost:8080/alfresco/api/-default-/cmis/versions/1.0/atom
http://localhost:8080/alfresco/api/-default-/cmis/versions/1.1/atom
http://localhost:8080/alfresco/api/-default-/cmis/versions/1.1/browser
http://localhost:8080/alfresco/cmis (SOAP)
#SummitNow
#SummitNow
13. Set Up Your Dev Environment
#SummitNow
#SummitNow
14. Let’s set up your environment
Could use curl or any other HTTP client, but
why?
Grab OpenCMIS from Apache Chemistry
Maven makes it easy
Group: org.apache.chemistry.opencmis
Artifact: chemistry-opencmis-client-impl
Version: 0.10.0
#SummitNow
#SummitNow
15. File Loader Example
Let’s load some images into Alfresco onpremise
• Get a session
• Create a folder
• Check-in some documents
• Set some properties
https://code.google.com/p/alfresco-api-java-examples/
#SummitNow
#SummitNow
16. CMIS Works in the Cloud Too!
Let’s load some images into Alfresco in the
cloud
Same CMIS calls, different authentication
Register for an API key
• http://www.alfresco.com/develop
#SummitNow
#SummitNow
18. CMIS object IDs are opaque
Best not to even
look at one!
#SummitNow
#SummitNow
19. Queries
CMIS queries are read-only
Do you really need everything?
• select * from cmis:document
Do you really need all rows?
• Use OperationContext to limit
#SummitNow
#SummitNow
20. Working with Aspects
CMIS 1.0 doesn’t know what an aspect is
• Must use OpenCMIS Extension
CMIS 1.1 calls aspects secondary types
• Add/remove aspects by setting
cmis:secondaryObjectTypeIds
For queries, use a join
#SummitNow
#SummitNow
21. Adding an aspect (CMIS 1.0)
parameter.put(SessionParameter.OBJECT_FACTORY_CLASS,
"org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl");
if (!doc.hasAspect("P:cm:geographic")) {
doc.addAspect("P:cm:geographic");
System.out.println("Added aspect");
} else {
System.out.println("Doc already had aspect");
}
HashMap<String, Object> props = new
HashMap<String, Object>();
props.put("cm:latitude", 52.513871);
props.put("cm:longitude", 13.391106);
doc.updateProperties(props);
#SummitNow
#SummitNow
22. Adding an aspect (CMIS 1.1)
List<Object> aspects =
doc.getProperty("cmis:secondaryObjectTypeIds").getValues();
if (!aspects.contains("P:cm:geographic")) {
aspects.add("P:cm:geographic");
HashMap<String, Object> props = new
HashMap<String, Object>();
props.put("cmis:secondaryObjectTypeIds", aspects);
doc.updateProperties(props);
System.out.println("Added aspect");
} else {
System.out.println("Doc already had aspect");
}
HashMap<String, Object> props = new
HashMap<String, Object>();
props.put("cm:latitude", 52.513871);
props.put("cm:longitude", 13.391106);
doc.updateProperties(props);
#SummitNow
#SummitNow
23. Query for aspect-based props
SELECT D.cmis:name, G.cm:latitude, G.cm:longitude
FROM cmis:document as D
JOIN cm:geographic as G
ON D.cmis:objectId = G.cmis:objectId
#SummitNow
#SummitNow
24. Working with Relationships
Peer associations only
Both sides must be instances of cmis:folder
or cmis:document or a descendant type
#SummitNow
#SummitNow
25. Working with ACLs
Can manage ACLs
Cannot set or un-set ACL inheritance
#SummitNow
#SummitNow
26. Other Limitations
Can only access objects that are
descendants of cm:content or cm:folder
Cannot create users/groups
Cannot create or change types through the
API (yet)
Cannot work with categories or tags
#SummitNow
#SummitNow
27. A Word About Interoperability
Pay attention to RepositoryInfo
• Multifiling, search, ACL, etc. may differ
between repository vendors
Inspect getAllowableActions
Look at the type definitions
• Not all repositories name types the same
way
#SummitNow
#SummitNow
28. Example Apps & Additional
Learning Resources
#SummitNow
#SummitNow
29. Read the Book
Everything you need to know
about CMIS 1.0 & 1.1
Lots of Groovy and Java
examples
Also covers
Python, .NET, PHP, Android, &
iOS
37%-off: 12cmisal
#SummitNow
#SummitNow
31. Ask questions in the “Alfresco
API” forum!
#SummitNow
#SummitNow
32. First Steps with CMIS
1. Choose CMIS as your preferred API
2. Use the OpenCMIS Workbench as a
learning tool
3. Set up your development environment
4. Watch out for gotchas/limitations
5. Take advantage of additional learning
resources
#SummitNow
#SummitNow
Alfresco Public API (CMIS++)CMISWeb scripts marked “Public”Custom web scripts
Developer tools, client-side and server-side libraries
The OpenCMIS Workbench answers that question. If you can do it in the Workbench, you can do it with the CMIS API
I see lots of people hitting the bindings directly in the forums and on stack. Why do that when there are perfectly good client libraries available?
Why are you selecting *? Do you really need every single property? If not, list the ones that you need. Do you really need all rows? Add a where clause and/or use an OperationContext to limit what comes back