JCLOUDS-941: Auto-detect filesystem Content-Type

When a filesystem blob does not have content metadata and when users
set jclouds.filesystem.auto-detect-content-type to tru, probe the file
type to return to clients.  This is useful when using jclouds to serve
an existing filesystem.
This commit is contained in:
Iván López 2015-06-21 12:37:27 +02:00 committed by Andrew Gaul
parent b8b20c16f5
commit 37a014ae00
5 changed files with 57 additions and 2 deletions

View File

@ -16,7 +16,10 @@
*/
package org.jclouds.filesystem;
import static org.jclouds.filesystem.reference.FilesystemConstants.PROPERTY_AUTO_DETECT_CONTENT_TYPE;
import java.net.URI;
import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.apis.internal.BaseApiMetadata;
@ -24,6 +27,7 @@ import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.filesystem.config.FilesystemBlobStoreContextModule;
import com.google.auto.service.AutoService;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
/**
* Implementation of {@link ApiMetadata} for jclouds Filesystem-based BlobStore
@ -44,6 +48,13 @@ public class FilesystemApiMetadata extends BaseApiMetadata {
super(builder);
}
@Override
public Properties getDefaultProperties() {
Properties properties = BaseHttpApiMetadata.defaultProperties();
properties.setProperty(PROPERTY_AUTO_DETECT_CONTENT_TYPE, "false");
return properties;
}
public static class Builder extends BaseApiMetadata.Builder<Builder> {
protected Builder() {
@ -55,6 +66,7 @@ public class FilesystemApiMetadata extends BaseApiMetadata {
.defaultCredential("bar")
.version("1")
.documentation(URI.create("http://www.jclouds.org/documentation/userguide/blobstore-guide"))
.defaultProperties(FilesystemApiMetadata.defaultProperties())
.view(BlobStoreContext.class)
.defaultModule(FilesystemBlobStoreContextModule.class);
}

View File

@ -24,6 +24,9 @@ public final class FilesystemConstants {
/** Specify the base directory where provider starts its file operations - must exists */
public static final String PROPERTY_BASEDIR = "jclouds.filesystem.basedir";
/** Specify if the Content-Type of a file should be autodetected if it is not set */
public static final String PROPERTY_AUTO_DETECT_CONTENT_TYPE = "jclouds.filesystem.auto-detect-content-type";
private FilesystemConstants() {
throw new AssertionError("intentionally unimplemented");
}

View File

