Devoxx08 - Nuxeo Core, JCR 2, CMIS

82
www.devoxx.com Using content repositories: Nuxeo Core, JCR 2, CMIS Florent Guillaume Head of R&D Nuxeo

description

Nuxeo Core, JCR 2, CMIS: learn how to use content repositories APIs
 to store and manipulate rich documents.

Transcript of Devoxx08 - Nuxeo Core, JCR 2, CMIS

Page 1: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Using content repositories: Nuxeo Core, JCR 2, CMIS

Florent GuillaumeHead of R&DNuxeo

Page 2: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Overall presentation goal

Learn how to use content repositories APIsto store and manipulate rich documents

Page 3: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Speaker’s qualificationsFlorent Guillaume is Head of R&D at Nuxeo, a leading vendor of Open Source ECM platforms

Florent Guillaume is a member of international normalization technical committees: JSR-283, Oasis CMIS

Florent Guillaume architected and wrote an ECM system (Nuxeo CPS) and is a lead architect on another (Nuxeo EP)

Florent Guillaume wrote a low-level storage engine for Nuxeo Core

3

Page 4: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Store information

Attached file (binary stream)

Metadata

Retrieve information

Search

Security

Be visible and editable

Out of scope for a repository

4

What is a document?

Page 5: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

What is a “rich” document?Depends on your definition of “rich”

5

Page 6: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

What is a “rich” document?Depends on your definition of “rich”

5

Page 7: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

What is a “rich” document?Depends on your definition of “rich”

Associated binary streams

Multiple attached files

Vignettes

Renditions

Complex metadata

Lists of records

Sub-records (XML-like)

6

Page 8: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

What storage APIs?Filesystem

Relational database

JCR (JSR-170, JSR-283)

Nuxeo Core

CMIS

7

Page 9: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

FilesystemDecide where to store files

Decide how to uniquely identify files

Use java.io.FileOutputStream for binaries

Decide how to serialize metadata

All by hand

java.io.ObjectOutputStream, Serializable

etc.

8

Page 10: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Read/write

Filesystem example

9

public void createDocument(Long id, String title) throws IOException { File file = new File(ROOT_DIR, id.toString()); OutputStream out = new FileOutputStream(file); try { out.write(title.getBytes("UTF-8")); } finally { out.close(); } }

public MyDocument getDocument(Long id) throws IOException { File file = new File(ROOT_DIR, id.toString()); InputStream in = new FileInputStream(file); try { byte[] bytes = new byte[100]; int n = in.read(bytes); String title = new String(bytes, "UTF-8"); MyDocument doc = new MyDocument(); doc.setId(id); doc.setTitle(title); return doc; } finally { in.close(); } }

Page 11: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Filesystem drawbacksSimplistic, no actual model

Everything has to be done manually

No search

10

Page 12: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Filesystem using JAXBMap Java objects to/from XML representations

Define a schema (model)

Marshall/Unmarshall using JAXB APIs

11

Page 13: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Relational databaseJDBC

Hibernate

...other ORMs

JPA

12

Page 14: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JDBCDefine a SQL model for your data

Tables, Columns, Data types

Decide where to store BLOBs

Column or filesystem

Emit SQL statements to do all read/write operations

13

Page 15: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JDBC exampleClass defining the model

14

class MyDocument {

private Long id;

private String title;

public Long getId() { return id; } public void setId(Long id) { this.id = id; }

public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}

Page 16: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Establish a connection, Write

JDBC example

15

public void init() throws ClassNotFoundException { Class.forName("com.myvendor.TheDriverClass"); } public Connection getConnection() throws SQLException { return DriverManager.getConnection("jdbc:myvendor:/my/database/info", "myLogin", "myPassword"); }

public void createDocument(Long id, String title) throws SQLException { PreparedStatement ps = null; Connection conn = getConnection(); try { ps = conn.prepareStatement("INSERT INTO MyDocuments (id, title) VALUES (?, ?)"); ps.setLong(1, id); ps.setString(2, title); ps.execute(); } finally { if (ps != null) ps.close(); conn.close(); } }

Page 17: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Read

JDBC example

16

public MyDocument getDocument(Long id) throws SQLException { PreparedStatement ps = null; Connection conn = getConnection(); try { ps = conn.prepareStatement("SELECT title FROM MyDocuments WHERE id = ?"); ps.setLong(1, id); ResultSet rs = ps.executeQuery(); if (!rs.next()) { return null; } String title = rs.getString(1); MyDocument doc = new MyDocument(); doc.setId(id); doc.setTitle(title); return doc; } finally { if (ps != null) ps.close(); conn.close(); } }

