Recherche
Nuxeo propose une interface REST. Cf. The Nuxeo Restlet API
Ce mécanisme est particulièrement intéressant dans la mesure où, si les services proposés de base par nuxeo ne sont pas suffisants, il est possible d'en ajouter de nouveaux.
A noter néanmoins que cette document est incomplète et qu'il existe beaucoup de services de bases dans nuxeo. Je vous conseille de rechercher tous les extensions de PluggableRestletService dans les sources de nuxeo pour voir ce qui est disponible. En général le point d'extension est bien documenté.Exemple :
<documentation> Create a File document via upload POST /nuxeo/restAPI/{repoId}/{docId}/{filename}/upload </documentation> <restletPlugin name="upload" class="org.nuxeo.ecm.platform.ui.web.restAPI.UploadRestlet" enabled="true" useSeam="true"> <urlPatterns> <urlPattern>/{repo}/{docid}/{filename}/upload</urlPattern> </urlPatterns> </restletPlugin>
Il est aussi possible d'utiliser/crée des services REST de/via WebEngine mais ici je me suis limité à utiliser ceux de nuxeo DM
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>fr.univrennes1.testCMIS</groupId> <artifactId>testREST</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>testCMIS</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> <version>1.1.1</version> </dependency> </dependencies> </project>
package fr.univrennes1.testREST; import java.io.File; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthState; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.ClientContext; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; public class Rest { public static void main( String[] args ) throws IOException, DocumentException { //************* diverses initialisations ************* Integer port = 8080; String host = "localhost"; String baseURL = "http://" + host + ":" + port + "/nuxeo/restAPI/default/"; UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("Administrator", "Administrator"); AuthScope authScope = new AuthScope(host, port); String url = null; String rep = null; //91ea0088-4545-41cd-a43e-22ce4c1aefda pour le workspace testRB String WorkspaceID = "83641c01-c9d4-4bee-a7ff-72c1a9fd051a"; //************* Suppression de Dossier1 ************* //GET /nuxeo/restAPI/{repoId}/deleteDocumentByPath?path=/default-domain/workspaces/doc1 url = baseURL + "deleteDocumentByPath?path=/default-domain/workspaces/testrb/dossier1"; getUrl(credentials, authScope, url); //************* création du dossier "Dossier1" ************* //GET /nuxeo/restAPI/{repo}/{parentdocid}/createDocument?docType=File url = baseURL + WorkspaceID + "/createDocument?docType=Folder&dublincore%3Atitle=Dossier1"; rep = getUrl(credentials, authScope, url); Document document = DocumentHelper.parseText(rep); String FolderID = document.selectSingleNode("/document/docRef").getText(); //************* création du fichier "Fichier1" ************* url = baseURL + FolderID + "/createDocument?docType=File&dublincore%3Atitle=Fichier1"; rep = getUrl(credentials, authScope, url); document = DocumentHelper.parseText(rep); String FileID = document.selectSingleNode("/document/docRef").getText(); //************* upload du contenu ************* //POST /nuxeo/restAPI/{repoId}/{docId}/{filename}/upload url = baseURL + FileID + "/metro.pdf/upload"; File targetFile = new File( "/A_GARDER_UN_PEU/nuxeo-dev/workspace/testCMIS/src/main/resources/metro.pdf" ); FileBody bin = new FileBody(targetFile); StringBody comment = new StringBody("metro.pdf"); MultipartEntity reqEntity = new MultipartEntity(); reqEntity.addPart("bin", bin); reqEntity.addPart("comment", comment); reqEntity.addPart("name", comment); HttpPost filePost = new HttpPost(url); filePost.setEntity(reqEntity); DefaultHttpClient httpclient = new DefaultHttpClient(); httpclient.getCredentialsProvider().setCredentials(authScope, credentials); BasicHttpContext localcontext = new BasicHttpContext(); // Generate BASIC scheme object and stick it to the local // execution context BasicScheme basicAuth = new BasicScheme(); localcontext.setAttribute("preemptive-auth", basicAuth); // Add as the first request interceptor httpclient.addRequestInterceptor(new PreemptiveAuth(), 0); ResponseHandler<String> responseHandler = new BasicResponseHandler(); rep = httpclient.execute(filePost, responseHandler, localcontext); System.out.println("**********************************"); System.out.println("url = " + url); System.out.println(rep); httpclient.getConnectionManager().shutdown(); } /** * @param credentials * @param authScope * @param url * @throws IOException * @throws ClientProtocolException */ private static String getUrl(UsernamePasswordCredentials credentials, AuthScope authScope, String url) throws IOException, ClientProtocolException { String ret = null; HttpGet httpget = new HttpGet(url); DefaultHttpClient httpclient = new DefaultHttpClient(); httpclient.getCredentialsProvider().setCredentials(authScope, credentials); BasicHttpContext localcontext = new BasicHttpContext(); // Generate BASIC scheme object and stick it to the local // execution context BasicScheme basicAuth = new BasicScheme(); localcontext.setAttribute("preemptive-auth", basicAuth); // Add as the first request interceptor httpclient.addRequestInterceptor(new PreemptiveAuth(), 0); ResponseHandler<String> responseHandler = new BasicResponseHandler(); ret = httpclient.execute(httpget, responseHandler, localcontext); System.out.println("**********************************"); System.out.println("url = " + url); System.out.println(ret); httpclient.getConnectionManager().shutdown(); return ret; } static class PreemptiveAuth implements HttpRequestInterceptor { public void process( final HttpRequest request, final HttpContext context) throws HttpException, IOException { AuthState authState = (AuthState) context.getAttribute( ClientContext.TARGET_AUTH_STATE); // If no auth scheme avaialble yet, try to initialize it preemptively if (authState.getAuthScheme() == null) { AuthScheme authScheme = (AuthScheme) context.getAttribute( "preemptive-auth"); CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute( ClientContext.CREDS_PROVIDER); HttpHost targetHost = (HttpHost) context.getAttribute( ExecutionContext.HTTP_TARGET_HOST); if (authScheme != null) { Credentials creds = credsProvider.getCredentials( new AuthScope( targetHost.getHostName(), targetHost.getPort())); if (creds == null) { throw new HttpException("No credentials for preemptive authentication"); } authState.setAuthScheme(authScheme); authState.setCredentials(creds); } } } } }
Fichier1 est bien créé dans Dossier1. Par contre, metro.pdf n'est pas mis en tant que contenu de Fichier1 mais comme un nouveau fichier (de nom metro) dans le dossier Dossier1. Ceci ne semble pas cohérent avec ce que prévoit le service REST. A ce jour, une rapide analyse du code nuxeo ne m'a pas permis de comprendre pourquoi... Visiblement un pb de "Could not instantiate Seam component: pictureBookManager"
la classe PreemptiveAuth est utilisée pour passer le user/password dès la première requête. Ceci évite de passer les autre mécanismes d'authentification de nuxeo (invité et cas par exemple).