/**
* Copyright (C) 2009-2015 Dell, Inc
* See annotations for authorship information
*
* ====================================================================
* 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.
* ====================================================================
*/
package org.dasein.cloud.joyent.storage;
import com.joyent.manta.client.MantaClient;
import com.joyent.manta.client.MantaObject;
import com.joyent.manta.exception.MantaClientHttpResponseException;
import com.joyent.manta.exception.MantaCryptoException;
import com.joyent.manta.exception.MantaObjectException;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.dasein.cloud.*;
import org.dasein.cloud.identity.ServiceAction;
import org.dasein.cloud.joyent.SmartDataCenter;
import org.dasein.cloud.storage.*;
import org.dasein.cloud.util.CacheLevel;
import org.dasein.cloud.util.NamingConstraints;
import org.dasein.util.uom.storage.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.*;
import java.util.*;
/**
* @author ilya.drabenia
* @author anton.karavaev
*/
/**
* Manta Object Store through Dasein vocabulary:
* -- Bucket - directory
* -- Object - file in the directory
* -- Buckets can be nested - subdirectories
* -- Root Objects are supported - root directory can contain files
*/
public class Manta extends AbstractBlobStoreSupport<SmartDataCenter> {
public static final String CUSTOM_PROP_STORAGE_URL = "storageUrl";
private static final Logger logger = SmartDataCenter.getLogger(MantaStorageServices.class, "std");
private MantaClient mantaClient;
private String rootPath;
private String publicPath;
public Manta( SmartDataCenter provider ) throws IOException, CloudException {
super(provider);
}
private transient volatile MantaCapabilities capabilities;
@Override
public BlobStoreCapabilities getCapabilities() throws CloudException, InternalException{
if(capabilities == null){
capabilities = new MantaCapabilities(getProvider());
}
return capabilities;
}
/**
* Check if context is set and try to initialise the Manta client and working paths
* FIXME: refactor this method to a class encapsulating mantaClient and the paths to remove coupling
* @throws CloudException
*/
private void checkContext() throws CloudException, InternalException {
ProviderContext ctx = getProvider().getContext();
if( ctx == null ) {
throw new InternalException("No context has been established for this request");
}
if( mantaClient == null ) {
try {
mantaClient = getClient();
}
catch( IOException e ) {
throw new CloudException("Unable to initialise Manta client", e);
}
rootPath = "/" + ctx.getAccountNumber() + "/stor";
publicPath = "/" + ctx.getAccountNumber() + "/public";
}
}
private MantaClient getClient() throws CloudException, IOException {
List<ContextRequirements.Field> fields = getProvider().getContextRequirements().getConfigurableValues();
String keyName = "";
String privateKey = "";
char[] keyPassword = null;
for( ContextRequirements.Field f : fields ) {
if( f.type.equals(ContextRequirements.FieldType.KEYPAIR) ) {
byte[][] keyPair = ( byte[][] ) getProvider().getContext().getConfigurationValue(f);
keyName = new String(keyPair[0], "utf-8");
privateKey = new String(keyPair[1], "utf-8");
}
else if( f.type.equals(ContextRequirements.FieldType.PASSWORD) ) {
byte[] password = ( byte[] ) getProvider().getContext().getConfigurationValue(f);
if( password != null ) {
keyPassword = new String(password, "utf-8").toCharArray();
}
}
}
return MantaClient.newInstance(getProvider().getContext().getCustomProperties().getProperty(CUSTOM_PROP_STORAGE_URL), getProvider().getContext().getAccountNumber(), privateKey, keyName, keyPassword);
}
/**
* Manta supports directories with sub-directories in /:login/stor or /:login/public.
*
*
* @throws CloudException
* @throws InternalException
* @return
*/
@Override
public boolean allowsNestedBuckets() throws CloudException, InternalException {
return true;
}
/**
* Manta does not support objects on root level. However, user must specify one of two available storage folders:
* /:login/stor or /:login/public which will be used as a root level.
*
* @throws CloudException
* @throws InternalException
* @return
*/
@Override
public boolean allowsRootObjects() throws CloudException, InternalException {
return true;
}
/**
* Manta allow public sharing using directory /:login/public
*
* @return
* @throws CloudException
* @throws InternalException
*/
@Override
public boolean allowsPublicSharing() throws CloudException, InternalException {
return true;
}
/**
* Manta deletes directory with content.
*
* @param bucket directory path
* @throws CloudException
* @throws InternalException
*/
@Override
public void clearBucket(@Nonnull String bucket) throws CloudException, InternalException {
checkContext();
String path = toStoragePath(bucket, null, !isPublic(bucket, null));
boolean retryRecursively = false;
try {
mantaClient.delete(path);
} catch (MantaCryptoException e) {
throw new CloudException(e);
} catch (IOException e) {
retryRecursively = true;
logger.debug("Directory is not empty. Delete recursively.", e);
} catch( MantaClientHttpResponseException e ) {
retryRecursively = true;
logger.debug("Directory is not empty. Delete recursively.", e);
}
if( retryRecursively ) {
// if bucket is not empty remove recursively
try {
mantaClient.deleteRecursive(path);
} catch( MantaCryptoException e ) {
throw new CloudException(e);
} catch( IOException e ) {
throw new CloudException(e);
} catch( MantaClientHttpResponseException e ) {
throw new CloudException(e);
}
}
}
/**
* Manta creates new directory.
*
* @param bucket directory path
* @param findFreeName is not supported and ignored
* @return cloud storage object
* @throws InternalException
* @throws CloudException
*/
@Nonnull
@Override
public Blob createBucket(@Nonnull String bucket, boolean findFreeName) throws InternalException, CloudException {
checkContext();
try {
mantaClient.putDirectory(toStoragePath(bucket, null, true), null);
} catch (IOException e) {
throw new CloudException(e);
} catch (MantaCryptoException e) {
throw new CloudException(e);
} catch( MantaClientHttpResponseException e ) {
throw new CloudException(e);
}
return Blob.getInstance(getProvider().getContext().getRegionId(), "", bucket, new Date().getTime());
}
/**
* Checks if bucket exists. Gets directory metadata, if anything returned, bucket exists.
*
* @param bucket directory path
* @return true if bucket exists, false otherwise
* @throws InternalException
* @throws CloudException
*/
@Override
public boolean exists(@Nonnull String bucket) throws InternalException, CloudException {
checkContext();
return getMantaObjectMetadata(bucket, null, true) != null
|| getMantaObjectMetadata(bucket, null, false) != null;
}
// private boolean checkMantaPathExists( @Nonnull String path ) throws InternalException, CloudException {
// try {
// mantaClient.head(path);
// return true;
// } catch (MantaCryptoException e) {
// throw new CloudException(e);
// } catch (MantaClientHttpResponseException e) {
// if (e.getStatusCode() != HttpStatus.SC_NOT_FOUND) {
// if (e.getStatusCode() != HttpStatus.SC_FORBIDDEN) {
// throw new CloudException(e);
// }
// }
// } catch (IOException e) {
// throw new CloudException(e);
// }
// return false;
// }
/**
* Returns {@link Blob} representation of Manta directory. Null if a bucket name is not a directory or a bucket not found
*
* @param bucketName directory path
*
* @return {@link Blob} representation of Manta directory
*
* @throws InternalException
* @throws CloudException
*/
@Override
public @Nullable Blob getBucket(@Nonnull String bucketName) throws InternalException, CloudException {
checkContext();
Blob bucket = null;
// check private bucket first
MantaObject mantaObject = getMantaObjectMetadata(bucketName, null);
if( mantaObject == null ) { // this is 404
return null;
}
if (isDirectory(mantaObject)) {
bucket = Blob.getInstance(getProvider().getContext().getRegionId(), "", bucketName, new Date().getTime());
}
return bucket;
}
/**
* {@link com.joyent.manta.client.MantaObject#isDirectory()} works only after listObjects(String path) method.
*
* @param mantaObject object with content type header
* @return
*/
private boolean isDirectory(@Nonnull MantaObject mantaObject) {
return mantaObject.getHttpHeaders().getContentType().equals(MantaObject.DIRECTORY_HEADER);
}
/**
* {@link com.joyent.manta.client.MantaObject#getContentLength()} works only after listObjects(String path) method.
* Returns Double for convenient usage with {@link Storage}.
*
* @param mantaObject object with content
* @return
*/
private Double getContentLength(@Nonnull MantaObject mantaObject) {
return mantaObject.getHttpHeaders().getContentLength().doubleValue();
}
/**
* Returns {@link Blob} representation of {@link MantaObject}.
*
* @param bucketName directory path
* @param objectName object name
*
* @return {@link Blob} representation of {@link MantaObject}.
*
* @throws InternalException
* @throws CloudException
*/
@Override
public @Nullable Blob getObject(@Nullable String bucketName, @Nonnull String objectName)
throws InternalException, CloudException {
checkContext();
checkBucket(bucketName);
MantaObject mantaObject = getMantaObjectMetadata(bucketName, objectName);
if(mantaObject == null) { // this is 404
return null;
}
return Blob.getInstance(getProvider().getContext().getRegionId(), "", bucketName, objectName, new Date().getTime(),
new Storage<org.dasein.util.uom.storage.Byte>(getContentLength(mantaObject), Storage.BYTE));
}
/**
* Returns {@link Storage} of {@link MantaObject}.
*
* @param bucketName directory path
* @param objectName object name
* @return {@link Storage} of {@link MantaObject}
* @throws InternalException
* @throws CloudException
*/
@Override
public @Nullable Storage<org.dasein.util.uom.storage.Byte> getObjectSize(@Nullable String bucketName,
@Nullable String objectName)
throws InternalException, CloudException {
checkContext();
checkBucket(bucketName);
Storage<org.dasein.util.uom.storage.Byte> storage = null;
if (objectName != null) {
MantaObject mantaObject = getMantaObjectMetadata(bucketName, objectName);
if(mantaObject != null) {
storage = new Storage<org.dasein.util.uom.storage.Byte>(getContentLength(mantaObject), Storage.BYTE);
}
}
return storage;
}
/**
* Loads {@link MantaObject} without it`s content.
*
* @param bucket bucket name
* @param object object name
* @return Manta object
*/
private @Nullable MantaObject getMantaObjectMetadata( @Nullable String bucket, @Nullable String object, boolean isPrivate )
throws CloudException, InternalException {
try {
return mantaClient.head(toStoragePath(bucket, object, isPrivate));
} catch (MantaClientHttpResponseException e) {
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
return null;
}
throw new CloudException(e);
} catch (IOException e) {
throw new CloudException(e);
} catch (MantaCryptoException e) {
throw new InternalException(e);
}
}
private @Nullable MantaObject getMantaObjectMetadata( @Nullable String bucket, @Nullable String object) throws CloudException, InternalException {
MantaObject o = getMantaObjectMetadata(bucket, object, true);
if( o == null ) {
o = getMantaObjectMetadata(bucket, object, false);
}
return o;
}
/**
* According to this <a href=http://apidocs.joyent.com/manta/#directories>doc</a> there is no limit for directories
* and sub-directories.
*
* @return max directories
* @throws CloudException
* @throws InternalException
*/
@Override
public int getMaxBuckets() throws CloudException, InternalException {
return Integer.MAX_VALUE;
}
/**
* According to this <a href=http://apidocs.joyent.com/manta/#directories>doc</a> there is no limit for object size.
* @return max object size
* @throws InternalException
* @throws CloudException
*/
@Override
public Storage<org.dasein.util.uom.storage.Byte> getMaxObjectSize() throws InternalException, CloudException {
return new Storage<org.dasein.util.uom.storage.Byte>(Long.MAX_VALUE, Storage.BYTE);
}
/**
* According to this <a href=http://apidocs.joyent.com/manta/#directories>doc</a> Manta limits objects per single
* directory to 1,000,000.
*
* @return objects limit per single directory
* @throws CloudException
* @throws InternalException
*/
@Override
public int getMaxObjectsPerBucket() throws CloudException, InternalException {
return 1000000;
}
private final char[] BUCKET_CHARS = {'-', '.'};
@Override
public @Nonnull
NamingConstraints getBucketNameRules() throws CloudException, InternalException {
return NamingConstraints.getAlphaNumeric(1, 255).lowerCaseOnly().limitedToLatin1().constrainedBy(BUCKET_CHARS);
}
private final char[] OBJECT_CHARS = {'-', '.', ',', '#', '+'};
@Override
public @Nonnull NamingConstraints getObjectNameRules() throws CloudException, InternalException {
return NamingConstraints.getAlphaNumeric(1, 255).lowerCaseOnly().limitedToLatin1().constrainedBy(OBJECT_CHARS);
}
/**
* Provider term for bucket in Manta is "directory".
*
* @param locale
* @return
*/
@Nonnull
@Override
public String getProviderTermForBucket(@Nonnull Locale locale) {
return "directory";
}
/**
*
* @param locale
* @return
*/
@Nonnull
@Override
public String getProviderTermForObject(@Nonnull Locale locale) {
return "object";
}
/**
* Manta public storage is located in /:login/public/ directory.
*
* @param bucket directory path
* @param object object name is not used since manta checks only directory path
* @return is the storage public or not
* @throws CloudException
* @throws InternalException
*/
@Override
public boolean isPublic(@Nullable String bucket, @Nullable String object) throws CloudException, InternalException {
checkContext();
return getMantaObjectMetadata(bucket, object, false) != null;
}
/**
* Method check if access to cloud is available
*
* @return
* @throws CloudException
* @throws InternalException
*/
@Override
public boolean isSubscribed() throws CloudException, InternalException {
checkContext();
org.dasein.cloud.util.Cache<Boolean> cache = org.dasein.cloud.util.Cache.getInstance(getProvider(), "Blob.isSubscribed", Boolean.class, CacheLevel.REGION_ACCOUNT);
final Iterable<Boolean> cachedIsSubscribed = cache.get(getProvider().getContext());
if (cachedIsSubscribed != null && cachedIsSubscribed.iterator().hasNext()) {
final Boolean isSubscribed = cachedIsSubscribed.iterator().next();
if (isSubscribed != null) {
return isSubscribed;
}
}
try {
mantaClient.listObjects(rootPath);
cache.put(getProvider().getContext(), Collections.singleton(true));
return true;
} catch (MantaClientHttpResponseException ex) {
if (ex.getStatusCode() == HttpStatus.SC_FORBIDDEN) {
cache.put(getProvider().getContext(), Collections.singleton(false));
return false;
}
throw new CloudException(ex);
} catch (Exception ex) {
throw new CloudException(ex);
}
}
@Nonnull
@Override
public Iterable<Blob> list(@Nullable String bucket) throws CloudException, InternalException {
checkContext();
checkBucket(bucket);
Collection<MantaObject> mantaObjects;
Collection<Blob> result = new ArrayList<Blob>();
try {
mantaObjects = mantaClient.listObjects(toStoragePath(bucket, null, !isPublic(bucket, null)));
} catch (MantaCryptoException e) {
throw new CloudException(e);
} catch (IOException e) {
throw new CloudException(e);
} catch (MantaObjectException e) {
throw new CloudException(e);
} catch( MantaClientHttpResponseException e ) {
throw new CloudException(e);
}
for (MantaObject mantaObject : mantaObjects) {
if (mantaObject.isDirectory()) {
result.add(Blob.getInstance(getProvider().getContext().getRegionId(), "", bucket, new Date().getTime()));
} else {
String objectName = parseObjectName(mantaObject.getPath());
result.add(Blob.getInstance(getProvider().getContext().getRegionId(), "", bucket, objectName, new Date().getTime(),
new Storage<org.dasein.util.uom.storage.Byte>(mantaObject.getContentLength(), Storage.BYTE)
));
}
}
return result;
}
/**
* Manta has to move directory to /:login/public to make directory public. It violates Dasein rules.
* Method throws {@link OperationNotSupportedException}.
*
* @param bucket
* @throws InternalException
* @throws CloudException
*/
@Override
public void makePublic(@Nonnull String bucket) throws InternalException, CloudException {
throw new OperationNotSupportedException("Not supported yet");
}
/**
* Manta has to move directory to /:login/public to make directory public. It violates Dasein rules.
* Method throws {@link OperationNotSupportedException}.
*
* @param bucket Manta does not support buckets. This parameter is ignored.
* @param object
* @throws InternalException
* @throws CloudException
*/
@Override
public void makePublic(@Nullable String bucket, @Nonnull String object) throws InternalException, CloudException {
throw new OperationNotSupportedException("Not supported yet");
}
/**
* Manta does not support buckets. Method throws {@link OperationNotSupportedException}.
*
* @param fromBucket
* @param objectName
* @param toBucket
* @throws InternalException
* @throws CloudException
*/
@Override
public void move(@Nullable String fromBucket, @Nullable String objectName, @Nullable String toBucket) throws
InternalException, CloudException {
throw new OperationNotSupportedException("Manta does not have support of buckets");
}
/**
* Deletes directory with contents.
*
* @param bucket path
* @throws CloudException
* @throws InternalException
*/
@Override
public void removeBucket(@Nonnull String bucket) throws CloudException, InternalException {
checkContext();
boolean retryRecursively = false;
String path = toStoragePath(bucket, null, !isPublic(bucket, null));
try {
mantaClient.delete(path);
} catch (MantaCryptoException e) {
throw new CloudException(e);
} catch (IOException e) {
retryRecursively = true;
logger.debug("Directory is not empty. Delete recursively.", e);
} catch( MantaClientHttpResponseException e ) {
retryRecursively = true;
logger.debug("Directory is not empty. Delete recursively.", e);
}
if( retryRecursively ) {
// if bucket is not empty remove recursively
try {
mantaClient.deleteRecursive(path);
} catch (MantaCryptoException ex) {
throw new CloudException(ex);
} catch (MantaClientHttpResponseException ex) {
throw new CloudException(ex);
} catch (IOException ex) {
throw new CloudException(ex);
}
}
}
/**
* Method remove file.
*
* @param bucket Path to directory. Null is not supported
* @param object Manta object name
* @throws CloudException
* @throws InternalException
*/
@Override
public void removeObject(@Nullable String bucket, @Nonnull String object) throws CloudException, InternalException {
checkContext();
checkBucket(bucket);
try {
mantaClient.delete(toStoragePath(bucket, object, !isPublic(bucket, object)));
} catch (MantaCryptoException e) {
throw new CloudException(e);
} catch (IOException e) {
throw new CloudException(e);
} catch( MantaClientHttpResponseException e ) {
throw new CloudException(e);
}
}
/**
* Manta does not support directory linking. Method throws {@link OperationNotSupportedException}.
*
* @param oldName
* @param newName
* @param findFreeName
* @return
* @throws CloudException
* @throws InternalException
*/
@Nonnull
@Override
public String renameBucket(@Nonnull String oldName, @Nonnull String newName, boolean findFreeName) throws
CloudException, InternalException {
throw new OperationNotSupportedException("Not supported yet");
}
/**
* Method rename object. It creates hard link and remove original link to file.
*
* @param bucket directory path
* @param oldName old object name
* @param newName new object name
* @throws CloudException
* @throws InternalException
*/
@Override
public void renameObject(@Nullable String bucket, @Nonnull String oldName, @Nonnull String newName) throws
CloudException, InternalException {
checkContext();
String path = toStoragePath(bucket, oldName, !isPublic(bucket, oldName));
String linkPath = path + parseObjectName(newName);
String objPath = path + parseObjectName(oldName);
try {
mantaClient.putSnapLink(linkPath, objPath, null);
mantaClient.delete(objPath);
} catch (MantaCryptoException e) {
throw new CloudException(e);
} catch (IOException e) {
throw new CloudException(e);
} catch( MantaClientHttpResponseException e ) {
throw new CloudException(e);
}
}
/**
* Method uploads {@code sourceFile} to Manta {@code bucket} with {@code objectName}.
*
* @param sourceFile file that will be uploaded
* @param bucket path to Manta object. Null means root and not supported by Manta {@link Manta#allowsRootObjects}.
* @param objectName Manta object name
* @return representation of uploaded file
* @throws CloudException
* @throws InternalException
*/
@Nonnull
@Override
public Blob upload(@Nonnull File sourceFile, @Nullable String bucket, @Nonnull String objectName) throws
CloudException, InternalException {
checkContext();
if( bucket == null ) {
bucket = "";
}
String validObjectName = parseObjectName(objectName);
put(bucket, objectName, sourceFile);
return Blob.getInstance(getProvider().getContext().getRegionId(), "", bucket, validObjectName , new Date().getTime(),
new Storage<org.dasein.util.uom.storage.Byte>(sourceFile.length(), Storage.BYTE));
}
//TODO: remove, root objects ARE supported by Manta
private void checkBucket(@Nullable String bucket) throws OperationNotSupportedException {
// if (bucket == null || bucket.trim().isEmpty()) {
// throw new OperationNotSupportedException("Root objects are not supported");
// }
}
// /**
// * Makes path a Manta private storage directory path.
// *
// * @param path directory path
// * @return Manta directory path
// */
// private @Nonnull String coerceToDirectory(@Nonnull String path) {
// if( path == null ) {
// path = "";
// }
// String pathToDir = path.trim();
// if (!pathToDir.startsWith(rootPath)) {
// pathToDir = rootPath + "/" + pathToDir;
// }
// if (!pathToDir.endsWith("/")) {
// pathToDir += "/";
// }
// return pathToDir;
// }
private @Nonnull String toPath(@Nullable String bucket, @Nullable String object) {
String path = "/";
if( bucket != null ) {
path += bucket;
}
if( object != null ) {
if( !path.endsWith("/") && !object.startsWith("/")) {
path += "/";
}
path += object;
}
return path;
}
private @Nonnull String toStoragePath(@Nullable String bucket, @Nullable String object, boolean isPrivate) {
if( isPrivate ) {
return rootPath + toPath(bucket, object);
}
else {
return publicPath + toPath(bucket, object);
}
}
/**
* Returns path without object name.
*
* @param objectName full path
* @return directory path
*/
private @Nonnull String parsePath(@Nonnull String objectName) {
return objectName.substring(0, objectName.lastIndexOf('/') + 1);
}
/**
* Returns object name without path.
*
* @param path full path
* @return object name
*/
private @Nonnull String parseObjectName(@Nonnull String path) {
return path.substring(path.lastIndexOf('/') + 1);
}
// /**
// * Method download file {@code objectName} from Manta to file {@code toFile}. Action occurs asynchronous.
// * @param bucket Manta does not support buckets. This parameter is ignored.
// * @param objectName
// * @param toFile
// *
// * @return
// *
// * @throws InternalException
// * @throws CloudException
// */
// @Override
// public FileTransfer download(final @Nullable String bucket, @Nonnull final String objectName, final @Nonnull File toFile)
// throws InternalException, CloudException {
// checkBucket(bucket);
// final FileTransfer fileTransfer = new FileTransfer();
//
// new Thread(new Runnable() {
// @Override
// public void run() {
// try {
// processDownloadAsync(fileTransfer, toStoragePath(bucket, objectName, !isPublic(bucket, objectName)), toFile);
// } catch (Exception ex) {
// logger.error("Error on file download from Manta Storage", ex);
// fileTransfer.complete(ex);
// }
// }
// }).start();
//
// return fileTransfer;
// }
@Override
protected void get( @Nullable String bucket, @Nonnull String object, @Nonnull File toFile, @Nullable FileTransfer transfer ) throws InternalException, CloudException {
checkContext();
try {
MantaObject mantaObject = mantaClient.get(toStoragePath(bucket, object, !isPublic(bucket, object)));
FileUtils.copyInputStreamToFile(mantaObject.getDataInputStream(), toFile);
}
catch( MantaCryptoException e ) {
throw new CloudException(e);
}
catch( MantaClientHttpResponseException e ) {
throw new CloudException(e);
}
catch( IOException e ) {
throw new CloudException(e);
}
}
@Override
protected void put( @Nullable String bucket, @Nonnull String objectName, @Nonnull File file ) throws InternalException, CloudException {
checkContext();
if( bucket == null ) {
bucket = "";
}
checkBucket(bucket);
String pathToDir = toStoragePath(bucket, null, true);
String validObjectName = parseObjectName(objectName);
try {
if (!exists(pathToDir)) {
createBucket(bucket, false);
}
MantaObject mantaObject = new MantaObject(pathToDir + "/" + validObjectName);
mantaObject.setDataInputFile(file);
mantaClient.put(mantaObject);
} catch (IOException e) {
throw new CloudException(e);
} catch (MantaCryptoException e) {
throw new CloudException(e);
} catch( MantaClientHttpResponseException e ) {
throw new CloudException(e);
}
}
@Override
protected void put( @Nullable String bucketName, @Nonnull String objectName, @Nonnull String content ) throws InternalException, CloudException {
checkContext();
if( bucketName == null ) {
bucketName = "";
}
checkBucket(bucketName);
String pathToDir = toStoragePath(bucketName, null, true);
String validObjectName = parseObjectName(objectName);
try {
if (!exists(pathToDir)) {
createBucket(bucketName, false);
}
MantaObject mantaObject = new MantaObject(pathToDir + "/" + validObjectName);
mantaObject.setDataInputString(content);
mantaClient.put(mantaObject);
} catch (IOException e) {
throw new CloudException(e);
} catch (MantaCryptoException e) {
throw new CloudException(e);
} catch( MantaClientHttpResponseException e ) {
throw new CloudException(e);
}
}
// private void processDownloadAsync(FileTransfer fileTransfer, String path, File toFile) throws IOException, MantaCryptoException, MantaClientHttpResponseException {
//
// // need to synchronize because variables in task is not synchronized properly
// synchronized (fileTransfer) {
// fileTransfer.setStartTime(new Date().getTime());
// fileTransfer.setPercentComplete(0);
// }
//
// MantaObject mantaObject = mantaClient.get(path);
// FileUtils.copyInputStreamToFile(mantaObject.getDataInputStream(), toFile);
//
// synchronized (fileTransfer) {
// fileTransfer.setPercentComplete(100);
// fileTransfer.setBytesToTransfer(0);
// fileTransfer.setBytesTransferred(getContentLength(mantaObject).longValue());
// fileTransfer.completeWithResult(toFile);
// }
//
// }
@Override
public String getSignedObjectUrl(@Nonnull String bucket, @Nonnull String object, @Nonnull String expiresEpochInSeconds) throws InternalException, CloudException{
throw new OperationNotSupportedException("Signed object URLs are not currently supported.");
}
@Nonnull
@Override
public String[] mapServiceAction(@Nonnull ServiceAction action) {
return new String[0]; //To change body of implemented methods use File | Settings | File Templates.
}
}