Page 18: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JDBC drawbacksStill very much manual

No document abstraction

Reads from ResultSets have to know proper types

17

Page 19: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

HibernateModel your documents as classes

Define an object-relational mapping in XML

Use Hibernate to automate read/writes

18

Page 20: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Hibernate exampleXML configuration

19

<hibernate-mapping> <class name="example.MyDocument" table="DOCUMENTS"> <id name="id" column="DOC_ID"> <generator class="native"/> </id> <property name="title"/> </class></hibernate-mapping>

Page 21: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Hibernate exampleRead/write

20

class DocumentManager {

public void createDocument(Long id, String title) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); MyDocument doc = new MyDocument(); doc.setId(id); doc.setTitle(title); session.save(doc); session.getTransaction().commit(); session.close(); }

public MyDocument getDocument(Long id) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Query query = session.createQuery("FROM MyDocument WHERE id = :id"); query.setParameter("id", id); MyDocument doc = (MyDocument) query.uniqueResult(); session.getTransaction().commit(); session.close(); return doc; }}

Page 22: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Hibernate drawbacksDocument classes have to be defined by hand

No standard, just application-defined classes

Object-relational mapping too flexible

Too much choice can be a curse

Binaries are still a problem (no streaming)

Hibernate’s “binary” is a byte[] → Memory hog

Blob support inconsistent

21

Page 23: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JPAModel your documents as classes

Define an object-relational mapping using annotations

Use JPA to automate read/writes

22

Page 24: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JPA exampleClass defining the model and the mapping

23

@Entityclass MyDocument {

private Long id;

private String title;

@Id public Long getId() { return id; } public void setId(Long id) { this.id = id; }

public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}

Page 25: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JPA exampleRead/write

24

@Statelessclass DocumentManagerBean {

@PersistenceContext EntityManager em;

public void createDocument(Long id, String title) { MyDocument doc = new MyDocument(); doc.setId(id); doc.setTitle(title); em.persist(doc); }

public MyDocument getDocument(Long id) { return em.find(MyDocument.class, id); }

public List<MyDocument> listDocuments() { Query query = em.createQuery("SELECT doc FROM MyDocument doc"); return query.getResultList(); }}

Page 26: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JPA drawbacksSame as Hibernate

Although annotations are very convenient

25

Page 28: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Beyond mere storageStandard document abstraction

Security

Locking

Versioning

Full text search

Types and inheritance

Folders? ordering?

27

Page 29: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCRContent Repository API for Java™ Technology

JSR-170, released in June 2005

Initiated by Day Software

Also BEA, Documentum, FileNet, IBM, Oracle, Vignette and others

Apache Jackrabbit is the RI

28

Page 30: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR goalsJava API

Fine-grained, hierarchical storage model

Be the “SQL” of hierarchical storage

Lots of functionality

29

Page 31: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR featuresCRUD

Hierarchy of nodes

Simple properties, Lists, Binaries

Queries

Versioning, Locking, References, ...

30

Page 32: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR 2JSR-283

First public review July 2007

Final release expected early 2009

Nuxeo is a contributor to the specification

31

Page 33: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR 2 featuresFix JSR-170 inconsistencies

Several compliance levels

New property types

Improved features

Versioning, Access control, Observation

Retention & Hold

Shareable nodes

Java query API

32

Page 34: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – nodes and properties

33

Node Type

foo

Property Type

value

bar

childchild

Page 35: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – node hierarchy

34

(root)

Folder Folder

Document

Document

Folder

foo bar gee

File

docthing

vignette

Page 36: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – properties types

35

String

Binary

Date

Long

Double

Boolean

Name

Path

Reference

JCR 2

Decimal

WeakReference

URI

Page 37: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – hierarchy with properties

36

(root)

Folder Folder

Document

Document

String

my doc

String

...

Folder

foo bar gee

Date

2008-12-11

String

florentFile

String

img.png

Binary

<binary>

docthing

title descriptiondate creatorvignette

filename data

Page 38: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – node hierarchy

37

(root)

Folder Folder

Document

Document

title: my doc

description: ...

date: 2008-12-11

creator: florent

Folder

foo bar gee

File

filename: img.png

date: <binary>

docthing

vignette

Page 39: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – typesDefine the model

38

<my='http://my.example.com/ns'>

[my:document]- my:id (long) mandatory- my:title- my:description- my:creator- my:date (date)+ my:vignette (nt:resource)