@ -21,6 +21,7 @@ import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.io.BaseEncoding.base16;
import static java.nio.file.Files.getFileAttributeView;
import static java.nio.file.Files.getPosixFilePermissions;
import static java.nio.file.Files.probeContentType;
import static java.nio.file.Files.readAttributes;
import static java.nio.file.Files.setPosixFilePermissions;
import static org.jclouds.filesystem.util.Utils.isPrivate;
@ -108,16 +109,19 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
protected final Provider<BlobBuilder> blobBuilders;
protected final String baseDirectory;
protected final boolean autoDetectContentType;
protected final FilesystemContainerNameValidator filesystemContainerNameValidator;
protected final FilesystemBlobKeyValidator filesystemBlobKeyValidator;
@Inject
protected FilesystemStorageStrategyImpl(Provider<BlobBuilder> blobBuilders,
@Named(FilesystemConstants.PROPERTY_BASEDIR) String baseDir,
@Named(FilesystemConstants.PROPERTY_AUTO_DETECT_CONTENT_TYPE) boolean autoDetectContentType,
FilesystemContainerNameValidator filesystemContainerNameValidator,
FilesystemBlobKeyValidator filesystemBlobKeyValidator) {
this.blobBuilders = checkNotNull(blobBuilders, "filesystem storage strategy blobBuilders");
this.baseDirectory = checkNotNull(baseDir, "filesystem storage strategy base directory");
this.autoDetectContentType = autoDetectContentType;
this.filesystemContainerNameValidator = checkNotNull(filesystemContainerNameValidator,
"filesystem container name validator");
this.filesystemBlobKeyValidator = checkNotNull(filesystemBlobKeyValidator, "filesystem blob key validator");
@ -335,6 +339,9 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
contentEncoding = readStringAttributeIfPresent(view, attributes, XATTR_CONTENT_ENCODING);
contentLanguage = readStringAttributeIfPresent(view, attributes, XATTR_CONTENT_LANGUAGE);
contentType = readStringAttributeIfPresent(view, attributes, XATTR_CONTENT_TYPE);
if (contentType == null && autoDetectContentType) {
contentType = probeContentType(file.toPath());
}
if (attributes.contains(XATTR_CONTENT_MD5)) {
ByteBuffer buf = ByteBuffer.allocate(view.size(XATTR_CONTENT_MD5));
view.read(XATTR_CONTENT_MD5, buf);

View File

@ -88,6 +88,7 @@ public class FilesystemBlobStoreTest {
// create context for filesystem container
Properties prop = new Properties();
prop.setProperty(FilesystemConstants.PROPERTY_BASEDIR, TestUtils.TARGET_BASE_DIR);
prop.setProperty(FilesystemConstants.PROPERTY_AUTO_DETECT_CONTENT_TYPE, "false");
context = ContextBuilder.newBuilder(PROVIDER).overrides(prop).build(BlobStoreContext.class);
// create a container in the default location
blobStore = context.getBlobStore();

View File

@ -84,7 +84,7 @@ public class FilesystemStorageStrategyImplTest {
return new BlobBuilderImpl();
}
}, TestUtils.TARGET_BASE_DIR, new FilesystemContainerNameValidatorImpl(), new FilesystemBlobKeyValidatorImpl());
}, TestUtils.TARGET_BASE_DIR, false, new FilesystemContainerNameValidatorImpl(), new FilesystemBlobKeyValidatorImpl());
TestUtils.cleanDirectoryContent(TestUtils.TARGET_BASE_DIR);
TestUtils.createResources();
}
@ -369,6 +369,38 @@ public class FilesystemStorageStrategyImplTest {
blobKey.substring(0, blobKey.length() - 1)));
}
public void testGetBlobContentType_AutoDetect_True() throws IOException {
FilesystemStorageStrategyImpl storageStrategyAutoDetectContentType = new FilesystemStorageStrategyImpl(
new Provider<BlobBuilder>() {
@Override
public BlobBuilder get() {
return new BlobBuilderImpl();
}
}, TestUtils.TARGET_BASE_DIR, true, new FilesystemContainerNameValidatorImpl(), new FilesystemBlobKeyValidatorImpl());
String blobKey = TestUtils.createRandomBlobKey("file-", ".jpg");
TestUtils.createBlobsInContainer(CONTAINER_NAME, blobKey);
Blob blob = storageStrategyAutoDetectContentType.getBlob(CONTAINER_NAME, blobKey);
assertEquals(blob.getMetadata().getContentMetadata().getContentType(), "image/jpeg");
blobKey = TestUtils.createRandomBlobKey("file-", ".pdf");
TestUtils.createBlobsInContainer(CONTAINER_NAME, blobKey);
blob = storageStrategyAutoDetectContentType.getBlob(CONTAINER_NAME, blobKey);
assertEquals(blob.getMetadata().getContentMetadata().getContentType(), "application/pdf");
blobKey = TestUtils.createRandomBlobKey("file-", ".mp4");
TestUtils.createBlobsInContainer(CONTAINER_NAME, blobKey);
blob = storageStrategyAutoDetectContentType.getBlob(CONTAINER_NAME, blobKey);
assertEquals(blob.getMetadata().getContentMetadata().getContentType(), "video/mp4");
}
public void testGetBlobContentType_AutoDetect_False() throws IOException {
String blobKey = TestUtils.createRandomBlobKey("file-", ".jpg");
TestUtils.createBlobsInContainer(CONTAINER_NAME, blobKey);
Blob blob = storageStrategy.getBlob(CONTAINER_NAME, blobKey);
assertEquals(blob.getMetadata().getContentMetadata().getContentType(), null);
}
public void testListDirectoryBlob() throws IOException {
String blobKey = TestUtils.createRandomBlobKey("directory-", File.separator);
Blob blob = storageStrategy.newBlob(blobKey);
@ -477,7 +509,7 @@ public class FilesystemStorageStrategyImplTest {
public BlobBuilder get() {
return new BlobBuilderImpl();
}
}, absoluteBasePath, new FilesystemContainerNameValidatorImpl(), new FilesystemBlobKeyValidatorImpl());
}, absoluteBasePath, false, new FilesystemContainerNameValidatorImpl(), new FilesystemBlobKeyValidatorImpl());
TestUtils.cleanDirectoryContent(absoluteContainerPath);
String blobKey;