Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.xiaomi.infra.galaxy.fds.client.GalaxyFDSClient Maven / Gradle / Ivy
package com.xiaomi.infra.galaxy.fds.client;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.LinkedListMultimap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.xiaomi.infra.galaxy.fds.bean.ThirdPartyObjectBean;
import com.xiaomi.infra.galaxy.fds.client.model.InitiateMultipartUploadRequest;
import com.xiaomi.infra.galaxy.fds.client.network.SSLConnectionInfoRecorderSocketFactory;
import com.xiaomi.infra.galaxy.fds.model.StorageClass;
import com.xiaomi.infra.galaxy.fds.client.model.FDSBucket;
import com.xiaomi.infra.galaxy.fds.client.model.FDSCopyObjectRequest;
import com.xiaomi.infra.galaxy.fds.client.model.FDSMd5InputStream;
import com.xiaomi.infra.galaxy.fds.client.model.FDSObject;
import com.xiaomi.infra.galaxy.fds.client.model.FDSObjectInputStream;
import com.xiaomi.infra.galaxy.fds.client.model.FDSObjectListing;
import com.xiaomi.infra.galaxy.fds.client.model.FDSObjectSummary;
import com.xiaomi.infra.galaxy.fds.client.model.FDSPutObjectRequest;
import com.xiaomi.infra.galaxy.fds.client.model.Owner;
import com.xiaomi.infra.galaxy.fds.model.ThirdPartyObject;
import com.xiaomi.infra.galaxy.fds.model.TimestampAntiStealingLinkConfig;
import com.xiaomi.infra.galaxy.fds.result.AccessControlPolicy;
import com.xiaomi.infra.galaxy.fds.result.CopyObjectResult;
import com.xiaomi.infra.galaxy.fds.result.InitMultipartUploadResult;
import com.xiaomi.infra.galaxy.fds.result.ListAllAuthorizedBucketsResult;
import com.xiaomi.infra.galaxy.fds.result.ListAllBucketsResult;
import com.xiaomi.infra.galaxy.fds.result.ListDomainMappingsResult;
import com.xiaomi.infra.galaxy.fds.result.ListObjectsResult;
import com.xiaomi.infra.galaxy.fds.result.PutObjectResult;
import com.xiaomi.infra.galaxy.fds.result.QuotaPolicy;
import com.xiaomi.infra.galaxy.fds.result.UploadPartResult;
import com.xiaomi.infra.galaxy.fds.result.UploadPartResultList;
import com.xiaomi.infra.galaxy.fds.result.VersionListing;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.DnsResolver;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SystemDefaultDnsResolver;
import org.apache.http.ssl.SSLContexts;
import org.json.JSONException;
import com.xiaomi.infra.galaxy.fds.Action;
import com.xiaomi.infra.galaxy.fds.Common;
import com.xiaomi.infra.galaxy.fds.SubResource;
import com.xiaomi.infra.galaxy.fds.auth.signature.SignAlgorithm;
import com.xiaomi.infra.galaxy.fds.auth.signature.Signer;
import com.xiaomi.infra.galaxy.fds.auth.signature.XiaomiHeader;
import com.xiaomi.infra.galaxy.fds.bean.BucketBean;
import com.xiaomi.infra.galaxy.fds.bean.GrantBean;
import com.xiaomi.infra.galaxy.fds.bean.GranteeBean;
import com.xiaomi.infra.galaxy.fds.bean.ObjectBean;
import com.xiaomi.infra.galaxy.fds.bean.OwnerBean;
import com.xiaomi.infra.galaxy.fds.client.credential.GalaxyFDSCredential;
import com.xiaomi.infra.galaxy.fds.client.exception.GalaxyException;
import com.xiaomi.infra.galaxy.fds.client.exception.GalaxyFDSClientException;
import com.xiaomi.infra.galaxy.fds.client.filter.FDSClientLogFilter;
import com.xiaomi.infra.galaxy.fds.client.filter.MetricsRequestFilter;
import com.xiaomi.infra.galaxy.fds.client.filter.MetricsResponseFilter;
import com.xiaomi.infra.galaxy.fds.client.metrics.ClientMetrics;
import com.xiaomi.infra.galaxy.fds.client.metrics.MetricsCollector;
import com.xiaomi.infra.galaxy.fds.client.network.ConnectionInfoRecorderSocketFactory;
import com.xiaomi.infra.galaxy.fds.client.network.Constants;
import com.xiaomi.infra.galaxy.fds.client.network.FDSBlackListEnabledHostChecker;
import com.xiaomi.infra.galaxy.fds.client.network.HttpContextUtil;
import com.xiaomi.infra.galaxy.fds.client.network.InternalIpBlackListRetryHandler;
import com.xiaomi.infra.galaxy.fds.client.network.InternalSiteBlackListDNSResolver;
import com.xiaomi.infra.galaxy.fds.client.network.RoundRobinDNSResolver;
import com.xiaomi.infra.galaxy.fds.client.network.ServiceUnavailableDNSBlackListStrategy;
import com.xiaomi.infra.galaxy.fds.client.network.TimeBasedIpAddressBlackList;
import com.xiaomi.infra.galaxy.fds.model.AccessControlList;
import com.xiaomi.infra.galaxy.fds.model.AccessLogConfig;
import com.xiaomi.infra.galaxy.fds.model.FDSObjectMetadata;
import com.xiaomi.infra.galaxy.fds.model.HttpMethod;
import com.xiaomi.infra.galaxy.fds.model.LifecycleConfig;
import com.xiaomi.infra.galaxy.fds.model.CORSConfiguration;
import com.xiaomi.infra.galaxy.fds.model.CORSConfiguration.CORSRule;
import javax.net.ssl.SSLContext;
public class GalaxyFDSClient implements GalaxyFDS {
public static final String ORG_ID_PARAM = "orgId";
private static final String VERSION_ID = "versionId";
private static final String ARCHIVE = "archive";
private final GalaxyFDSCredential credential;
private final FDSClientConfiguration fdsConfig;
private final DnsResolver dnsResolver;
private MetricsCollector metricsCollector;
private String delimiter = "/";
private final Random random = new Random();
private final String clientId = UUID.randomUUID().toString().substring(0, 8);
private HttpClient httpClient;
private FDSClientLogFilter logFilter = new FDSClientLogFilter();
private PoolingHttpClientConnectionManager connectionManager;
private static final Set retryMethodSet = new HashSet();
private BasicAuthCache authCache = null;
private CredentialsProvider credentialsProvider = null;
// TODO(wuzesheng) Make the authenticator configurable and let the
// authenticator supply sign algorithm and generate signature
private static SignAlgorithm SIGN_ALGORITHM = SignAlgorithm.HmacSHA1;
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
static {
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
retryMethodSet.add("getBucketAcl");
retryMethodSet.add("getObjectAcl");
retryMethodSet.add("getAccessLogConfig");
retryMethodSet.add("listNextBatchOfObjects");
retryMethodSet.add("listObjects");
retryMethodSet.add("listTrashObjects");
retryMethodSet.add("getObjectMetadata");
retryMethodSet.add("initMultipartUpload");
retryMethodSet.add("getLifecycleConfig");
retryMethodSet.add("listAuthorizedBuckets");
retryMethodSet.add("listBuckets");
retryMethodSet.add("listDomainMappings");
retryMethodSet.add("getMirror");
retryMethodSet.add("listNextBatchOfVersions");
retryMethodSet.add("listVersions");
retryMethodSet.add("doesBucketExist");
retryMethodSet.add("doesObjectExist");
retryMethodSet.add("prefetchObject");
retryMethodSet.add("refreshObject");
retryMethodSet.add("deleteDomainMapping");
retryMethodSet.add("deleteMirror");
retryMethodSet.add("deleteObjectAcl");
retryMethodSet.add("getBucket");
retryMethodSet.add("putDomainMapping");
retryMethodSet.add("setBucketAcl");
retryMethodSet.add("setMirror");
retryMethodSet.add("setObjectAcl");
retryMethodSet.add("setPublic");
retryMethodSet.add("updateAccessLogConfig");
retryMethodSet.add("updateLifecycleConfig");
}
private static final Log LOG = LogFactory.getLog(GalaxyFDSClient.class);
protected TimeBasedIpAddressBlackList ipBlackList;
protected InternalIpBlackListRetryHandler retryHandler;
public GalaxyFDSClient(GalaxyFDSCredential credential,
FDSClientConfiguration fdsConfig) {
this(credential, fdsConfig, null);
}
public GalaxyFDSClient(GalaxyFDSCredential credential,
FDSClientConfiguration fdsConfig,
DnsResolver dnsResolver) {
this.credential = credential;
this.fdsConfig = fdsConfig;
this.dnsResolver = dnsResolver;
init();
}
private void init() {
if (fdsConfig.isApacheConnectorEnabled()) {
LOG.warn("Apache Connector not supported");
}
httpClient = createHttpClient(this.fdsConfig);
if (fdsConfig.isMetricsEnabled()) {
metricsCollector = new MetricsCollector(this);
}
}
private HttpClient createHttpClient(FDSClientConfiguration config) {
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
.setConnectTimeout(config.getConnectionTimeoutMs())
.setSocketTimeout(config.getSocketTimeoutMs());
String proxyHost = config.getProxyHost();
int proxyPort = config.getProxyPort();
if (proxyHost != null && proxyPort > 0) {
HttpHost proxy = new HttpHost(proxyHost, proxyPort);
requestConfigBuilder.setProxy(proxy);
String proxyUsername = config.getProxyUsername();
String proxyPassword = config.getProxyPassword();
String proxyDomain = config.getProxyDomain();
String proxyWorkstation = config.getProxyWorkstation();
if (proxyUsername != null && proxyPassword != null) {
credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope(proxyHost, proxyPort), new NTCredentials(proxyUsername, proxyPassword, proxyWorkstation, proxyDomain));
authCache = new BasicAuthCache();
authCache.put(proxy, new BasicScheme());
}
}
RequestConfig requestConfig = requestConfigBuilder.build();
SocketConfig socketConfig = SocketConfig.custom()
.setSoTimeout(config.getSocketTimeoutMs())
.build();
RegistryBuilder registryBuilder = RegistryBuilder.create();
registryBuilder.register("http", new ConnectionInfoRecorderSocketFactory(
new PlainConnectionSocketFactory()));
if (config.isHttpsEnabled()) {
SSLContext sslContext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionInfoRecorderSocketFactory(
sslContext,
NoopHostnameVerifier.INSTANCE);
registryBuilder.register("https", sslConnectionSocketFactory);
}
ipBlackList = new TimeBasedIpAddressBlackList(config.getIpAddressNegativeDurationMillsec());
connectionManager = new PoolingHttpClientConnectionManager(registryBuilder.build(),
null,
null,
new RoundRobinDNSResolver(new InternalSiteBlackListDNSResolver(ipBlackList,
this.dnsResolver == null ?
SystemDefaultDnsResolver.INSTANCE : this.dnsResolver)),
config.getHTTPKeepAliveTimeoutMS(), TimeUnit.MILLISECONDS);
connectionManager.setDefaultMaxPerRoute(config.getMaxConnection());
connectionManager.setMaxTotal(config.getMaxConnection());
connectionManager.setDefaultSocketConfig(socketConfig);
FDSBlackListEnabledHostChecker fdsBlackListEnabledHostChecker = new FDSBlackListEnabledHostChecker();
retryHandler = new InternalIpBlackListRetryHandler(config.getRetryCount(),
ipBlackList, fdsBlackListEnabledHostChecker);
return HttpClients.custom()
.setRetryHandler(retryHandler)
.setServiceUnavailableRetryStrategy(new ServiceUnavailableDNSBlackListStrategy(
config.getRetryCount(),
config.getRetryIntervalMilliSec(),
ipBlackList,
fdsBlackListEnabledHostChecker))
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
}
@Override
public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
}
private HttpUriRequest prepareRequestMethod(URI uri,
HttpMethod method, ContentType contentType, FDSObjectMetadata metadata,
HashMap params, Map> headers,
HttpEntity requestEntity) throws GalaxyFDSClientException {
if (params != null) {
URIBuilder builder = new URIBuilder(uri).setCharset(Charset.forName("UTF-8"));
for (Entry param : params.entrySet()) {
builder.addParameter(param.getKey(), param.getValue());
}
try {
uri = builder.build();
} catch (URISyntaxException e) {
throw new GalaxyFDSClientException("Invalid param: " + params.toString(), e);
}
}
if (headers == null)
headers = new HashMap>();
Map h = prepareRequestHeader(uri, method, contentType, metadata);
for (Entry hIte : h.entrySet()) {
String key = hIte.getKey();
if (!headers.containsKey(key)) {
headers.put(key, new ArrayList());
}
headers.get(key).add(hIte.getValue());
}
HttpUriRequest httpRequest;
switch (method) {
case PUT:
HttpPut httpPut = new HttpPut(uri);
if (requestEntity != null)
httpPut.setEntity(requestEntity);
httpRequest = httpPut;
break;
case GET:
httpRequest = new HttpGet(uri);
break;
case DELETE:
httpRequest = new HttpDelete(uri);
break;
case HEAD:
httpRequest = new HttpHead(uri);
break;
case POST:
HttpPost httpPost = new HttpPost(uri);
if (requestEntity != null)
httpPost.setEntity(requestEntity);
httpRequest = httpPost;
break;
default:
throw new GalaxyFDSClientException("Method " + method.name() +
" not supported");
}
for (Entry> header : headers.entrySet()) {
String key = header.getKey();
if (key == null || key.isEmpty())
continue;
for (Object obj : header.getValue()) {
if (obj == null)
continue;
httpRequest.addHeader(header.getKey(), obj.toString());
}
}
return httpRequest;
}
@Override
public List listBuckets() throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), "", (SubResource[]) null);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, null, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.ListBuckets);
ListAllBucketsResult result = (ListAllBucketsResult) processResponse(response, ListAllBucketsResult.class,
"list buckets");
ArrayList buckets = new ArrayList();
if (result != null) {
OwnerBean owner = result.getOwner();
for (BucketBean b : result.getBuckets()) {
FDSBucket bucket = new FDSBucket(b.getName());
bucket.setOwner(new Owner(owner.getId(), owner.getDisplayName()));
buckets.add(bucket);
}
}
return buckets;
}
@Override
public List listAuthorizedBuckets() throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), "", (SubResource[]) null);
HashMap params = new LinkedHashMap();
params.put("authorizedBuckets", "");
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.ListAuthorizedBuckets);
ListAllAuthorizedBucketsResult result = (ListAllAuthorizedBucketsResult) processResponse(response,
ListAllAuthorizedBucketsResult.class, "list authorized buckets");
ArrayList buckets = new ArrayList();
if (result != null) {
for (BucketBean b : result.getBuckets()) {
FDSBucket bucket = new FDSBucket(b.getName());
bucket.setOwner(new Owner(b.getOrgId(), b.getOrgId()));
buckets.add(bucket);
}
}
return buckets;
}
private Object processResponse(HttpResponse response, Class c,
String purposeStr) throws GalaxyFDSClientException {
return processResponse(response, c, null, purposeStr);
}
private T processResponse(HttpResponse response, Class c,
JsonDeserializer deserializer,
String purposeStr) throws GalaxyFDSClientException {
HttpEntity httpEntity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
try {
if (statusCode == HttpStatus.SC_OK) {
if (c != null) {
Gson gson;
if (deserializer != null) {
// TODO (shenjiaqi) create new GsonBuilder as field of this class
gson = new GsonBuilder().registerTypeAdapter(c, deserializer).create();
} else {
gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").create();
}
Reader reader = new InputStreamReader(httpEntity.getContent(), Charset.forName("UTF-8"));
T entityVal = gson.fromJson(reader, c);
return entityVal;
}
return null;
} else {
String errorMsg = formatErrorMsg(purposeStr, response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg, statusCode);
}
} catch (IOException e) {
String errorMsg = formatErrorMsg("read response entity", e);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg, e);
} finally {
closeResponseEntity(response);
}
}
private HttpResponse executeHttpRequest(HttpUriRequest httpRequest,
Action action) throws GalaxyFDSClientException {
if(!Strings.isNullOrEmpty(fdsConfig.getUserAgent())) {
httpRequest.setHeader(Common.USER_AGENT, fdsConfig.getUserAgent());
}
HttpClientContext context = HttpClientContext.create();
if (fdsConfig.isMetricsEnabled()) {
context.setAttribute(Common.ACTION, action);
context.setAttribute(Common.METRICS_COLLECTOR, metricsCollector);
MetricsRequestFilter requestFilter = new MetricsRequestFilter();
try {
requestFilter.filter(context);
} catch (IOException e) {
LOG.error("fail to call request filter", e);
}
}
if (authCache != null && credentialsProvider != null) {
context.setCredentialsProvider(credentialsProvider);
context.setAuthCache(authCache);
}
context.setAttribute(Constants.REQUEST_METHOD, httpRequest.getMethod());
HttpContextUtil.setRequestRepeatable(context, true);
if (httpRequest instanceof HttpEntityEnclosingRequestBase) {
HttpEntity entity = ((HttpEntityEnclosingRequestBase) httpRequest).getEntity();
if (entity != null && !entity.isRepeatable()) {
HttpContextUtil.setRequestRepeatable(context, false);
}
}
HttpResponse response = null;
try {
try {
response = httpClient.execute(httpRequest, context);
} catch (IOException e) {
LOG.error("http request failed", e);
throw new GalaxyFDSClientException(e.getMessage(), e);
}
return response;
} finally {
if (fdsConfig.isMetricsEnabled()) {
try {
logFilter.filter(httpRequest, response);
} catch (IOException e) {
LOG.error("log filter failed", e);
}
MetricsResponseFilter responseFilter = new MetricsResponseFilter();
try {
responseFilter.filter(context);
} catch (IOException e) {
LOG.error("fail to call response filter", e);
}
}
}
}
@Override
public void createBucketUnderOrg(String org, String bucketName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
StringEntity requestEntity = getJsonStringEntity("{}", ContentType.APPLICATION_JSON);
HashMap params = new HashMap();
params.put(ORG_ID_PARAM, org);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT,
ContentType.APPLICATION_JSON, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutBucket);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
String errorMsg = formatErrorMsg("create bucket [" + bucketName + "]", response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
} finally {
closeResponseEntity(response);
}
}
@Override
public void createBucket(String bucketName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
StringEntity requestEntity = getJsonStringEntity("{}", ContentType.APPLICATION_JSON);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT,
ContentType.APPLICATION_JSON, null, null, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutBucket);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
String errorMsg = formatErrorMsg("create bucket [" + bucketName + "]", response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
} finally {
closeResponseEntity(response);
}
}
private void closeResponseEntity(HttpResponse response) {
if (response == null)
return;
HttpEntity entity = response.getEntity();
if (entity != null && entity.isStreaming())
try {
entity.getContent().close();
} catch (IOException e) {
LOG.error(formatErrorMsg("close response entity", e));
}
}
@Override
public void deleteBucket(String bucketName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.DELETE, null, null, null,
null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutBucket);
processResponse(response, null, "delete bucket [" + bucketName + "]");
}
@Override
@Deprecated
public void getBucket(String bucketName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, null, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetBucketMeta);
processResponse(response, null, "get bucket [" + bucketName + "]");
}
@Override
public BucketBean getBucketInfo(String bucketName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, null, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetBucketMeta);
BucketBean bucketInfo = (BucketBean) processResponse(response,
BucketBean.class, "get bucket [" + bucketName + "] info");
return bucketInfo;
}
@Override
public boolean doesBucketExist(String bucketName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.HEAD, null, null, null, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.HeadBucket);
int statusCode = response.getStatusLine().getStatusCode();
try {
if (statusCode == HttpStatus.SC_OK)
return true;
else if (statusCode == HttpStatus.SC_NOT_FOUND)
return false;
else {
String errorMsg = formatErrorMsg("check bucket [" + bucketName + "] existence", response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
} finally {
closeResponseEntity(response);
}
}
private String getResponseEntityPhrase(HttpResponse response) {
try {
InputStream inputStream = response.getEntity().getContent();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] data = new byte[1024];
for (int count; (count = inputStream.read(data, 0, 1024)) != -1; )
outputStream.write(data, 0, count);
String reason = outputStream.toString();
if (reason == null || reason.isEmpty())
return response.getStatusLine().getReasonPhrase();
return reason;
} catch (Exception e) {
LOG.error("Fail to get entity string");
return response.getStatusLine().getReasonPhrase();
}
}
@Override
public AccessControlList getBucketAcl(String bucketName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, SubResource.ACL);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, null, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetBucketACL);
AccessControlPolicy acp = (AccessControlPolicy) processResponse(response,
AccessControlPolicy.class, "get bucket [" + bucketName + "] acl");
return acpToAcl(acp);
}
@Override
public void setBucketAcl(String bucketName, AccessControlList acl)
throws GalaxyFDSClientException {
Preconditions.checkNotNull(acl);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, SubResource.ACL);
ContentType contentType = ContentType.APPLICATION_JSON;
AccessControlPolicy acp = aclToAcp(acl);
StringEntity requestEntity = getJsonStringEntity(acp, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null, null, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutBucketACL);
processResponse(response, null, "set bucket [" + bucketName + "] acl");
}
@Override public void deleteBucketAcl(String bucketName, AccessControlList acl)
throws GalaxyFDSClientException {
Preconditions.checkNotNull(acl);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, SubResource.ACL);
HashMap params = new HashMap();
params.put("action", "delete");
ContentType contentType = ContentType.APPLICATION_JSON;
AccessControlPolicy acp = aclToAcp(acl);
StringEntity requestEntity = getJsonStringEntity(acp, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteBucketACL);
processResponse(response, null, "delete bucket [" + bucketName + "] acl");
}
@Override
@Deprecated
public QuotaPolicy getBucketQuota(String bucketName)
throws GalaxyFDSClientException {
Preconditions.checkNotNull(bucketName);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, SubResource.QUOTA);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, null, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetBucketQuota);
QuotaPolicy quotaPolicy = (QuotaPolicy) processResponse(response,
QuotaPolicy.class, "get bucket [" + bucketName + "] quota");
return quotaPolicy;
}
@Override
@Deprecated
public void setBucketQuota(String bucketName, QuotaPolicy quotaPolicy)
throws GalaxyFDSClientException {
Preconditions.checkNotNull(quotaPolicy);
Preconditions.checkNotNull(bucketName);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, SubResource.QUOTA);
ContentType contentType = ContentType.APPLICATION_JSON;
HttpEntity requestEntity = getJsonStringEntity(quotaPolicy, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null, null,
null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutBucketQuota);
processResponse(response, null, "set bucket [" + bucketName + "] quota");
}
@Override
public FDSObjectListing listObjects(String bucketName)
throws GalaxyFDSClientException {
return listObjects(bucketName, "", this.delimiter);
}
@Override
public VersionListing listVersions(String bucketName)
throws GalaxyFDSClientException {
return listVersions(bucketName, "", this.delimiter);
}
@Override
public FDSObjectListing listObjects(String bucketName, String prefix)
throws GalaxyFDSClientException {
return listObjects(bucketName, prefix, this.delimiter);
}
@Override
public VersionListing listVersions(String bucketName, String prefix)
throws GalaxyFDSClientException {
return listVersions(bucketName, prefix, this.delimiter);
}
@Override
public FDSObjectListing listObjects(String bucketName, String prefix,
String delimiter) throws GalaxyFDSClientException {
return listObjects(bucketName, prefix, delimiter, false);
}
@Override
public FDSObjectListing listObjects(String bucketName, String prefix, String delimiter, boolean reverse) throws GalaxyFDSClientException {
return listObjects(bucketName, prefix, delimiter, reverse, false);
}
@Override
public FDSObjectListing listObjects(String bucketName, String prefix,
String delimiter, boolean reverse, boolean isBackup) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("prefix", prefix);
params.put("reverse", String.valueOf(reverse));
params.put("isBackup", String.valueOf(isBackup));
params.put("delimiter", delimiter);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.ListObjects);
ListObjectsResult listObjectsResult = (ListObjectsResult) processResponse(response, ListObjectsResult.class, "list objects under bucket [" + bucketName + "] with prefix [" + prefix + "]");
return getObjectListing(listObjectsResult);
}
@Override
public VersionListing listVersions(String bucketName, String prefix, String
delimiter) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("versions", "");
params.put("prefix", prefix);
params.put("delimiter", delimiter);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.ListVersions);
VersionListing versionListing = (VersionListing) processResponse(response,
VersionListing.class, "List versions under bucket [" + bucketName +
"] with prefix [" + prefix + "]");
return versionListing;
}
@Override
@Deprecated
public FDSObjectListing listTrashObjects(String prefix, String delimiter)
throws GalaxyFDSClientException {
return listObjects(Common.TRASH_BUCKET_NAME, prefix, delimiter);
}
@Override
public FDSObjectListing listNextBatchOfObjects(
FDSObjectListing previousObjectListing) throws GalaxyFDSClientException {
if (!previousObjectListing.isTruncated()) {
LOG.warn("The previous listObjects() response is complete, " +
"call of listNextBatchOfObjects() will be ingored");
return null;
}
String bucketName = previousObjectListing.getBucketName();
String prefix = previousObjectListing.getPrefix();
String delimiter = previousObjectListing.getDelimiter();
String marker = previousObjectListing.getNextMarker();
String reverse = String.valueOf(previousObjectListing.isReverse());
int maxKeys = previousObjectListing.getMaxKeys();
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("prefix", prefix);
params.put("delimiter", delimiter);
params.put("marker", marker);
params.put("reverse", reverse);
params.put("maxKeys", Integer.toString(maxKeys));
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.ListObjects);
ListObjectsResult listObjectsResult = (ListObjectsResult) processResponse(response,
ListObjectsResult.class,
"list next batch of objects under bucket [" + bucketName + "]" +
" with prefix [" + prefix + "], marker [" + marker + "]");
return getObjectListing(listObjectsResult);
}
@Override
public VersionListing listNextBatchOfVersions(VersionListing versionListing)
throws GalaxyFDSClientException {
if (!versionListing.isTruncated()) {
LOG.warn("The previous listVersions response is complete, " +
"call of listNexBatchOfVersions will be ingored");
return null;
}
String bucketName = versionListing.getBucketName();
String prefix = versionListing.getPrefix();
String delimiter = versionListing.getDelimiter();
String keyMarker = versionListing.getNextKeyMarker();
String versionIdMarker = versionListing.getNextVersionIdMarker();
int maxKeys = versionListing.getMaxKeys();
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("versions", "");
params.put("prefix", prefix);
params.put("delimiter", delimiter);
params.put("keyMarker", keyMarker);
params.put("versionIdMarker", versionIdMarker);
params.put("maxKeys", Integer.toString(maxKeys));
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null,
null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.ListVersions);
return (VersionListing) processResponse(
response, VersionListing.class, "List next batch of versions under " +
"bucket [" + bucketName + "] with prefix [" + prefix + "], marker" +
"[" + keyMarker + "], versionIdMarker [" + versionIdMarker + "]");
}
@Override
public PutObjectResult putObject(String bucketName, String objectName,
File file) throws GalaxyFDSClientException {
return putObject(bucketName, objectName, file, null);
}
@Override
public PutObjectResult putObject(String bucketName, String objectName,
File file, FDSObjectMetadata metadata) throws GalaxyFDSClientException {
Preconditions.checkNotNull(objectName);
return uploadLargeWithFile(bucketName, objectName, file, metadata);
}
private PutObjectResult uploadLargeWithFile(String bucketName, String objectName,
File file, FDSObjectMetadata metadata) throws GalaxyFDSClientException {
int partSize = fdsConfig.getPartSize();
if(file.length() <= partSize){
return uploadWithFile(bucketName, objectName, file, metadata);
} else {
PutObjectResult result = null;
try {
result = uploadLargeWithInputStream(bucketName, objectName, new FileInputStream(file), -1, metadata, null);
} catch (FileNotFoundException e){
throw new GalaxyFDSClientException(e);
}
return result;
}
}
private PutObjectResult uploadWithFile(String bucketName, String objectName,
File file, FDSObjectMetadata metadata) throws GalaxyFDSClientException {
if (this.fdsConfig.isMd5CalculateEnabled()) {
throw new GalaxyFDSClientException("Upload with File object and MD5 calculate enabled is not supported");
}
ContentType contentType = ContentType.APPLICATION_OCTET_STREAM;
if (metadata == null) {
metadata = new FDSObjectMetadata();
}
if (metadata.getContentType() != null) {
contentType = ContentType.create(metadata.getContentType());
}
URI uri = formatUri(fdsConfig.getUploadBaseUri(), bucketName + "/"
+ (objectName == null ? "" : objectName), (SubResource[]) null);
FileEntity requestEntity = new FileEntity(file, contentType);
HttpMethod m = objectName == null ? HttpMethod.POST : HttpMethod.PUT;
HttpUriRequest httpRequest = prepareRequestMethod(uri,
m, contentType, metadata, null, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest,
objectName == null ? Action.PostObject : Action.PutObject);
return (PutObjectResult) processResponse(response,
PutObjectResult.class,
m.name() + " object [" + objectName + "] to bucket [" + bucketName + "]");
}
@Override
public PutObjectResult putObject(FDSPutObjectRequest request) throws GalaxyFDSClientException {
Preconditions.checkNotNull(request);
try{
return this.uploadLargeWithInputStream(request.getBucketName(), request.getObjectName(),
request.getInputStream(), request.getInputStreamLength(), request.getMetadata(), request.getStorageClass());
}
catch (GalaxyFDSClientException ex){
throw ex;
}
finally {
if (request.isUploadFile()){
try{
request.getInputStream().close();
}
catch (Exception e){}
}
}
}
@Override
public PutObjectResult putObject(String bucketName, String objectName,
InputStream input, long contentLength, FDSObjectMetadata metadata)
throws GalaxyFDSClientException {
FDSPutObjectRequest putObjectRequest = new FDSPutObjectRequest()
.withBucketName(bucketName)
.withObjectName(objectName)
.withInputStream(input, contentLength)
.withMetadata(metadata);
return putObject(putObjectRequest);
}
private PutObjectResult uploadLargeWithInputStream(String bucketName,
String objectName, InputStream input, long contentLength,
FDSObjectMetadata metadata, String storageClass) throws GalaxyFDSClientException {
int partSize = fdsConfig.getPartSize();
byte[] data = new byte[partSize];
try {
int len = readData(input, data);
if (len < partSize) {
return uploadWithInputStream(bucketName, objectName,
new ByteArrayInputStream(data, 0, len), contentLength, metadata, storageClass);
} else {
FDSObjectMetadata metadataInit = new FDSObjectMetadata();
metadataInit.setMultipartUploadMode("DIRECT");
long uploadDone = 0;
long startTime = System.currentTimeMillis();
InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(bucketName, objectName, metadataInit)
.withStorageClass(storageClass == null ? null : StorageClass.fromValue(storageClass));
InitMultipartUploadResult initMultipartUploadResult = initMultipartUpload(initiateMultipartUploadRequest);
String uploadId = initMultipartUploadResult.getUploadId();
List results = new ArrayList();
int partNumber = 1;
do{
int retryCount = fdsConfig.getRetryCount();
int currentCount = 0;
UploadPartResult result = null;
while(true) {
currentCount++;
try {
result = uploadPart(bucketName, objectName, uploadId, partNumber, new ByteArrayInputStream(data, 0, len));
uploadDone += len;
limitUpload(uploadDone, fdsConfig.getUploadBandwidth(), System.currentTimeMillis() - startTime);
break;
} catch (GalaxyFDSClientException e){
Integer statusCode = Utils.getErrorCode(e.getMessage());
if(statusCode != null && statusCode != 429 && statusCode < 500){
throw e;
}
if(retryCount < currentCount){
throw e ;
}
LOG.warn("retry time:" + currentCount);
try {
Thread.sleep(fdsConfig.getRetryIntervalMilliSec());
} catch (InterruptedException ie){
//Ignore
}
}
}
if(fdsConfig.isMd5CalculateEnabled()){
if(!result.getEtag().equals(DigestUtils.md5Hex(Arrays.copyOfRange(data, 0, len)))){
LOG.error("md5 is discrepancy with serve, retry time:" + currentCount);
break;
}
}
results.add(result);
partNumber++;
} while((len = readData(input, data)) > 0);
return completeMultipartUpload(bucketName, objectName, uploadId, metadata, new UploadPartResultList(results));
}
} catch (IOException e){
throw new GalaxyFDSClientException(e);
}
}
private int readData(InputStream inputStream, byte[] data) throws IOException{
int len = 0;
int readlen = 0;
while(len < data.length && (readlen = inputStream.read(data, len, data.length - len)) != -1){
len += readlen;
}
return len;
}
private void limitUpload(long uploadDone, long uploadBandwidth, long timeUsed){
if (uploadBandwidth > 0) {
long sleepTimeInMs = 1000 * uploadDone / uploadBandwidth - timeUsed;
if (sleepTimeInMs > 0) {
try {
Thread.sleep(sleepTimeInMs);
} catch (InterruptedException e) {
// do nothing.
}
}
}
}
private PutObjectResult uploadWithInputStream(String bucketName,
String objectName, InputStream input, long contentLength,
FDSObjectMetadata metadata, String storageClass) throws GalaxyFDSClientException {
if(metadata == null){
metadata = new FDSObjectMetadata();
}
checkAndSetStorageClass(metadata, storageClass);
ContentType contentType = ContentType.APPLICATION_OCTET_STREAM;
if (metadata != null && metadata.getContentType() != null) {
contentType = ContentType.create(metadata.getContentType());
}
if (fdsConfig.isMd5CalculateEnabled()) {
if (metadata == null) {
metadata = new FDSObjectMetadata();
}
metadata.addHeader(XiaomiHeader.MD5_ATTACHED_STREAM.getName(), "1");
try {
input = new FDSMd5InputStream(input);
} catch (NoSuchAlgorithmException e) {
throw new GalaxyFDSClientException("Cannot init md5", e);
}
}
URI uri = formatUri(fdsConfig.getUploadBaseUri(), bucketName + "/"
+ (objectName == null ? "" : objectName), (SubResource[]) null);
AbstractHttpEntity requestEntity = getRequestEntity(input, contentType, contentLength);
HttpMethod m = objectName == null ? HttpMethod.POST : HttpMethod.PUT;
HttpUriRequest httpRequest = prepareRequestMethod(uri,
m, contentType, metadata, null, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest,
objectName == null ? Action.PostObject : Action.PutObject);
return (PutObjectResult) processResponse(response,
PutObjectResult.class,
m.name() + " object [" + objectName + "] to bucket [" + bucketName + "]");
}
@Override
public PutObjectResult putObject(String bucketName, String objectName,
InputStream input, FDSObjectMetadata metadata)
throws GalaxyFDSClientException {
FDSPutObjectRequest putObjectRequest = new FDSPutObjectRequest()
.withBucketName(bucketName)
.withObjectName(objectName)
.withInputStream(input, -1)
.withMetadata(metadata);
return putObject(putObjectRequest);
}
@Override
public PutObjectResult postObject(String bucketName, File file)
throws GalaxyFDSClientException {
return uploadWithFile(bucketName, null, file, null);
}
@Override
public PutObjectResult postObject(String bucketName, InputStream input,
FDSObjectMetadata metadata) throws GalaxyFDSClientException {
return uploadWithInputStream(bucketName, null, input, -1, metadata, null);
}
/**
* Be extremely careful when using this method; the returned Galaxy FDS object
* contains a direct stream of data from the HTTP connection. The underlying
* HTTP connection cannot be closed until the user finishes reading the data
* and closes the stream.
* Therefore:
*
*
* Use the data from the input stream in Galaxy FDS object as soon as
* possible
* Close the input stream in Galaxy FDS object as soon as possible
*
* If these rules are not followed, the client can run out of resources by
* allocating too many open, but unused, HTTP connections.
*
*
* To get an object from Galaxy FDS, the caller must have read permission
* access to the object.
*
* @param bucketName The name of the bucket where the object stores
* @param objectName The name of the object to get
* @return
* @throws GalaxyFDSClientException
*/
@Override
public FDSObject getObject(String bucketName, String objectName)
throws GalaxyFDSClientException {
// start from position 0 by default
return this.getObject(bucketName, objectName, null, 0);
}
@Override
public FDSObject getObject(String bucketName, String objectName, String
versionId) throws GalaxyFDSClientException {
return this.getObject(bucketName, objectName, versionId, 0);
}
/**
* range mode for getobject while not be autoReConnection
* @param bucketName The name of the bucket where the object stores
* @param objectName The name of the object to get
* @param pos The position to start read
* @return
* @throws GalaxyFDSClientException
*/
@Override
public FDSObject getObject(String bucketName, String objectName, long pos)
throws GalaxyFDSClientException {
return this.getObject(bucketName, objectName, null, pos);
}
@Override
public FDSObject getObject(String bucketName, String objectName, String
versionId, long pos) throws GalaxyFDSClientException {
if (pos < 0) {
String errorMsg = "get object " + objectName + " from bucket "
+ bucketName + " failed, reason=invalid seek position:" + pos;
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
URI uri = formatUri(fdsConfig.getDownloadBaseUri(), bucketName + "/"
+ objectName, (SubResource[]) null);
Map> headers = new HashMap>();
if (pos > 0) {
List objects = new ArrayList();
objects.add("bytes=" + pos + "-");
headers.put(Common.RANGE, objects);
}
HashMap params = new HashMap();
if (versionId != null) {
params.put(VERSION_ID, versionId);
}
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null,
null, params, headers, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetObject);
HttpEntity httpEntity = response.getEntity();
FDSObject rtnObject = null;
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT) {
FDSObjectMetadata metadata = FDSObjectMetadata.parseObjectMetadata(
headerArray2MultiValuedMap(response.getAllHeaders()));
FDSObjectSummary summary = new FDSObjectSummary();
summary.setBucketName(bucketName);
summary.setObjectName(objectName);
summary.setSize(httpEntity.getContentLength());
summary.setUploadTime(metadata.getLastModified().getTime());
FDSObjectInputStream stream = null;
stream = new FDSObjectInputStream.Builder(httpEntity)
.withFDSClient(this)
.withSummarg(summary)
.withVersionId(versionId)
.withHttpUriRequest(httpRequest)
.withPos(pos)
.build();
rtnObject = new FDSObject();
rtnObject.setObjectSummary(summary);
rtnObject.setObjectContent(stream);
rtnObject.setObjectMetadata(metadata);
return rtnObject;
} else {
String errorMsg = formatErrorMsg("get object [" + objectName + "] with"
+ " versionId [" + versionId + "] from bucket [" + bucketName + "]",
response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
} catch (IOException e) {
String errorMsg = formatErrorMsg("read entity stream", e);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg, e);
} finally {
if (rtnObject == null) {
closeResponseEntity(response);
}
}
}
@Override
public FDSObject getArchive(String bucketName, String objectName, long pos) throws GalaxyFDSClientException {
if (pos < 0) {
String errorMsg = "get object " + objectName + " from bucket "
+ bucketName + " failed, reason=invalid seek position:" + pos;
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
URI uri = formatUri(fdsConfig.getDownloadBaseUri(), bucketName + "/"
+ objectName, (SubResource[]) null);
Map> headers = new HashMap>();
if (pos > 0) {
List objects = new ArrayList();
objects.add("bytes=" + pos + "-");
headers.put(Common.RANGE, objects);
}
HashMap params = new HashMap();
params.put(ARCHIVE, Boolean.TRUE.toString());
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null,
null, params, headers, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetObject);
HttpEntity httpEntity = response.getEntity();
FDSObject rtnObject = null;
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT) {
FDSObjectMetadata metadata = FDSObjectMetadata.parseObjectMetadata(
headerArray2MultiValuedMap(response.getAllHeaders()));
FDSObjectSummary summary = new FDSObjectSummary();
summary.setBucketName(bucketName);
summary.setObjectName(objectName);
summary.setSize(httpEntity.getContentLength());
summary.setUploadTime(metadata.getLastModified().getTime());
FDSObjectInputStream stream = null;
stream = new FDSObjectInputStream.Builder(httpEntity)
.withFDSClient(this)
.withSummarg(summary)
.withHttpUriRequest(httpRequest)
.withPos(pos)
.build();
rtnObject = new FDSObject();
rtnObject.setObjectSummary(summary);
rtnObject.setObjectContent(stream);
rtnObject.setObjectMetadata(metadata);
return rtnObject;
} else {
String errorMsg = formatErrorMsg("get object [" + objectName + "] from bucket [" + bucketName + "]",
response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
} catch (IOException e) {
String errorMsg = formatErrorMsg("read entity stream", e);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg, e);
} finally {
if (rtnObject == null) {
closeResponseEntity(response);
}
}
}
@Override
public FDSObject getObjectFromThirdParty(String bucketName, String objectName, long pos)
throws GalaxyFDSClientException {
if (pos < 0) {
String errorMsg = "get object " + objectName + " from third party in bucket "
+ bucketName + " failed, reason=invalid seek position:" + pos;
throw new GalaxyFDSClientException(errorMsg);
}
ThirdPartyObject thirdPartyObject = this.getThirdPartyObject(bucketName, objectName);
if (thirdPartyObject == null) {
LOG.warn("Get third party object return null, turn to get object directly, bucket [" +
bucketName + "], object [" + objectName + "]");
return getObject(bucketName, objectName, pos);
}
String url = thirdPartyObject.getThirdPartyObjectBean().getUrl();
if (!fdsConfig.isHttpsEnabled()) {
url = url.replace("https://", "http://");
}
HttpUriRequest httpRequest = new HttpGet(url);
long startPos = pos + thirdPartyObject.getThirdPartyObjectBean().getStartPos();
long stopPos = thirdPartyObject.getThirdPartyObjectBean().getStopPos();
httpRequest.addHeader(Common.RANGE, "bytes=" + startPos + "-" + stopPos);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetObject);
HttpEntity httpEntity = response.getEntity();
FDSObject rtnObject = null;
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT) {
FDSObjectSummary summary = new FDSObjectSummary();
summary.setBucketName(bucketName);
summary.setObjectName(objectName);
summary.setSize(httpEntity.getContentLength());
summary.setUploadTime(thirdPartyObject.getObjectMetadata().getLastModified().getTime());
long objectSize = Long.parseLong(thirdPartyObject.getObjectMetadata().getRawMetadata()
.get(XiaomiHeader.CONTENT_LENGTH.getName()));
if (pos > 0) {
thirdPartyObject.getObjectMetadata().removeHeader(Common.CONTENT_MD5);
thirdPartyObject.getObjectMetadata().setContentRange(pos, objectSize - 1, objectSize);
}
thirdPartyObject.getObjectMetadata().addHeader(Common.CONTENT_LENGTH,
String.valueOf(httpEntity.getContentLength()));
thirdPartyObject.getObjectMetadata().removeHeader(Common.CACHE_CONTROL);
FDSObjectInputStream stream = null;
stream = new FDSObjectInputStream.Builder(httpEntity)
.withFDSClient(this)
.withSummarg(summary)
.withHttpUriRequest(httpRequest)
.withPos(pos)
.build();
rtnObject = new FDSObject();
rtnObject.setObjectSummary(summary);
rtnObject.setObjectContent(stream);
rtnObject.setObjectMetadata(thirdPartyObject.getObjectMetadata());
return rtnObject;
} else {
String errorMsg = formatErrorMsg("get object [" + objectName + "] from"
+ " third party from bucket [" + bucketName + "]",
response);
throw new GalaxyFDSClientException(errorMsg);
}
} catch (IOException e) {
String errorMsg = formatErrorMsg("read entity stream", e);
throw new GalaxyFDSClientException(errorMsg, e);
} finally {
if (rtnObject == null) {
closeResponseEntity(response);
}
}
}
@Override
public FDSObjectMetadata getObjectMetadata(String bucketName,
String objectName) throws GalaxyFDSClientException {
return getObjectMetadata(bucketName, objectName, null);
}
@Override
public FDSObjectMetadata getObjectMetadata(String bucketName, String objectName,
String versionId) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName, SubResource.METADATA);
HashMap params = new HashMap();
if (versionId != null) {
params.put(VERSION_ID, versionId);
}
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetObjectMetadata);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
FDSObjectMetadata metadata = FDSObjectMetadata.parseObjectMetadata(
headerArray2MultiValuedMap(response.getAllHeaders()));
return metadata;
} else {
String errorMsg = formatErrorMsg("get metadata for object [" +
objectName + "] with versionId + [" + versionId + "] under bucket ["
+ bucketName + "]", response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
} finally {
closeResponseEntity(response);
}
}
@Override
public AccessControlList getObjectAcl(String bucketName, String objectName)
throws GalaxyFDSClientException {
return getObjectAcl(bucketName, objectName, null);
}
@Override
public AccessControlList getObjectAcl(String bucketName, String objectName,
String versionId) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
SubResource.ACL);
HashMap params = new HashMap();
if (versionId != null) {
params.put(VERSION_ID, versionId);
}
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null,
null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetObjectACL);
AccessControlPolicy acp = (AccessControlPolicy) processResponse(response,
AccessControlPolicy.class, "get acl for object [" + objectName + "] with" +
" versionId [" + versionId + "] under bucket [" + bucketName + "]");
return acpToAcl(acp);
}
@Override
public void setObjectAcl(String bucketName, String objectName,
AccessControlList acl) throws GalaxyFDSClientException {
setObjectAcl(bucketName, objectName, null, acl);
}
@Override
public void setObjectAcl(String bucketName, String objectName, String
versionId, AccessControlList acl) throws GalaxyFDSClientException {
Preconditions.checkNotNull(acl);
AccessControlPolicy acp = aclToAcp(acl);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
SubResource.ACL);
HashMap params = new HashMap();
if (versionId != null) {
params.put(VERSION_ID, versionId);
}
StringEntity requestEntity = getJsonStringEntity(acp, ContentType.APPLICATION_JSON);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT,
ContentType.APPLICATION_JSON, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutObjectACL);
processResponse(response, null, "set acl for object [" +
objectName + "] with versionId [" + versionId + "] under bucket [" + bucketName + "]");
}
@Override
public void setArchiveAcl(String bucketName, String objectName, AccessControlList acl) throws GalaxyFDSClientException {
Preconditions.checkNotNull(acl);
AccessControlPolicy acp = aclToAcp(acl);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
SubResource.ACL);
HashMap params = new HashMap();
params.put(ARCHIVE, Boolean.TRUE.toString());
StringEntity requestEntity = getJsonStringEntity(acp, ContentType.APPLICATION_JSON);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT,
ContentType.APPLICATION_JSON, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutObjectACL);
processResponse(response, null, "set acl for archive [" +
objectName + "] under bucket [" + bucketName + "]");
}
@Override
public void deleteObjectAcl(String bucketName, String objectName,
AccessControlList acl) throws GalaxyFDSClientException {
deleteObjectAcl(bucketName, objectName, null, acl);
}
@Override
public void deleteObjectAcl(String bucketName, String objectName, String
versionId, AccessControlList acl) throws GalaxyFDSClientException {
Preconditions.checkNotNull(acl);
AccessControlPolicy acp = aclToAcp(acl);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
SubResource.ACL);
HashMap params = new HashMap();
params.put("action", "delete");
if (versionId != null) {
params.put(VERSION_ID, versionId);
}
ContentType contentType = ContentType.APPLICATION_JSON;
StringEntity requestEntity = getJsonStringEntity(acp, ContentType.APPLICATION_JSON);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT,
contentType, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteObjectACL);
processResponse(response, null, "delete acl for object [" + objectName +
"] with versionId [" + versionId + "] under bucket [" + bucketName + "]");
}
@Override
public void deleteArchiveAcl(String bucketName, String objectName, AccessControlList acl) throws GalaxyFDSClientException {
Preconditions.checkNotNull(acl);
AccessControlPolicy acp = aclToAcp(acl);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
SubResource.ACL);
HashMap params = new HashMap();
params.put("action", "delete");
params.put(ARCHIVE, Boolean.TRUE.toString());
ContentType contentType = ContentType.APPLICATION_JSON;
StringEntity requestEntity = getJsonStringEntity(acp, ContentType.APPLICATION_JSON);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT,
contentType, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteObjectACL);
processResponse(response, null, "delete acl for archive [" + objectName +
"] under bucket [" + bucketName + "]");
}
@Override
public boolean doesObjectExist(String bucketName, String objectName)
throws GalaxyFDSClientException {
return doesObjectExist(bucketName, objectName, null);
}
@Override
public boolean doesObjectExist(String bucketName, String objectName, String
versionId) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
(SubResource[]) null);
HashMap params = new HashMap();
if (versionId != null) {
params.put(VERSION_ID, versionId);
}
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.HEAD, null, null, params,
null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.HeadObject);
int statusCode = response.getStatusLine().getStatusCode();
try {
if (statusCode == HttpStatus.SC_OK)
return true;
else if (statusCode == HttpStatus.SC_NOT_FOUND)
return false;
else {
String errorMsg = formatErrorMsg("check existence of object [" + objectName +
"] with versionId [" + versionId + "] under bucket [" + bucketName
+ "]", response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
} finally {
closeResponseEntity(response);
}
}
@Override
public void deleteObject(String bucketName, String objectName)
throws GalaxyFDSClientException {
deleteObject(bucketName, objectName, null);
}
@Override
public void deleteObject(String bucketName, String objectName, String versionId)
throws GalaxyFDSClientException {
deleteObject(bucketName, objectName, null, true);
}
@Override
public void deleteObject(String bucketName, String objectName, String versionId, boolean enableTrash)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
(SubResource[]) null);
HashMap params = new HashMap();
if (versionId != null) {
params.put(VERSION_ID, versionId);
}
if (!enableTrash) {
params.put("enableTrash", String.valueOf(enableTrash));
}
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.DELETE,
null, null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteObject);
processResponse(response, null, "delete object [" + objectName + "] with " +
"versionId[ " + versionId + " under bucket [" + bucketName + "]");
}
@Override
public void deleteArchive(String bucketName, String objectName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
(SubResource[]) null);
HashMap params = new HashMap();
params.put(ARCHIVE, Boolean.TRUE.toString());
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.DELETE,
null, null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteObject);
processResponse(response, null, "delete object [" + objectName +
"] under bucket [" + bucketName + "]");
}
@Override
public List> deleteObjects(String bucketName, String prefix)
throws GalaxyFDSClientException {
return deleteObjects(bucketName, prefix, true);
}
@Override
public List> deleteObjects(String bucketName, String prefix, boolean enableTrash)
throws GalaxyFDSClientException {
Preconditions.checkNotNull(bucketName);
Preconditions.checkNotNull(prefix);
List> resultList = new ArrayList>();
FDSObjectListing objects = listObjects(bucketName, prefix, "");
long totalItemsListed = 0, totalItemsDeleted = 0;
int batchDeleteSize = fdsConfig.getMaxBatchDeleteSize();
for (int iterationCnt = 0; objects != null; ++iterationCnt) {
int itemsLeft = objects.getObjectSummaries().size();
totalItemsListed += itemsLeft;
List objectNameList = new ArrayList();
totalItemsDeleted += itemsLeft;
if (itemsLeft > 0)
for (FDSObjectSummary s : objects.getObjectSummaries()) {
String objectName = s.getObjectName();
objectNameList.add(objectName);
--itemsLeft;
if (objectNameList.size() >= batchDeleteSize || itemsLeft <= 0) {
try {
List> errorList = deleteObjects(bucketName, objectNameList, enableTrash);
totalItemsDeleted -= errorList.size();
resultList.addAll(errorList);
} catch (Exception e) {
LOG.warn("fail to delete objects", e);
// retry with small batch size
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
}
for (int index = 0, interval = Math.max(10, objectNameList.size() / 10);
index < objectNameList.size(); ) {
int to = Math.min(index + interval, objectNameList.size());
resultList.addAll(deleteObjects(bucketName,
objectNameList.subList(index, to)));
index = to;
}
}
objectNameList.clear();
}
}
LOG.info("" + iterationCnt + "th round, "
+ " total items listed: " + totalItemsListed
+ " total items deleted: " + totalItemsDeleted
+ " total errors: " + resultList.size());
objects = listNextBatchOfObjects(objects);
}
return resultList;
}
@Override
public List> deleteObjects(String bucketName,
List objectNameList)
throws GalaxyFDSClientException {
return deleteObjects(bucketName, objectNameList, true);
}
@Override
public List> deleteObjects(String bucketName,
List objectNameList, boolean enableTrash)
throws GalaxyFDSClientException {
Preconditions.checkNotNull(bucketName);
Preconditions.checkNotNull(objectNameList);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
ContentType contentType = ContentType.APPLICATION_JSON;
StringEntity requestEntity = getJsonStringEntity(objectNameList, contentType);
HashMap params = new HashMap();
params.put("deleteObjects", "");
if (!enableTrash) {
params.put("enableTrash", String.valueOf(enableTrash));
}
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteObjects);
List> responseList = (List>) processResponse(
response, List.class,
"delete " + objectNameList.size() + " objects under bucket [" + bucketName + "]");
return responseList;
}
@Override
public void restoreObject(String bucketName, String objectName)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
StringEntity requestEntity = getJsonStringEntity("", contentType);
HashMap params = new HashMap();
params.put("restore", "");
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
(SubResource[]) null);
HttpUriRequest httpRequest = prepareRequestMethod(uri,
HttpMethod.PUT, contentType, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.RestoreObject);
processResponse(response, null,
"restore object [" + objectName + "] under bucket [" + bucketName + "]");
}
@Override
public void migrateBucket(String bucketName, String orgId, String teamId)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
StringEntity requestEntity = getJsonStringEntity("", contentType);
HashMap params = new HashMap();
params.put("migrate", "");
params.put("orgId", orgId);
params.put("teamId", teamId);
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.MigrateBucket);
processResponse(response, null,
"migrate bucket [" + bucketName + "] to orgId [" + orgId + "]");
}
@Override
public void renameObject(String bucketName, String srcObjectName,
String dstObjectName) throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_OCTET_STREAM;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + srcObjectName,
(SubResource[]) null);
HashMap params = new HashMap();
params.put("renameTo", dstObjectName);
StringEntity requestEntity = getJsonStringEntity("", contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri,
HttpMethod.PUT, contentType, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.RenameObject);
processResponse(response, null, "rename object [" + srcObjectName +
"] to object [" + dstObjectName + "] under bucket [" + bucketName + "]");
}
@Override
public long prefetchObject(String bucketName, String objectName)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("prefetch", "");
StringEntity requestEntity = getJsonStringEntity(null, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PrefetchObject);
long restPrivateQuota = (Long)processResponse(response, Long.class, "prefetch object [" + objectName + "] under bucket [" +
bucketName + "]");
return restPrivateQuota;
}
@Override
public long refreshObject(String bucketName, String objectName)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
(SubResource[]) null);
HashMap params = new HashMap();
params.put("refresh", "");
StringEntity requestEntity = getJsonStringEntity(null, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT,
contentType, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.RefreshObject);
long restPrivateQuota = (Long)processResponse(response, Long.class, "refresh object [" + objectName + "] under bucket [" +
bucketName + "]");
return restPrivateQuota;
}
@Override
public void putDomainMapping(String bucketName, String domainName)
throws GalaxyFDSClientException {
putDomainMapping(bucketName, domainName, "index.html");
}
@Override
public void putDomainMapping(String bucketName, String domainName, String indexName)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("domain", domainName);
params.put("index", indexName);
StringEntity requestEntity = getJsonStringEntity("", contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutDomainMapping);
processResponse(response, null, "add domain mapping; bucket [" + bucketName
+ "], domainName [" + domainName + "]");
}
@Override
public List listDomainMappings(String bucketName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("domain", "");
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.ListDomainMappings);
ListDomainMappingsResult result = (ListDomainMappingsResult) processResponse(response,
ListDomainMappingsResult.class,
"list domain mappings; bucket [" + bucketName + "]");
return result.getDomainMappings();
}
@Override
public void deleteDomainMapping(String bucketName, String domainName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("domain", domainName);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.DELETE,
null, null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteDomainMapping);
processResponse(response, null, "delete domain mapping; bucket [" + bucketName
+ "], domain [" + domainName + "]");
}
@Override
public void cropImage(String bucketName, String objectName,
int x, int y, int w, int h)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_OCTET_STREAM;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
(SubResource[]) null);
HashMap params = new HashMap();
params.put("cropImage", "");
params.put("x", Integer.toString(x));
params.put("y", Integer.toString(y));
params.put("w", Integer.toString(w));
params.put("h", Integer.toString(h));
StringEntity requestEntity = getJsonStringEntity("", contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.CropImage);
processResponse(response, null, "crop image; bucket [" + bucketName
+ "], object [" + objectName + "]");
}
@Override
public FDSObject getThumbnail(String bucketName, String objectName, int w, int h)
throws GalaxyFDSClientException{
URI uri = formatUri(fdsConfig.getDownloadBaseUri(), bucketName + "/"
+ objectName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("thumb", "1");
params.put("w", Integer.toString(w));
params.put("h", Integer.toString(h));
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetObject);
HttpEntity httpEntity = response.getEntity();
FDSObject rtnObject = null;
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT) {
FDSObjectSummary summary = new FDSObjectSummary();
summary.setBucketName(bucketName);
summary.setObjectName(objectName);
summary.setSize(httpEntity.getContentLength());
FDSObjectInputStream stream = new FDSObjectInputStream.Builder(httpEntity).build();
rtnObject = new FDSObject();
rtnObject.setObjectSummary(summary);
rtnObject.setObjectContent(stream);
rtnObject.setObjectMetadata(FDSObjectMetadata.parseObjectMetadata(
headerArray2MultiValuedMap(response.getAllHeaders())));
return rtnObject;
} else {
String errorMsg = formatErrorMsg("get object [" + objectName + "] with"
+ " from bucket [" + bucketName + "]",
response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg);
}
} catch (IOException e) {
String errorMsg = formatErrorMsg("read entity stream", e);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg, e);
} finally {
if (rtnObject == null) {
closeResponseEntity(response);
}
}
}
@Override
public void setPublic(String bucketName, String objectName)
throws GalaxyFDSClientException {
AccessControlList acl = new AccessControlList();
acl.addGrant(new AccessControlList.Grant(AccessControlList.UserGroups.ALL_USERS.name(), AccessControlList.Permission.READ,
AccessControlList.GrantType.GROUP));
setObjectAcl(bucketName, objectName, acl);
}
@Override
public void setPublic(String bucketName) throws GalaxyFDSClientException {
AccessControlList acl = new AccessControlList();
acl.addGrant(new AccessControlList.Grant(AccessControlList.UserGroups.ALL_USERS.name(), AccessControlList.Permission.READ_OBJECTS, AccessControlList.GrantType.GROUP));
setBucketAcl(bucketName, acl);
}
@Override
public URI generateDownloadObjectUri(String bucketName, String objectName)
throws GalaxyFDSClientException {
return formatUri(fdsConfig.getDownloadBaseUri(), bucketName + "/"
+ objectName, (SubResource[]) null);
}
@Override
public URI generatePresignedUri(String bucketName, String objectName,
Date expiration) throws GalaxyFDSClientException {
return generatePresignedUri(bucketName, objectName, expiration, HttpMethod.GET);
}
@Override
public URI generatePresignedCdnUri(String bucketName, String objectName,
Date expiration) throws GalaxyFDSClientException {
return generatePresignedCdnUri(bucketName, objectName, expiration, HttpMethod.GET);
}
@Override
public URI generatePresignedUri(String bucketName, String objectName,
Date expiration, HttpMethod httpMethod) throws GalaxyFDSClientException {
try {
return generatePresignedUri(fdsConfig.getBaseUri(), bucketName, objectName,
null, null, expiration, httpMethod, credential.getGalaxyAccessId(),
credential.getGalaxyAccessSecret(), SIGN_ALGORITHM);
} catch (GalaxyException e) {
throw new GalaxyFDSClientException(e);
}
}
@Override
public URI generatePresignedCdnUri(String bucketName, String objectName,
Date expiration, HttpMethod httpMethod) throws GalaxyFDSClientException {
try {
return generatePresignedUri(fdsConfig.getCdnBaseUri(), bucketName,
objectName, null, null, expiration, httpMethod, credential.getGalaxyAccessId(),
credential.getGalaxyAccessSecret(), SIGN_ALGORITHM);
} catch (GalaxyException e) {
throw new GalaxyFDSClientException(e);
}
}
@Override
public URI generatePresignedUri(String bucketName, String objectName,
SubResource subResource, Date expiration, HttpMethod httpMethod)
throws GalaxyFDSClientException {
List subResources = new ArrayList();
subResources.add(subResource.getName());
return generatePresignedUri(bucketName, objectName, subResources,
expiration, httpMethod);
}
@Override
public URI generatePresignedUri(String bucketName, String objectName,
List subResources, Date expiration, HttpMethod httpMethod)
throws GalaxyFDSClientException {
try {
return generatePresignedUri(fdsConfig.getBaseUri(), bucketName, objectName,
subResources, null, expiration, httpMethod, credential.getGalaxyAccessId(),
credential.getGalaxyAccessSecret(), SIGN_ALGORITHM);
} catch (GalaxyException e) {
throw new GalaxyFDSClientException(e);
}
}
@Override
public URI generatePresignedUri(String bucketName, String objectName,
List subResources, Date expiration, HttpMethod httpMethod, String contentType)
throws GalaxyFDSClientException {
try {
return generatePresignedUri(fdsConfig.getBaseUri(), bucketName, objectName,
subResources, contentType, expiration, httpMethod, credential.getGalaxyAccessId(),
credential.getGalaxyAccessSecret(), SIGN_ALGORITHM);
} catch (GalaxyException e) {
throw new GalaxyFDSClientException(e);
}
}
@Override public URI generatePresignedUri(String bucketName, String objectName,
List subResources, Date expiration, HttpMethod httpMethod, String contentType,
String contentMD5) throws GalaxyFDSClientException {
try {
return generatePresignedUri(fdsConfig.getBaseUri(), bucketName, objectName, subResources,
contentType, contentMD5, expiration, httpMethod, credential.getGalaxyAccessId(),
credential.getGalaxyAccessSecret(), SIGN_ALGORITHM);
} catch (GalaxyException e) {
throw new GalaxyFDSClientException(e);
}
}
@Override
public URI generatePresignedCdnUri(String bucketName, String objectName,
SubResource subResource, Date expiration, HttpMethod httpMethod)
throws GalaxyFDSClientException {
List subResources = new ArrayList();
subResources.add(subResource.getName());
return generatePresignedCdnUri(bucketName, objectName, subResources,
expiration, httpMethod);
}
@Override
public URI generatePresignedCdnUri(String bucketName, String objectName,
List subResources, Date expiration, HttpMethod httpMethod)
throws GalaxyFDSClientException {
try {
return generatePresignedUri(fdsConfig.getCdnBaseUri(), bucketName,
objectName, subResources, null, expiration, httpMethod,
credential.getGalaxyAccessId(), credential.getGalaxyAccessSecret(),
SIGN_ALGORITHM);
} catch (GalaxyException e) {
throw new GalaxyFDSClientException(e);
}
}
@Override
public InitMultipartUploadResult initMultipartUpload(InitiateMultipartUploadRequest request)
throws GalaxyFDSClientException{
return initMultipartUpload(request.getBucketName(), request.getObjectName(),
request.getObjectMetadata(), request.getStorageClass());
}
@Override
public InitMultipartUploadResult initMultipartUpload(String bucketName,
String objectName) throws GalaxyFDSClientException{
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
return initMultipartUpload(request);
}
@Override
public InitMultipartUploadResult initMultipartUpload(String bucketName,
String objectName, FDSObjectMetadata metadata) throws GalaxyFDSClientException {
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName, metadata);
return initMultipartUpload(request);
}
private InitMultipartUploadResult initMultipartUpload(String bucketName,
String objectName, FDSObjectMetadata metadata, String storageClass) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
SubResource.UPLOADS);
ContentType contentType = ContentType.APPLICATION_JSON;
if(metadata == null){
metadata = new FDSObjectMetadata();
}
checkAndSetStorageClass(metadata, storageClass);
HttpUriRequest httpRequest = prepareRequestMethod(uri,
HttpMethod.PUT, contentType, metadata, null, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.InitMultiPartUpload);
InitMultipartUploadResult initMultipartUploadResult = (InitMultipartUploadResult) processResponse(response,
InitMultipartUploadResult.class,
"init multipart upload object [" + objectName +
"] to bucket [" + bucketName + "]");
return initMultipartUploadResult;
}
@Override
public UploadPartResult uploadPart(String bucketName, String objectName,
String uploadId, int partNumber, InputStream in)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
null);
ContentType contentType = ContentType.APPLICATION_OCTET_STREAM;
HashMap params = new HashMap();
params.put("uploadId", uploadId);
params.put("partNumber", String.valueOf(partNumber));
AbstractHttpEntity requestEntity = getRequestEntity(in, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri,
HttpMethod.PUT, contentType, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.UploadPart);
UploadPartResult uploadPartResult = (UploadPartResult) processResponse(response,
UploadPartResult.class,
"upload part of object [" + objectName +
"] to bucket [" + bucketName + "]" + "; part number [" +
partNumber + "], upload id [" + uploadId + "]");
return uploadPartResult;
}
@Override
public PutObjectResult completeMultipartUpload(String bucketName,
String objectName, String uploadId, FDSObjectMetadata metadata,
UploadPartResultList uploadPartResultList) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
null);
ContentType contentType = ContentType.APPLICATION_OCTET_STREAM;
if (metadata != null && metadata.getContentType() != null) {
contentType = ContentType.create(metadata.getContentType());
}
HashMap params = new HashMap();
params.put("uploadId", uploadId);
StringEntity requestEntity = getJsonStringEntity(uploadPartResultList, ContentType.APPLICATION_JSON);
HttpUriRequest httpRequest = prepareRequestMethod(uri,
HttpMethod.PUT, contentType, metadata, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.CompleteMultiPartUpload);
PutObjectResult putObjectResult = (PutObjectResult) processResponse(response,
PutObjectResult.class,
"complete multipart upload of object [" + objectName +
"] to bucket [" + bucketName + "]" + "; upload id [" + uploadId + "]");
return putObjectResult;
}
@Override
public void abortMultipartUpload(String bucketName, String objectName,
String uploadId) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName,
null);
ContentType contentType = ContentType.APPLICATION_JSON;
HashMap params = new HashMap();
params.put("uploadId", uploadId);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.DELETE, contentType, null,
params, null, null);
HttpResponse response = executeHttpRequest(httpRequest,
Action.AbortMultiPartUpload);
processResponse(response, null,
"abort multipart upload of object [" + objectName +
"] to bucket [" + bucketName + "]" +
"; upload id [" + uploadId + "]");
}
@Override
public AccessLogConfig getAccessLogConfig(String bucketName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("accessLog", "");
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetAccessLogConfig);
AccessLogConfig accessLogConfig = (AccessLogConfig) processResponse(response,
AccessLogConfig.class, "Get bucket [" + bucketName + "] access log config");
return accessLogConfig;
}
@Override
public void updateAccessLogConfig(String bucketName, AccessLogConfig accessLogConfig) throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("accessLog", "");
StringEntity requestEntity = getJsonStringEntity(accessLogConfig, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.UpdateAccessLogConfig);
processResponse(response, null, "Update bucket [" + bucketName + "]" +
"access log config");
}
@Override
public LifecycleConfig getLifecycleConfig(final String bucketName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("lifecycle", "");
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null,
null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetLifecycleConfig);
LifecycleConfig lifecycleConfig = processResponse(response, LifecycleConfig.class,
new JsonDeserializer() {
@Override
public LifecycleConfig deserialize(JsonElement json, Type type,
JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
try {
return LifecycleConfig.fromJson(json.toString());
} catch (JSONException e) {
String errorMsg = "Failed to get lifecycle config for bucket " + bucketName;
LOG.error(errorMsg);
throw new JsonParseException(errorMsg, e);
}
}
},
"Get bucket [" + bucketName + "] lifecycle " + "config");
return lifecycleConfig;
}
@Override
public void updateLifecycleConfig(String bucketName, LifecycleConfig lifecycleConfig)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("lifecycle", "");
StringEntity requestEntity;
try {
requestEntity = new StringEntity(lifecycleConfig.toJson(), contentType);
} catch (JSONException e) {
throw new GalaxyFDSClientException(e);
}
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.UpdateLifecycleConfig);
processResponse(response, null, "Update bucket [" + bucketName + "]" +
"lifecycle config");
}
@Override
public void setMirror(String bucketName, String mirrorAddress)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("mirror", "");
StringEntity requestEntity = new StringEntity(mirrorAddress, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.SetMirror);
processResponse(response, null, "Set mirror bucket [" + bucketName + "]");
}
@Override
public String getMirror(String bucketName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("mirror", "");
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null,
null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetMirror);
return (String) processResponse(response, String.class, "Get mirror bucket [" + bucketName + "]");
}
@Override
public void deleteMirror(String bucketName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("mirror", "");
HttpUriRequest httpRequest = prepareRequestMethod(uri,
HttpMethod.DELETE, null, null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteMirror);
processResponse(response, null, "Delete mirror bucket [" + bucketName + "]");
}
@Override
public URI generateAntiStealingUri(String bucketName, String objectName,
Date expiration, String key) throws GalaxyFDSClientException {
return generateAntiStealingUri(fdsConfig.getBaseUri(), bucketName, objectName, expiration, key);
}
private URI generateAntiStealingUri(String baseUri, String bucketName, String objectName,
Date expiration, String key) throws GalaxyFDSClientException {
try {
URI uri = new URI(baseUri);
URI encodeUri = new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(),
"/" + bucketName + "/" + objectName, null, null);
long timestamp = expiration.getTime() / 1000;
String t = Long.toHexString(timestamp).toLowerCase();
String stringToCalc = key + encodeUri.getPath() + t;
String sign = com.xiaomi.infra.galaxy.fds.auth.signature.Utils.calcMD5(stringToCalc);
return new URI(encodeUri.toString() + "?sign=" + sign + "&t=" + t);
} catch (URISyntaxException e) {
LOG.error("Invalid URI syntax", e);
throw new GalaxyFDSClientException("Invalid URI syntax", e);
} catch (NoSuchAlgorithmException nae) {
LOG.error("Unsupported signature algorithm: MD5", nae);
throw new GalaxyFDSClientException("Unsupported signature algorithm: MD5", nae);
} catch (UnsupportedEncodingException uee) {
LOG.error("Unsupported encoding: UTF-8", uee);
throw new GalaxyFDSClientException("Unsupported encoding: UTF-8", uee);
}
}
@Override
public URI generateAntiStealingCdnUri(String bucketName, String objectName,
Date expiration, String key) throws GalaxyFDSClientException {
return generateAntiStealingUri(fdsConfig.getCdnBaseUri(), bucketName, objectName, expiration, key);
}
@Override
public void updateTimestampAntiStealingLinkConfig(String bucketName,
TimestampAntiStealingLinkConfig antiStealingLinkConfig) throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("antiStealingLink", "");
Gson gson = new Gson();
StringEntity requestEntity = new StringEntity(gson.toJson(antiStealingLinkConfig), contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.UpdateAntiStealingLinkConfig);
processResponse(response, null, "Update anti-stealing-link config bucket [" + bucketName + "]");
}
@Override
public TimestampAntiStealingLinkConfig getTimestampAntiStealingLinkConfig(
String bucketName) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("antiStealingLink", "");
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null,
null, params, null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetAntiStealingLinkConfig);
return (TimestampAntiStealingLinkConfig) processResponse(
response, TimestampAntiStealingLinkConfig.class,
"Get anti-stealing-link config bucket [" + bucketName + "]");
}
@Override
public void deleteTimestampAntiStealingLinkConfig(String bucketName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("antiStealingLink", "");
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.DELETE, null, null, params,
null, null);
HttpResponse response = executeHttpRequest(httpRequest, Action.DeleteAntiStealingLinkConfig);
processResponse(response, null, "Delete anti-stealing-link config bucket [" + bucketName + "]");
}
/**
* Put client metrics to server. This method should only be used internally.
*
* @param clientMetrics Metrics to be pushed to server.
* @throws GalaxyFDSClientException
*/
public void putClientMetrics(ClientMetrics clientMetrics)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), "", (SubResource[]) null);
ContentType contentType = ContentType.APPLICATION_JSON;
HashMap params = new HashMap();
params.put("clientMetrics", "");
HttpEntity requestEntity = getJsonStringEntity(clientMetrics, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT,
contentType, null, params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.PutClientMetrics);
processResponse(response, null, "put client metrics");
}
private StringEntity getJsonStringEntity(Object entityContent, ContentType mediaType) {
Gson gson = new Gson();
String jsonStr = "";
if (entityContent != null) {
jsonStr = gson.toJson(entityContent);
}
StringEntity entity = new StringEntity(jsonStr, mediaType);
return entity;
}
private AbstractHttpEntity getRequestEntity(InputStream input,
ContentType contentType) throws GalaxyFDSClientException {
return getRequestEntity(input, contentType, -1/* unknown length*/);
}
private AbstractHttpEntity getRequestEntity(InputStream input,
ContentType contentType, long inputStreamLength) throws GalaxyFDSClientException {
if(fdsConfig.isMd5CalculateEnabled()){
inputStreamLength = -1;
}
if (input instanceof ByteArrayInputStream) {
try {
if (inputStreamLength > Integer.MAX_VALUE ||
// -1 means length unknown, use all data
(inputStreamLength < 0 && inputStreamLength != -1)) {
throw new GalaxyFDSClientException("Invalid length [" +
inputStreamLength + "] for byteArrayInputStream");
}
byte[] data = IOUtils.toByteArray(input);
int len = inputStreamLength >= 0 ? (int)inputStreamLength : data.length;
return new ByteArrayEntity(data, 0, len, contentType);
} catch (IOException e) {
throw new GalaxyFDSClientException("Failed to get content of input stream", e);
}
} else {
BufferedInputStream bufferedInputStream = new BufferedInputStream(input);
InputStreamEntity entity = new InputStreamEntity(bufferedInputStream,
inputStreamLength, contentType);
return entity;
}
}
URI formatUri(String baseUri,
String resource, SubResource... subResourceParams)
throws GalaxyFDSClientException {
String subResource = null;
if (subResourceParams != null) {
for (SubResource param : subResourceParams) {
if (subResource != null) {
subResource += "&" + param.getName();
} else {
subResource = param.getName();
}
}
}
try {
URI uri = new URI(baseUri);
String schema = uri.getScheme();
String host = uri.getHost();
int port = uri.getPort();
URI encodedUri;
if (subResource == null) {
encodedUri = new URI(schema, null, host, port, "/" + resource,
null, null);
} else {
encodedUri = new URI(schema, null, host, port, "/" + resource,
subResource, null);
}
return encodedUri;
} catch (URISyntaxException e) {
LOG.error("Invalid uri syntax", e);
throw new GalaxyFDSClientException("Invalid uri syntax", e);
}
}
Map prepareRequestHeader(URI uri,
HttpMethod method, ContentType contentType, FDSObjectMetadata metadata)
throws GalaxyFDSClientException {
LinkedListMultimap headers = LinkedListMultimap.create();
if (metadata != null) {
for (Entry e : metadata.getRawMetadata().entrySet()) {
headers.put(e.getKey(), e.getValue());
}
}
// Format date
String date = DATE_FORMAT.format(new Date());
headers.put(Common.DATE, date);
// Set content type
if (contentType != null)
headers.put(Common.CONTENT_TYPE, contentType.toString());
// Set unique request id
headers.put(XiaomiHeader.REQUEST_ID.getName(), getUniqueRequestId());
// Set authorization information
String signature;
try {
URI relativeUri = new URI(uri.toString().substring(
uri.toString().indexOf('/', uri.toString().indexOf(':') + 3)));
signature = Signer.signToBase64(method, relativeUri, headers,
credential.getGalaxyAccessSecret(), SIGN_ALGORITHM);
} catch (InvalidKeyException e) {
LOG.error("Invalid secret key spec", e);
throw new GalaxyFDSClientException("Invalid secret key sepc", e);
} catch (NoSuchAlgorithmException e) {
LOG.error("Unsupported signature algorithm:" + SIGN_ALGORITHM, e);
throw new GalaxyFDSClientException("Unsupported signature slgorithm:"
+ SIGN_ALGORITHM, e);
} catch (Exception e) {
throw new GalaxyFDSClientException(e);
}
String authString = "Galaxy-V2 " + credential.getGalaxyAccessId() + ":"
+ signature;
headers.put(Common.AUTHORIZATION, authString);
Map httpHeaders = new HashMap();
for (Entry entry : headers.entries()) {
httpHeaders.put(entry.getKey(), entry.getValue());
}
return httpHeaders;
}
AccessControlList acpToAcl(AccessControlPolicy acp) {
AccessControlList acl = null;
if (acp != null) {
acl = new AccessControlList();
for (GrantBean g : acp.getAccessControlList()) {
acl.addGrant(new AccessControlList.Grant(g.getGrantee().getId(),
g.getPermission(), g.getType()));
}
if (acp.getOwner() != null) {
acl.setOwnerId(acp.getOwner().getId());
}
}
return acl;
}
AccessControlPolicy aclToAcp(AccessControlList acl) {
AccessControlPolicy acp = null;
if (acl != null) {
acp = new AccessControlPolicy();
acp.setOwner(new OwnerBean(credential.getGalaxyAccessId()));
List grants = new ArrayList(
acl.getGrantList().size());
for (AccessControlList.Grant g : acl.getGrantList()) {
grants.add(new GrantBean(new GranteeBean(g.getGranteeId()),
g.getPermission(), g.getType()));
}
acp.setAccessControlList(grants);
}
return acp;
}
FDSObjectListing getObjectListing(ListObjectsResult result) {
FDSObjectListing listing = null;
if (result != null) {
listing = new FDSObjectListing();
listing.setBucketName(result.getName());
listing.setPrefix(result.getPrefix());
listing.setDelimiter(result.getDelimiter());
listing.setMarker(result.getMarker());
listing.setNextMarker(result.getNextMarker());
listing.setMaxKeys(result.getMaxKeys());
listing.setTruncated(result.isTruncated());
listing.setReverse(result.isReverse());
List summaries = new ArrayList(
result.getObjects().size());
for (ObjectBean o : result.getObjects()) {
FDSObjectSummary summary = new FDSObjectSummary();
summary.setBucketName(result.getName());
summary.setObjectName(o.getName());
summary.setSize(o.getSize());
summary.setOwner(new Owner(o.getOwner().getId(),
o.getOwner().getDisplayName()));
summary.setUploadTime(o.getUploadTime());
summaries.add(summary);
}
listing.setObjectSummaries(summaries);
listing.setCommonPrefixes(result.getCommonPrefixes());
}
return listing;
}
private String getUniqueRequestId() {
return clientId + "_" + random.nextInt();
}
private String formatErrorMsg(String purpose, Exception e) {
String msg = "failed to " + purpose + ", " + e.getMessage();
return msg;
}
private String formatErrorMsg(String purpose, HttpResponse response) {
String msg = "failed to " + purpose + ", status=" +
response.getStatusLine().getStatusCode() +
", reason=" + getResponseEntityPhrase(response);
return msg;
}
void closeInputStream(InputStream inputStream) throws GalaxyFDSClientException {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
String errorMsg = "close file input stream failed";
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg, e);
}
}
}
private static URI generatePresignedUri(String baseUri, String bucketName,
String objectName, List subResources, String contentType, Date expiration,
HttpMethod httpMethod, String accessId, String accessSecret,
SignAlgorithm signAlgorithm) throws GalaxyException {
return generatePresignedUri(baseUri, bucketName, objectName,
subResources, contentType, null, expiration, httpMethod, accessId,
accessSecret, signAlgorithm);
}
private static URI generatePresignedUri(String baseUri, String bucketName,
String objectName, List subResources, String contentType, String contentMD5, Date expiration,
HttpMethod httpMethod, String accessId, String accessSecret,
SignAlgorithm signAlgorithm) throws GalaxyException {
URI encodedUri = null;
try {
if (objectName != null && !objectName.isEmpty()) {
objectName = "/" + objectName;
} else {
objectName = "";
}
URI uri = new URI(baseUri);
if (subResources == null || subResources.isEmpty()) {
encodedUri = new URI(uri.getScheme(), null, uri.getHost(),
uri.getPort(), "/" + bucketName + objectName,
Common.GALAXY_ACCESS_KEY_ID + "=" + accessId
+ "&" + Common.EXPIRES + "=" + expiration.getTime(), null);
} else {
encodedUri = new URI(uri.getScheme(), null, uri.getHost(),
uri.getPort(), "/" + bucketName + objectName,
StringUtils.join(subResources, "&") + "&" +
Common.GALAXY_ACCESS_KEY_ID + "=" + accessId
+ "&" + Common.EXPIRES + "=" + expiration.getTime(), null);
}
LinkedListMultimap headers = null;
if (contentType != null && !contentType.isEmpty()) {
headers = LinkedListMultimap.create();
headers.put(Common.CONTENT_TYPE, contentType);
}
if (contentMD5 != null && !contentMD5.isEmpty()) {
if (headers == null) {
headers = LinkedListMultimap.create();
}
headers.put(Common.CONTENT_MD5, contentMD5);
}
String signature = Signer.signToBase64(httpMethod, encodedUri, headers,
accessSecret, signAlgorithm);
return new URI(encodedUri.toString() + "&" + Common.SIGNATURE + "="
+ new String(signature));
} catch (URISyntaxException e) {
LOG.error("Invalid URI syntax", e);
throw new GalaxyException("Invalid URI syntax", e);
} catch (InvalidKeyException e) {
LOG.error("Invalid secret key spec", e);
throw new GalaxyException("Invalid secret key spec", e);
} catch (NoSuchAlgorithmException e) {
LOG.error("Unsupported signature algorithm:" + signAlgorithm, e);
throw new GalaxyException("Unsupported signature algorithm:"
+ signAlgorithm, e);
} catch (UnsupportedEncodingException e) {
LOG.error("Failed to encode the url:" + encodedUri.toString(), e);
throw new GalaxyException("Failed to encode the url:" + encodedUri.toString(), e);
}
}
@Override
public FDSClientConfiguration getFdsConfig(){
return this.fdsConfig;
}
@Override
public CopyObjectResult copyObject(FDSCopyObjectRequest request) throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(),
request.getDstBucketName() + "/" + request.getDstObjectName(), (SubResource[]) null);
ContentType contentType = ContentType.APPLICATION_JSON;
HashMap cp = new HashMap();
cp.put("cp", "");
// Prepare request entity
Map copySrcObject = new HashMap();
copySrcObject.put("srcBucketName", request.getSrcBucketName());
copySrcObject.put("srcObjectName", request.getSrcObjectName());
StringEntity requestEntity = getJsonStringEntity(copySrcObject, contentType);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null, cp, null, requestEntity);
HttpResponse response = executeHttpRequest(httpRequest, Action.CopyObject);
int statusCode = response.getStatusLine().getStatusCode();
return (CopyObjectResult) processResponse(response,
CopyObjectResult.class,
HttpMethod.PUT.name() + " object [" + request.getDstObjectName() + "] to bucket [" + request.getDstBucketName() + "]");
}
@Override
public CopyObjectResult copyObject(String srcBucketName, String srcObjectName, String dstBucketName, String dstObjectName) throws GalaxyFDSClientException {
FDSCopyObjectRequest request = new FDSCopyObjectRequest(srcBucketName, srcObjectName, dstBucketName, dstObjectName);
return copyObject(request);
}
@Override
public CopyObjectResult copyObject(String bucketName, String srcObjectName, String dstObjectName) throws GalaxyFDSClientException {
FDSCopyObjectRequest request = new FDSCopyObjectRequest(bucketName, srcObjectName, bucketName, dstObjectName);
return copyObject(request);
}
private LinkedListMultimap headerArray2MultiValuedMap(Header[] headers) {
LinkedListMultimap m = LinkedListMultimap.create();
if (headers != null)
for (Header h : headers) {
m.put(h.getName(), h.getValue());
}
return m;
}
private void checkAndSetStorageClass(FDSObjectMetadata metadata, String storageClass) throws GalaxyFDSClientException {
if (metadata.getStorageClass() != null &&
!metadata.getStorageClass().toString().equals(storageClass)) {
throw new GalaxyFDSClientException("The storageClass is different from storageClass in meatdata");
}
if (storageClass != null) {
metadata.setStorageClass(StorageClass.fromValue(storageClass));
}
}
@Override public CORSConfiguration getBucketCORSConfiguration(final String bucketName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("cors", "");
HttpUriRequest httpUriRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params,
null, null);
HttpResponse response = executeHttpRequest(httpUriRequest, Action.GetBucketCORSConfiguration);
CORSConfiguration configuration = processResponse(response, CORSConfiguration.class,
new JsonDeserializer() {
@Override public CORSConfiguration deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
try {
return CORSConfiguration.fromJson(json.toString());
} catch (JSONException e) {
String errorMsg = "Failed to get cors configuration for bucket " + bucketName;
LOG.error(errorMsg);
throw new JsonParseException(errorMsg, e);
}
}
}, "get bucket [" + bucketName + "] cors configuration");
return configuration;
}
@Override public CORSRule getBucketCORSRule(String bucketName, final String ruleId)
throws GalaxyFDSClientException {
if (ruleId == null || ruleId.isEmpty()) {
throw new GalaxyFDSClientException("CORS ruleId is empty");
}
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("cors", ruleId);
HttpUriRequest httpUriRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params,
null, null);
HttpResponse response = executeHttpRequest(httpUriRequest, Action.GetBucketCORSRule);
CORSRule corsRule = processResponse(response, CORSRule.class, new JsonDeserializer() {
@Override public CORSRule deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
try {
return CORSRule.fromJson(json.toString());
} catch (JSONException e) {
String errorMsg = "Failed to get CORSRule for ruleId " + ruleId;
LOG.error(errorMsg);
throw new JsonParseException(errorMsg, e);
}
}
}, "get bucket [" + bucketName + "] CORSRule");
return corsRule;
}
@Override public void updateBucketCORSConfiguration(String bucketName,
CORSConfiguration corsConfiguration) throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("cors", "");
StringEntity requestEntity;
try {
requestEntity = new StringEntity(corsConfiguration.toJson(), contentType);
} catch (JSONException e) {
throw new GalaxyFDSClientException(e);
}
HttpUriRequest httpUriRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpUriRequest,
Action.UpdateBucketCORSConfiguration);
processResponse(response, null, "Update bucket [" + bucketName + "]" + " cors configuration");
}
@Override public void addOrUpdateBucketCORSRule(String bucketName, CORSRule rule)
throws GalaxyFDSClientException {
ContentType contentType = ContentType.APPLICATION_JSON;
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("cors", "rule");
StringEntity requestEntity;
try {
requestEntity = new StringEntity(rule.toJson(), contentType);
} catch (JSONException e) {
throw new GalaxyFDSClientException(e);
}
HttpUriRequest httpUriRequest = prepareRequestMethod(uri, HttpMethod.PUT, contentType, null,
params, null, requestEntity);
HttpResponse response = executeHttpRequest(httpUriRequest, Action.AddOrUpdateBucketCORSRule);
processResponse(response, null, "Update bucket [" + bucketName + "]" + " CORSRule");
}
@Override
public Set getRetryMethodSet(){
return retryMethodSet;
}
@Override
public ThirdPartyObject getThirdPartyObject(String bucketName, String objectName)
throws GalaxyFDSClientException {
HashMap params = new HashMap();
params.put("thirdPartyObject", "");
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName + "/" + objectName, (SubResource[]) null);
HttpUriRequest httpRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params, null,
null);
HttpResponse response = executeHttpRequest(httpRequest, Action.GetThirdPartyObject);
ThirdPartyObject thirdPartyObject= null;
int statusCode = response.getStatusLine().getStatusCode();
try {
if (statusCode == HttpStatus.SC_OK) {
FDSObjectMetadata metadata = FDSObjectMetadata
.parseObjectMetadata(headerArray2MultiValuedMap(response.getAllHeaders()));
ThirdPartyObjectBean thirdPartyObjectBean = (ThirdPartyObjectBean) processResponse(response,
ThirdPartyObjectBean.class,
"get third party object for object [" + objectName + "] under bucket [" + bucketName + "]");
thirdPartyObject = new ThirdPartyObject();
thirdPartyObject.setObjectMetadata(metadata);
thirdPartyObject.setThirdPartyObjectBean(thirdPartyObjectBean);
} else if (statusCode == HttpStatus.SC_METHOD_NOT_ALLOWED) {
return null;
} else {
String errorMsg = formatErrorMsg("get third party object for object [" + objectName +
"] under bucket [" + bucketName + "]", response);
throw new GalaxyFDSClientException(errorMsg);
}
} finally {
if (thirdPartyObject == null) {
closeResponseEntity(response);
}
}
return thirdPartyObject;
}
@Override public void setDefaultGifExtractType(String bucketName, String type)
throws GalaxyFDSClientException {
//if type is "unknown", cancel auto gif extract
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("gifType", type);
HttpUriRequest httpUriRequest = prepareRequestMethod(uri, HttpMethod.PUT, null, null, params,
null, null);
HttpResponse response = executeHttpRequest(httpUriRequest, Action.EnableBucketAutoGifExtract);
processResponse(response, null,
"Update bucket [" + bucketName + "]" + " default gif extract type");
}
@Override public String getDefaultGifExtractType(String bucketName)
throws GalaxyFDSClientException {
URI uri = formatUri(fdsConfig.getBaseUri(), bucketName, (SubResource[]) null);
HashMap params = new HashMap();
params.put("gifType", "");
HttpUriRequest httpUriRequest = prepareRequestMethod(uri, HttpMethod.GET, null, null, params,
null, null);
HttpResponse response = executeHttpRequest(httpUriRequest, Action.GetExtractedGif);
String type = processResponse(response, String.class, new JsonDeserializer() {
@Override public String deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
return json.getAsString();
}
}, "Get bucket auto gif extract type");
//if type is "unknown", this bucket not set auto gif extract type
return type;
}
}