Page 40: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – APIEstablish a connection

39

public Repository repository;

public javax.jcr.Session session;

public void init() throws IOException { repository = new TransientRepository(); }

public void open() throws LoginException, RepositoryException { Credentials credentials = new SimpleCredentials("username", "password".toCharArray()); session = repository.login(credentials); }

public void close() { session.logout(); }

Page 41: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – APIRead/write

40

public void createDocument(Long id, String title) throws RepositoryException { Node root = session.getRootNode(); Node doc = root.addNode(id.toString()); doc.setProperty("my:id", id); doc.setProperty("my:title", title); session.save(); }

public Node getDocument(Long id) throws RepositoryException { Node root = session.getRootNode(); Node doc = root.getNode(id.toString()); return doc; }

Page 42: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

JCR – APIQuery

41

public List<Node> getDocuments() throws RepositoryException { QueryManager queryManager = session.getWorkspace().getQueryManager(); Query query = queryManager.createQuery( "//element(*, my:document)", Query.XPATH); query = queryManager.createQuery( "SELECT * from my:document", Query.SQL); List<Node> documents = new LinkedList<Node>(); NodeIterator it = query.execute().getNodes(); while (it.hasNext()) { documents.add(it.nextNode()); } return documents; }

Page 43: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

NuxeoFounded in 2000

Sustained growth for 8 years

Pioneering Open Source ECM software vendor

International organization, customers, partners, community

40+ employees

Business oriented Open Source

42

Page 44: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Nuxeo ECM3+ years of work

Focus on the platform

Document Core

Nuxeo EP, Nuxeo WebEngine, Nuxeo RCP

Components everywhere (OSGi)

Large feature set

Big deployments

43

Page 45: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Nuxeo CoreHigh-level document-oriented Java API

Complex document abstraction

Independent of actual storage backend

EJB remoting

REST bindings (JAX-RS)

SOAP bindings (JAX-WS)

44

Page 46: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Nuxeo Core basicsCRUD

Hierarchy of document

Complex properties

Binaries

Security

Locking

Versioning

Publishing, Proxies

45

Page 47: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Nuxeo CoreDefine the model

46

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:nxs="http://www.nuxeo.org/ecm/schemas/mydocument" targetNamespace="http://www.nuxeo.org/ecm/schemas/mydocument">

<xs:include schemaLocation="core-types.xsd"/>

<xs:element name="id" type="xs:integer"/> <xs:element name="title" type="xs:string"/> <xs:element name="description" type="xs:string"/> <xs:element name="creator" type="xs:string"/> <xs:element name="date" type="xs:date"/> <xs:element name="vignette" type="nxs:content"/> <xs:element name="fullname" type="nxs:fullname"/>

<xs:complexType name="fullname"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType>

</xs:schema>

Page 48: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Nuxeo CoreDefine the model

47

<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema"> <schema name="mydocument" src="schemas/mydocument.xsd" prefix="mydoc"/></extension>

<extension target="org.nuxeo.ecm.core.schema.TypeService" point="doctype"> <doctype name="MyDocument" extends="Document"> <schema name="common"/> <schema name="mydocument"/> <facet name="Versionable"/> </doctype></extension>

Page 49: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Nuxe Core – APIRead/Write

48

@Scope(ScopeType.STATELESS)@Name("myDocumentActions")public class DocumentActionsBean {

@In(create = true) protected transient NavigationContext navigationContext;

@In(create = true) protected transient CoreSession documentManager;

public void createDocument(Long id, String title) throws ClientException { DocumentModel current = navigationContext.getCurrentDocument(); DocumentModel doc = documentManager.createDocumentModel( current.getPathAsString(), null, "MyDocument"); doc.setProperty("mydocument", "id", id); doc.setPropertyValue("mydoc:title", title); doc.setPropertyValue("mydoc:fullname/firstname", "Florent"); documentManager.createDocument(doc); documentManager.save(); }}

Page 50: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMISDraft v 0.5 published in September 2008 by EMC, IBM, Microsoft

Alfresco, Open Text, Oracle, SAP also on board from the start

Oasis TC formed in November 2008

Adullact, Booz Allen Hamilton, Day, Ektron, Exalead, Fidelity, Flatirons, Magnolia, Mitre, Nuxeo, Saperion, Sun, Vamosa, Vignette (as of 2008-12-01)

CMIS 1.0 expected mid-2009

49

Page 51: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS goalsSimple document model

Independent of protocol

SOAP, REST (AtomPub) bindings

Not tied to a programming language

