/*
* (C) Copyright 2006-2015 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Florent Guillaume, jcarsique
*/
package org.nuxeo.ecm.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collections;
import javax.inject.Inject;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.nuxeo.ecm.core.api.AbstractSession;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.Blobs;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.blob.BlobInfo;
import org.nuxeo.ecm.core.blob.BlobManager;
import org.nuxeo.ecm.core.model.Document;
import org.nuxeo.ecm.core.model.Session;
import org.nuxeo.ecm.core.blob.ManagedBlob;
import org.nuxeo.ecm.core.blob.SimpleManagedBlob;
import org.nuxeo.ecm.core.test.CoreFeature;
import org.nuxeo.ecm.core.test.annotations.Granularity;
import org.nuxeo.ecm.core.test.annotations.RepositoryConfig;
import org.nuxeo.runtime.api.Framework;
import org.nuxeo.runtime.test.runner.Features;
import org.nuxeo.runtime.test.runner.FeaturesRunner;
import org.nuxeo.runtime.test.runner.LocalDeploy;
/**
* Sample test showing how to use a direct access to the binaries storage.
*/
@RunWith(FeaturesRunner.class)
@Features(CoreFeature.class)
@RepositoryConfig(cleanup = Granularity.METHOD)
@LocalDeploy("org.nuxeo.ecm.core.test.tests:OSGI-INF/test-blob-dispatcher.xml")
public class TestBlobDispatcher {
@Inject
protected CoreSession session;
@Test
public void testDirectBlob() throws Exception {
DocumentModel doc1 = session.createDocumentModel("/", "doc1", "File");
DocumentModel doc2 = session.createDocumentModel("/", "doc1", "File");
doc1 = session.createDocument(doc1);
doc2 = session.createDocument(doc2);
Blob blob1 = Blobs.createBlob("foo", "text/plain");
doc1.setPropertyValue("file:content", (Serializable) blob1);
doc1 = session.saveDocument(doc1);
Blob blob2 = Blobs.createBlob("bar", "video/mp4");
doc2.setPropertyValue("file:content", (Serializable) blob2);
doc2 = session.saveDocument(doc2);
// re-fetch
doc1 = session.getDocument(doc1.getRef());
doc2 = session.getDocument(doc2.getRef());
blob1 = (Blob) doc1.getPropertyValue("file:content");
try (InputStream in = blob1.getStream()) {
assertEquals("foo", IOUtils.toString(in));
}
blob2 = (Blob) doc2.getPropertyValue("file:content");
try (InputStream in = blob2.getStream()) {
assertEquals("bar", IOUtils.toString(in));
}
}
@Test
public void testAlreadyManagedBlob() throws Exception {
// register blob in provider by hand
Blob b = Blobs.createBlob("foo", "video/mp4");
String key = Framework.getService(BlobManager.class).getBlobProvider("dummy").writeBlob(b);
key = "dummy:" + key;
// create a blob already managed and not corresponding to a dispatch target
DocumentModel doc = session.createDocumentModel("/", "doc", "File");
BlobInfo blobInfo = new BlobInfo();
blobInfo.key = key;
blobInfo.mimeType = "video/mp4";
Blob blob = new SimpleManagedBlob(blobInfo);
doc.setPropertyValue("file:content", (Serializable) blob);
doc = session.createDocument(doc);
// check that it wasn't dispatched even though the metadata would suggest it
blob = (Blob) doc.getPropertyValue("file:content");
assertTrue(blob.getClass().getName(), blob instanceof SimpleManagedBlob);
String key2 = ((ManagedBlob) blob).getKey();
assertEquals(key, key2);
}
@Test
public void testSwitchDispatch() throws Exception {
String foo = "foo";
String foo_test_key = "test:acbd18db4cc2f85cedef654fccc4a4d8";
String foo2_test_key = "test2:acbd18db4cc2f85cedef654fccc4a4d8";
// create a regular binary in the first blob provider
DocumentModel doc = session.createDocumentModel("/", "doc", "File");
Blob blob = Blobs.createBlob(foo, "text/plain");
doc.setPropertyValue("file:content", (Serializable) blob);
doc = session.createDocument(doc);
// check binary key
blob = (Blob) doc.getPropertyValue("file:content");
String key = ((ManagedBlob) blob).getKey();
assertEquals(foo_test_key, key);
// update the blob MIME type to change the dispatch target
blob.setMimeType("video/mp4");
doc.setPropertyValue("file:content", (Serializable) blob);
doc = session.saveDocument(doc);
// check that it was dispatched on save to the second blob provider
blob = (Blob) doc.getPropertyValue("file:content");
assertEquals(foo2_test_key, ((ManagedBlob) blob).getKey());
}
@Test
public void testSwitchDispatchOnChange() throws Exception {
String foo = "foo";
String foo_test_key = "test:acbd18db4cc2f85cedef654fccc4a4d8";
String foo2_test_key = "test2:acbd18db4cc2f85cedef654fccc4a4d8";
// create a regular binary in the first blob provider
DocumentModel doc = session.createDocumentModel("/", "doc", "File");
Blob blob = Blobs.createBlob(foo, "text/plain");
doc.setPropertyValue("file:content", (Serializable) blob);
doc = session.createDocument(doc);
// check binary key
blob = (Blob) doc.getPropertyValue("file:content");
String key = ((ManagedBlob) blob).getKey();
assertEquals(foo_test_key, key);
// update the dc:format to change the dispatch target
doc.setPropertyValue("dc:format", "video");
doc = session.saveDocument(doc);
// check that it was dispatched on save to the second blob provider
blob = (Blob) doc.getPropertyValue("file:content");
assertEquals(foo2_test_key, ((ManagedBlob) blob).getKey());
}
@Test
public void testSwitchDispatchOnLifeCycle() throws Exception {
String foo = "foo";
String foo_test_key = "test:acbd18db4cc2f85cedef654fccc4a4d8";
String foo2_test_key = "test2:acbd18db4cc2f85cedef654fccc4a4d8";
// create a regular binary in the first blob provider
DocumentModel doc = session.createDocumentModel("/", "doc", "File");
Blob blob = Blobs.createBlob(foo, "text/plain");
doc.setPropertyValue("file:content", (Serializable) blob);
doc = session.createDocument(doc);
// check binary key
blob = (Blob) doc.getPropertyValue("file:content");
String key = ((ManagedBlob) blob).getKey();
assertEquals(foo_test_key, key);
// change lifecycle to change the dispatch target
doc.followTransition("approve");
doc = session.saveDocument(doc);
// check that it was dispatched on save to the second blob provider
blob = (Blob) doc.getPropertyValue("file:content");
assertEquals(foo2_test_key, ((ManagedBlob) blob).getKey());
}
@Test
public void testDispatchXPath() throws Exception {
DocumentModel doc = session.createDocumentModel("/", "doc", "File");
doc = session.createDocument(doc);
Blob blob = Blobs.createBlob("foo", "text/plain");
doc.setPropertyValue("file:content", (Serializable) blob);
doc = session.saveDocument(doc);
// check binary key
blob = (Blob) doc.getPropertyValue("file:content");
String key = ((ManagedBlob) blob).getKey();
assertTrue(key, key.startsWith("test:"));
// files/0/file gets stored in the second blob provider
blob = Blobs.createBlob("bar", "text/plain");
doc.setPropertyValue("files:files",
(Serializable) Collections.singletonList(Collections.singletonMap("file", blob)));
doc = session.saveDocument(doc);
// check binary key
blob = (Blob) doc.getPropertyValue("files:files/0/file");
key = ((ManagedBlob) blob).getKey();
assertTrue(key, key.startsWith("test2:"));
}
// same with low-level Document API
// (has a different code path to compute the xpath)
@Test
public void testDispatchXPathOnDocument() throws Exception {
Session documentSession = ((AbstractSession) session).getSession();
Document root = documentSession.getRootDocument();
Document doc = root.addChild("doc", "File");
Blob blob = Blobs.createBlob("foo", "text/plain");
doc.setValue("content", blob);
// check binary key
blob = (Blob) doc.getValue("content");
String key = ((ManagedBlob) blob).getKey();
assertTrue(key, key.startsWith("test:"));
// files/0/file gets stored in the second blob provider
blob = Blobs.createBlob("bar", "text/plain");
doc.setValue("files", Collections.singletonList(Collections.singletonMap("file", blob)));
// check binary key
blob = (Blob) doc.getValue("files/0/file");
key = ((ManagedBlob) blob).getKey();
assertTrue(key, key.startsWith("test2:"));
}
}