/* * (C) Copyright 2015-2016 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 */ package org.nuxeo.ecm.core.blob; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import javax.inject.Inject; import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; 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; import org.nuxeo.runtime.test.runner.RuntimeHarness; @RunWith(FeaturesRunner.class) @Features(BlobManagerFeature.class) @LocalDeploy("org.nuxeo.ecm.core.api:OSGI-INF/test-fs-blobprovider.xml") public class TestFilesystemBlobProvider { private static final String CONTENT = "hello"; private static final String CONTENT_MD5 = "5d41402abc4b2a76b9719d911017c592"; private static final String PROVIDER_ID = "testfs"; @Inject protected RuntimeHarness harness; @Inject protected BlobManager blobManager; protected Path tmpFile; protected String tmpFilePath; @Before public void setUp() throws Exception { tmpFile = Framework.createTempFilePath("tmp", ".txt"); try (OutputStream out = Files.newOutputStream(tmpFile)) { InputStream in = new ByteArrayInputStream(CONTENT.getBytes()); IOUtils.copy(in, out); } tmpFilePath = tmpFile.toString(); } @After public void tearDown() throws Exception { if (tmpFile != null && Files.exists(tmpFile)) { Files.delete(tmpFile); } } @Test public void testSupportsUserUpdate() throws Exception { BlobProvider blobProvider = blobManager.getBlobProvider(PROVIDER_ID); assertFalse(blobProvider.supportsUserUpdate()); // check that we can allow user updates of blobs by configuration harness.deployContrib("org.nuxeo.ecm.core.api.tests", "OSGI-INF/test-fs-blobprovider-override.xml"); try { blobProvider = blobManager.getBlobProvider(PROVIDER_ID); assertTrue(blobProvider.supportsUserUpdate()); } finally { harness.undeployContrib("org.nuxeo.ecm.core.api.tests", "OSGI-INF/test-fs-blobprovider-override.xml"); } } @Test public void testRead() throws Exception { String key = PROVIDER_ID + ":" + tmpFilePath; BlobInfo blobInfo = new BlobInfo(); blobInfo.key = key; BlobProvider blobProvider = blobManager.getBlobProvider(PROVIDER_ID); ManagedBlob blob = (ManagedBlob) blobProvider.readBlob(blobInfo); assertNotNull(blob); assertEquals(key, blob.getKey()); try (InputStream in = blob.getStream()) { assertEquals(CONTENT, IOUtils.toString(in)); } // same with explicit blob blobInfo.key = tmpFilePath; blobInfo.mimeType = "text/plain"; blob = ((FilesystemBlobProvider) blobProvider).createBlob(blobInfo); assertEquals(key, blob.getKey()); assertEquals(tmpFile.getFileName().toString(), blob.getFilename()); assertEquals("text/plain", blob.getMimeType()); assertEquals(CONTENT.length(), blob.getLength()); assertEquals(CONTENT_MD5, blob.getDigest()); try (InputStream in = blob.getStream()) { assertEquals(CONTENT, IOUtils.toString(in)); } } @Test public void testReadNotFound() throws Exception { String path = "/NO_SUCH_FILE_EXISTS"; assertFalse(Files.exists(Paths.get(path))); String key = PROVIDER_ID + ":" + path; BlobInfo blobInfo = new BlobInfo(); blobInfo.key = key; BlobProvider blobProvider = blobManager.getBlobProvider(PROVIDER_ID); ManagedBlob blob = (ManagedBlob) blobProvider.readBlob(blobInfo); try { blob.getStream(); fail("Should not be able to read non-existent file"); } catch (NoSuchFileException e) { // expected } } @Test public void testRoot() throws Exception { String PROVIDER_ID2 = "testfs2"; BlobProviderDescriptor descr = new BlobProviderDescriptor(); descr.klass = FilesystemBlobProvider.class; descr.name = PROVIDER_ID2; descr.properties = Collections.singletonMap(FilesystemBlobProvider.ROOT_PROP, tmpFile.getParent().toString()); ((BlobManagerComponent) blobManager).registerBlobProvider(descr); try { // use relative path under root String key = PROVIDER_ID2 + ":" + tmpFile.getFileName().toString(); BlobInfo blobInfo = new BlobInfo(); blobInfo.key = key; BlobProvider blobProvider = blobManager.getBlobProvider(PROVIDER_ID); ManagedBlob blob = (ManagedBlob) blobProvider.readBlob(blobInfo); assertNotNull(blob); assertEquals(key, blob.getKey()); try (InputStream in = blob.getStream()) { assertEquals(CONTENT, IOUtils.toString(in)); } } finally { ((BlobManagerComponent) blobManager).unregisterBlobProvider(descr); } } @Test public void testIllegalPath() throws Exception { String illegalPath = "../foo"; String PROVIDER_ID2 = "testfs2"; BlobProviderDescriptor descr = new BlobProviderDescriptor(); descr.klass = FilesystemBlobProvider.class; descr.name = PROVIDER_ID2; descr.properties = Collections.singletonMap(FilesystemBlobProvider.ROOT_PROP, tmpFile.getParent().toString()); ((BlobManagerComponent) blobManager).registerBlobProvider(descr); try { String key = PROVIDER_ID2 + ":" + illegalPath; BlobInfo blobInfo = new BlobInfo(); blobInfo.key = key; BlobProvider blobProvider = blobManager.getBlobProvider(PROVIDER_ID); ManagedBlob blob = (ManagedBlob) blobProvider.readBlob(blobInfo); assertNotNull(blob); assertEquals(key, blob.getKey()); try { blob.getStream(); fail("Should not be able to read file with illegal path"); } catch (FileNotFoundException e) { // ok } } finally { ((BlobManagerComponent) blobManager).unregisterBlobProvider(descr); } } }