Platform, vendor independent

Basic set of ECM functions

“Greatest common denominator”

50

Page 52: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS basicsCRUD

Hierarchy folders, documents

Simple properties, lists

One binary

Policies

Versioning

Relationships

Queries

51

Page 53: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS advancedMulti-filing

Advanced queries

Joins

Full text

... maybe more to come

52

Page 54: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS basic propertiesObjectId

Uri

ObjectTypeId

CreatedBy

CreationDate

LastModifiedBy

LastModificationDate

ChangeToken

Name (doc, folder)

version-related props (doc)

ParentId (folder)

AllowedChildObjectTypeIds (folder)

SourceId (rel)

TargetId (rel)

PolicyName (policy)

PolicyText (policy)53

Page 55: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS objects

54

Folder DocumentRelationship Policy

Page 56: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS folders

55

Folder(root)

Folderfoo

Folderbar

Folderstuff

Foldergee

Folderblah

Page 57: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS documents

56

Folder(root)

Folderfoo

Folderbar

Folderstuff

Foldergee

Folderblah

Doc123

Doc456

Doc789

Doc001

Page 58: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS relationships

57

Folder

(root)

Folder

foo

Folder

bar

Folder

stuff

Folder

blah

Doc

456

Doc

001

555

333

Doc

123

Page 59: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS policies

58

Folder(root)

Folderfoo

Folderbar

Doc123

Doc001

Policy

PolicyPolicy

Page 60: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS policies uses

59

ACLs

Locks

Retention & Hold

Automatic transformations

Repository hints

etc.

Page 62: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Standard SQL-92

Extensions for multi-valued properties

Extensions for hierarchical searches

Extensions for fulltext search

CMIS query example

61

SELECT OBJECT_ID, SCORE() AS SC, DESTINATION, DEPARTURE_DATES FROM TRAVEL_BROCHURE WHERE IN_TREE( , ‘ID00093854763’) AND CONTAINS( , 'PARADISE ISLAND CRUISE') AND '2010-01-01' < ANY DEPARTURE_DATES AND CONTINENT <> 'ANTARCTICA'ORDER BY SC DESC

Page 63: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Additional headers for behavior control

MIME types

CMIS AtomPub bindings

62

Service application/atomsvc+xml

Feed application/atom+xml;type=feed

Entry application/atom+xml;type=entry

Query application/cmisquery+xml

AllowableActions application/cmisallowableactions+xml

Page 64: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS Web Services bindings

63

All the WSDL files are provided

Check the spec ;-)

Page 65: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS repository servicesgetRepositories

getRepositoryInfo

getTypes

getTypeDefinition

64

Page 66: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS navigation servicesgetDescendants

getChildren

getFolderParent

getObjectParents

getCheckedoutDocuments

65

Page 67: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS object servicescreateDocument

createFolder

createRelationship

createPolicy

getAllowableActions

getProperties, updateProperties

getContentStream, setContentStream, deleteContentStream

moveObject, deleteObject, deleteTree66

Page 68: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS multi-filing servicesaddObjectToFolder

removeObjectFromFolder

67

Page 69: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS discovery servicequery

68

Page 70: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS relationships servicesgetRelationships

69

Page 71: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS policy servicesapplyPolicy

removePolicy

getAppliedPolicies

70

Page 72: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

CMIS versioning servicecheckOut

cancelCheckOut

checkIn

getPropertiesOfLatestVersion

getAllVersions

deleteAllVersions

71

Page 73: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Mapping documents to JCRDocument → Node

Schema → Mixin type

Simple & Array properties → Properties

Complex type → Sub-node

Lists of complex types → Ordered sub-nodes

72

Page 75: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Mapping documents to SQLParent-child relationships → Dedicated “hierarchy” table

Schema → Table

Simple property → Column

Array property → “Collection” table

Complex type → Sub-document

Lists of complex types → Ordered sub-documents

74

Page 78: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Nuxeo Core 2 and CMISNext-generation storage based on CMIS model

No “impedance mismatch” in models

Nuxeo extensions if needed

Leverage the Visible SQL Storage backend

Distributed and clusterable

Faster remote access and caching

True clusters

Facilitate cloud-based backends

77

Page 79: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

SummaryMany storage choices

Define your model, choose the right API

JCR is very capable

CMIS is coming fast

Nuxeo gives the best of both

78

Page 80: Devoxx08 - Nuxeo Core, JCR 2, CMIS

www.devoxx.com

Concluding statement

Look for CMIS soon, and check out Nuxeo now!