use of com.qcloud.cos.internal.ResponseHeaderHandlerChain in project cos-java-sdk-v5 by tencentyun.
the class COSClient method completeMultipartUpload.
@Override
public CompleteMultipartUploadResult completeMultipartUpload(CompleteMultipartUploadRequest completeMultipartUploadRequest) throws CosClientException, CosServiceException {
rejectNull(completeMultipartUploadRequest, "The request parameter must be specified when completing a multipart upload");
String bucketName = completeMultipartUploadRequest.getBucketName();
String key = completeMultipartUploadRequest.getKey();
String uploadId = completeMultipartUploadRequest.getUploadId();
rejectNull(bucketName, "The bucket name parameter must be specified when completing a multipart upload");
rejectNull(key, "The key parameter must be specified when completing a multipart upload");
rejectNull(uploadId, "The upload ID parameter must be specified when completing a multipart upload");
rejectNull(completeMultipartUploadRequest.getPartETags(), "The part ETags parameter must be specified when completing a multipart upload");
rejectNull(clientConfig.getRegion(), "region is null, region in clientConfig must be specified when completing a multipart uploads");
int retries = 0;
CompleteMultipartUploadHandler handler;
do {
CosHttpRequest<CompleteMultipartUploadRequest> request = createRequest(bucketName, key, completeMultipartUploadRequest, HttpMethodName.POST);
request.addParameter("uploadId", uploadId);
byte[] xml = RequestXmlFactory.convertToXmlByteArray(completeMultipartUploadRequest.getPartETags());
request.addHeader("Content-Type", "application/xml");
request.addHeader("Content-Length", String.valueOf(xml.length));
ObjectMetadata objectMetadata = completeMultipartUploadRequest.getObjectMetadata();
if (objectMetadata != null) {
populateRequestMetadata(request, objectMetadata);
}
request.setContent(new ByteArrayInputStream(xml));
if (completeMultipartUploadRequest.getPicOperations() != null) {
request.addHeader(Headers.PIC_OPERATIONS, Jackson.toJsonString(completeMultipartUploadRequest.getPicOperations()));
}
@SuppressWarnings("unchecked") ResponseHeaderHandlerChain<CompleteMultipartUploadHandler> responseHandler = new ResponseHeaderHandlerChain<CompleteMultipartUploadHandler>(// xml payload unmarshaller
new Unmarshallers.CompleteMultipartUploadResultUnmarshaller(), // header handlers
new ServerSideEncryptionHeaderHandler<CompleteMultipartUploadHandler>(), new ObjectExpirationHeaderHandler<CompleteMultipartUploadHandler>(), new VIDResultHandler<CompleteMultipartUploadHandler>());
handler = invoke(request, responseHandler);
if (handler.getCompleteMultipartUploadResult() != null) {
Map<String, String> responseHeaders = responseHandler.getResponseHeaders();
String versionId = responseHeaders.get(Headers.COS_VERSION_ID);
String crc64Ecma = responseHeaders.get(Headers.COS_HASH_CRC64_ECMA);
handler.getCompleteMultipartUploadResult().setVersionId(versionId);
handler.getCompleteMultipartUploadResult().setCrc64Ecma(crc64Ecma);
// if ci request, set ciUploadResult to CompleteMultipartUploadResult
if (completeMultipartUploadRequest.getPicOperations() != null) {
handler.getCompleteMultipartUploadResult().setCiUploadResult(handler.getCiUploadResult());
}
return handler.getCompleteMultipartUploadResult();
}
} while (shouldRetryCompleteMultipartUpload(completeMultipartUploadRequest, handler.getCOSException(), retries++));
throw handler.getCOSException();
}
use of com.qcloud.cos.internal.ResponseHeaderHandlerChain in project cos-java-sdk-v5 by tencentyun.
the class COSClient method copyObject.
@Override
public CopyObjectResult copyObject(CopyObjectRequest copyObjectRequest) throws CosClientException, CosServiceException {
rejectNull(copyObjectRequest, "The CopyObjectRequest parameter must be specified when copying an object");
rejectNull(copyObjectRequest.getSourceBucketName(), "The source bucket name must be specified when copying an object");
rejectNull(copyObjectRequest.getSourceKey(), "The source object key must be specified when copying an object");
rejectNull(copyObjectRequest.getDestinationBucketName(), "The destination bucket name must be specified when copying an object");
rejectNull(copyObjectRequest.getDestinationKey(), "The destination object key must be specified when copying an object");
rejectNull(clientConfig.getRegion(), "region is null, region in clientConfig must be specified when copying an object");
String destinationKey = copyObjectRequest.getDestinationKey();
String destinationBucketName = copyObjectRequest.getDestinationBucketName();
CosHttpRequest<CopyObjectRequest> request = createRequest(destinationBucketName, destinationKey, copyObjectRequest, HttpMethodName.PUT);
populateRequestWithCopyObjectParameters(request, copyObjectRequest);
/*
* We can't send a non-zero length Content-Length header if the user specified it, otherwise
* it messes up the HTTP connection when the remote server thinks there's more data to pull.
*/
setZeroContentLength(request);
CopyObjectResultHandler copyObjectResultHandler = null;
try {
@SuppressWarnings("unchecked") ResponseHeaderHandlerChain<CopyObjectResultHandler> handler = new ResponseHeaderHandlerChain<CopyObjectResultHandler>(// xml payload unmarshaller
new Unmarshallers.CopyObjectUnmarshaller(), // header handlers
new ServerSideEncryptionHeaderHandler<CopyObjectResultHandler>(), new ObjectExpirationHeaderHandler<CopyObjectResultHandler>(), new VIDResultHandler<CopyObjectResultHandler>());
copyObjectResultHandler = invoke(request, handler);
} catch (CosServiceException cse) {
/*
* If the request failed because one of the specified constraints was not met (ex:
* matching ETag, modified since date, etc.), then return null, so that users don't have
* to wrap their code in try/catch blocks and check for this status code if they want to
* use constraints.
*/
if (cse.getStatusCode() == Constants.FAILED_PRECONDITION_STATUS_CODE) {
return null;
}
throw cse;
}
/*
* CopyObject has two failure modes: 1 - An HTTP error code is returned and the error is
* processed like any other error response. 2 - An HTTP 200 OK code is returned, but the
* response content contains an XML error response.
*
* This makes it very difficult for the client runtime to cleanly detect this case and
* handle it like any other error response. We could extend the runtime to have a more
* flexible/customizable definition of success/error (per request), but it's probably
* overkill for this one special case.
*/
if (copyObjectResultHandler.getErrorCode() != null) {
String errorCode = copyObjectResultHandler.getErrorCode();
String errorMessage = copyObjectResultHandler.getErrorMessage();
String requestId = copyObjectResultHandler.getErrorRequestId();
CosServiceException cse = new CosServiceException(errorMessage);
cse.setErrorCode(errorCode);
cse.setRequestId(requestId);
cse.setStatusCode(200);
throw cse;
}
CopyObjectResult copyObjectResult = new CopyObjectResult();
copyObjectResult.setETag(copyObjectResultHandler.getETag());
copyObjectResult.setLastModifiedDate(copyObjectResultHandler.getLastModified());
copyObjectResult.setVersionId(copyObjectResultHandler.getVersionId());
copyObjectResult.setSSEAlgorithm(copyObjectResultHandler.getSSEAlgorithm());
copyObjectResult.setSSECustomerAlgorithm(copyObjectResultHandler.getSSECustomerAlgorithm());
copyObjectResult.setSSECustomerKeyMd5(copyObjectResultHandler.getSSECustomerKeyMd5());
copyObjectResult.setExpirationTime(copyObjectResultHandler.getExpirationTime());
copyObjectResult.setExpirationTimeRuleId(copyObjectResultHandler.getExpirationTimeRuleId());
copyObjectResult.setDateStr(copyObjectResultHandler.getDateStr());
copyObjectResult.setCrc64Ecma(copyObjectResultHandler.getCrc64Ecma());
copyObjectResult.setRequestId(copyObjectResultHandler.getRequestId());
return copyObjectResult;
}
use of com.qcloud.cos.internal.ResponseHeaderHandlerChain in project cos-java-sdk-v5 by tencentyun.
the class COSClient method copyPart.
@Override
public CopyPartResult copyPart(CopyPartRequest copyPartRequest) throws CosClientException, CosServiceException {
rejectNull(copyPartRequest, "The CopyPartRequest parameter must be specified when copying a part");
rejectNull(copyPartRequest.getSourceBucketName(), "The source bucket name must be specified when copying a part");
rejectNull(copyPartRequest.getSourceKey(), "The source object key must be specified when copying a part");
rejectNull(copyPartRequest.getDestinationBucketName(), "The destination bucket name must be specified when copying a part");
rejectNull(copyPartRequest.getUploadId(), "The upload id must be specified when copying a part");
rejectNull(copyPartRequest.getDestinationKey(), "The destination object key must be specified when copying a part");
rejectNull(copyPartRequest.getPartNumber(), "The part number must be specified when copying a part");
rejectNull(clientConfig.getRegion(), "region is null, region in clientConfig must be specified when copying a part");
String destinationKey = copyPartRequest.getDestinationKey();
String destinationBucketName = copyPartRequest.getDestinationBucketName();
CosHttpRequest<CopyPartRequest> request = createRequest(destinationBucketName, destinationKey, copyPartRequest, HttpMethodName.PUT);
populateRequestWithCopyPartParameters(request, copyPartRequest);
request.addParameter("uploadId", copyPartRequest.getUploadId());
request.addParameter("partNumber", Integer.toString(copyPartRequest.getPartNumber()));
/*
* We can't send a non-zero length Content-Length header if the user
* specified it, otherwise it messes up the HTTP connection when the
* remote server thinks there's more data to pull.
*/
setZeroContentLength(request);
CopyObjectResultHandler copyObjectResultHandler = null;
try {
@SuppressWarnings("unchecked") ResponseHeaderHandlerChain<CopyObjectResultHandler> handler = new ResponseHeaderHandlerChain<CopyObjectResultHandler>(// xml payload unmarshaller
new Unmarshallers.CopyObjectUnmarshaller(), // header handlers
new ServerSideEncryptionHeaderHandler<CopyObjectResultHandler>(), new COSVersionHeaderHandler());
copyObjectResultHandler = invoke(request, handler);
} catch (CosServiceException cse) {
/*
* If the request failed because one of the specified constraints
* was not met (ex: matching ETag, modified since date, etc.), then
* return null, so that users don't have to wrap their code in
* try/catch blocks and check for this status code if they want to
* use constraints.
*/
if (cse.getStatusCode() == Constants.FAILED_PRECONDITION_STATUS_CODE) {
return null;
}
throw cse;
}
/*
* CopyPart has two failure modes: 1 - An HTTP error code is returned
* and the error is processed like any other error response. 2 - An HTTP
* 200 OK code is returned, but the response content contains an XML
* error response.
*
* This makes it very difficult for the client runtime to cleanly detect
* this case and handle it like any other error response. We could
* extend the runtime to have a more flexible/customizable definition of
* success/error (per request), but it's probably overkill for this one
* special case.
*/
if (copyObjectResultHandler.getErrorCode() != null) {
String errorCode = copyObjectResultHandler.getErrorCode();
String errorMessage = copyObjectResultHandler.getErrorMessage();
String requestId = copyObjectResultHandler.getErrorRequestId();
CosServiceException cse = new CosServiceException(errorMessage);
cse.setErrorCode(errorCode);
cse.setErrorType(ErrorType.Service);
cse.setRequestId(requestId);
cse.setStatusCode(200);
throw cse;
}
CopyPartResult copyPartResult = new CopyPartResult();
copyPartResult.setETag(copyObjectResultHandler.getETag());
copyPartResult.setPartNumber(copyPartRequest.getPartNumber());
copyPartResult.setLastModifiedDate(copyObjectResultHandler.getLastModified());
copyPartResult.setVersionId(copyObjectResultHandler.getVersionId());
copyPartResult.setSSEAlgorithm(copyObjectResultHandler.getSSEAlgorithm());
copyPartResult.setSSECustomerAlgorithm(copyObjectResultHandler.getSSECustomerAlgorithm());
copyPartResult.setSSECustomerKeyMd5(copyObjectResultHandler.getSSECustomerKeyMd5());
copyPartResult.setCrc64Ecma(copyObjectResultHandler.getCrc64Ecma());
return copyPartResult;
}
use of com.qcloud.cos.internal.ResponseHeaderHandlerChain in project cos-java-sdk-v5 by tencentyun.
the class COSClient method uploadObjectInternal.
protected <UploadObjectRequest extends PutObjectRequest> ObjectMetadata uploadObjectInternal(UploadMode uploadMode, UploadObjectRequest uploadObjectRequest) throws CosClientException, CosServiceException {
rejectNull(uploadObjectRequest, "The PutObjectRequest parameter must be specified when uploading an object");
rejectNull(clientConfig.getRegion(), "region is null, region in clientConfig must be specified when uploading an object");
final File file = uploadObjectRequest.getFile();
final InputStream isOrig = uploadObjectRequest.getInputStream();
final String bucketName = uploadObjectRequest.getBucketName();
final String key = uploadObjectRequest.getKey();
ObjectMetadata metadata = uploadObjectRequest.getMetadata();
InputStream input = isOrig;
if (metadata == null)
metadata = new ObjectMetadata();
rejectNull(bucketName, "The bucket name parameter must be specified when uploading an object");
rejectNull(key, "The key parameter must be specified when uploading an object");
// information from it to auto-configure a few options
if (file == null) {
// unlimited mark-and-reset
if (input != null)
input = ReleasableInputStream.wrap(input);
} else {
// Always set the content length, even if it's already set
metadata.setContentLength(file.length());
final long maxAllowdSingleFileSize = 5 * 1024L * 1024L * 1024L;
if (file.length() > maxAllowdSingleFileSize) {
throw new CosClientException("max size 5GB is allowed by putObject Method, your filesize is " + file.length() + ", please use transferManager to upload big file!");
}
final boolean calculateMD5 = metadata.getContentMD5() == null;
if (calculateMD5 && !skipMd5CheckStrategy.skipServerSideValidation(uploadObjectRequest)) {
try {
String contentMd5_b64 = Md5Utils.md5AsBase64(file);
metadata.setContentMD5(contentMd5_b64);
} catch (Exception e) {
throw new CosClientException("Unable to calculate MD5 hash: " + e.getMessage(), e);
}
}
input = ResettableInputStream.newResettableInputStream(file, "Unable to find file to upload");
}
final ObjectMetadata returnedMetadata;
MD5DigestCalculatingInputStream md5DigestStream = null;
try {
CosHttpRequest<UploadObjectRequest> request = null;
if (uploadMode.equals(UploadMode.PUT_OBJECT)) {
request = createRequest(bucketName, key, uploadObjectRequest, HttpMethodName.PUT);
} else if (uploadMode.equals(UploadMode.APPEND_OBJECT)) {
request = createRequest(bucketName, key, uploadObjectRequest, HttpMethodName.POST);
AppendObjectRequest appendObjectRequest = (AppendObjectRequest) uploadObjectRequest;
String positionStr = String.valueOf(appendObjectRequest.getPosition());
request.addParameter("append", null);
request.addParameter("position", positionStr);
}
if (uploadObjectRequest.getAccessControlList() != null) {
addAclHeaders(request, uploadObjectRequest.getAccessControlList());
} else if (uploadObjectRequest.getCannedAcl() != null) {
request.addHeader(Headers.COS_CANNED_ACL, uploadObjectRequest.getCannedAcl().toString());
}
if (uploadObjectRequest.getStorageClass() != null) {
request.addHeader(Headers.STORAGE_CLASS, uploadObjectRequest.getStorageClass());
}
if (uploadObjectRequest.getRedirectLocation() != null) {
request.addHeader(Headers.REDIRECT_LOCATION, uploadObjectRequest.getRedirectLocation());
if (input == null) {
input = new ByteArrayInputStream(new byte[0]);
}
}
// Populate the SSE-C parameters to the request header
populateSSE_C(request, uploadObjectRequest.getSSECustomerKey());
// Populate the SSE KMS parameters to the request header
populateSSE_KMS(request, uploadObjectRequest.getSSECOSKeyManagementParams());
// Populate the traffic limit parameter to the request header
populateTrafficLimit(request, uploadObjectRequest.getTrafficLimit());
// Use internal interface to differentiate 0 from unset.
final Long contentLength = (Long) metadata.getRawMetadataValue(Headers.CONTENT_LENGTH);
if (contentLength == null) {
/*
* There's nothing we can do except for let the HTTP client buffer the input stream
* contents if the caller doesn't tell us how much data to expect in a stream since
* we have to explicitly tell how much we're sending before we start sending any of
* it.
*/
log.warn("No content length specified for stream data. " + "Stream contents will be buffered in memory and could result in " + "out of memory errors.");
} else {
final long expectedLength = contentLength.longValue();
final long maxAllowdSingleFileSize = 5 * 1024L * 1024L * 1024L;
if (expectedLength > maxAllowdSingleFileSize) {
throw new CosClientException("max size 5GB is allowed by putObject Method, your filesize is " + expectedLength + ", please use transferManager to upload big file!");
}
if (expectedLength >= 0) {
// Performs length check on the underlying data stream.
// For COS encryption client, the underlying data stream here
// refers to the cipher-text data stream (ie not the underlying
// plain-text data stream which in turn may have been wrapped
// with it's own length check input stream.)
LengthCheckInputStream lcis = new // expected
LengthCheckInputStream(// expected
input, // expected
expectedLength, // uploaded
EXCLUDE_SKIPPED_BYTES);
input = lcis;
}
}
if (metadata.getContentMD5() == null && !skipMd5CheckStrategy.skipClientSideValidationPerRequest(uploadObjectRequest)) {
/*
* If the user hasn't set the content MD5, then we don't want to buffer the whole
* stream in memory just to calculate it. Instead, we can calculate it on the fly
* and validate it with the returned ETag from the object upload.
*/
input = md5DigestStream = new MD5DigestCalculatingInputStream(input);
}
populateRequestMetadata(request, metadata);
request.setContent(input);
try {
if (uploadObjectRequest.getPicOperations() != null) {
request.addHeader(Headers.PIC_OPERATIONS, Jackson.toJsonString(uploadObjectRequest.getPicOperations()));
returnedMetadata = invoke(request, new ResponseHeaderHandlerChain<ObjectMetadata>(new Unmarshallers.ImagePersistenceUnmarshaller(), new CosMetadataResponseHandler()));
} else {
returnedMetadata = invoke(request, new CosMetadataResponseHandler());
}
} catch (Throwable t) {
throw Throwables.failure(t);
}
} finally {
CosDataSource.Utils.cleanupDataSource(uploadObjectRequest, file, isOrig, input, log);
}
String contentMd5 = metadata.getContentMD5();
if (md5DigestStream != null) {
contentMd5 = Base64.encodeAsString(md5DigestStream.getMd5Digest());
}
final String etag = returnedMetadata.getETag();
if (contentMd5 != null && uploadMode.equals(UploadMode.PUT_OBJECT) && !skipMd5CheckStrategy.skipClientSideValidationPerPutResponse(returnedMetadata)) {
byte[] clientSideHash = BinaryUtils.fromBase64(contentMd5);
byte[] serverSideHash = null;
try {
serverSideHash = BinaryUtils.fromHex(etag);
} catch (DecoderException e) {
throw new CosClientException("Unable to verify integrity of data upload. " + "Client calculated content hash (contentMD5: " + contentMd5 + " in base 64) didn't match hash (etag: " + etag + " in hex) calculated by COS . " + "You may need to delete the data stored in COS . (metadata.contentMD5: " + metadata.getContentMD5() + ", bucketName: " + bucketName + ", key: " + key + ")");
}
if (!Arrays.equals(clientSideHash, serverSideHash)) {
throw new CosClientException("Unable to verify integrity of data upload. " + "Client calculated content hash (contentMD5: " + contentMd5 + " in base 64) didn't match hash (etag: " + etag + " in hex) calculated by COS . " + "You may need to delete the data stored in COS . (metadata.contentMD5: " + metadata.getContentMD5() + ", bucketName: " + bucketName + ", key: " + key + ")");
}
}
return returnedMetadata;
}
use of com.qcloud.cos.internal.ResponseHeaderHandlerChain in project cos-java-sdk-v5 by tencentyun.
the class COSClient method setObjectTagging.
@Override
public SetObjectTaggingResult setObjectTagging(SetObjectTaggingRequest setObjectTaggingRequest) {
rejectNull(setObjectTaggingRequest, "The request parameter must be specified setting the object tags");
rejectNull(setObjectTaggingRequest.getBucketName(), "The request bucketName must be specified setting the object tags");
rejectNull(setObjectTaggingRequest.getKey(), "The request key must be specified setting the object tags");
rejectNull(setObjectTaggingRequest.getTagging(), "The request tagging must be specified setting the object tags");
CosHttpRequest<SetObjectTaggingRequest> request = createRequest(setObjectTaggingRequest.getBucketName(), setObjectTaggingRequest.getKey(), setObjectTaggingRequest, HttpMethodName.PUT);
request.addParameter("tagging", null);
addParameterIfNotNull(request, "versionId", setObjectTaggingRequest.getVersionId());
byte[] content = new ObjectTaggingXmlFactory().convertToXmlByteArray(setObjectTaggingRequest.getTagging());
setContent(request, content, "application/xml", true);
ResponseHeaderHandlerChain<SetObjectTaggingResult> handlerChain = new ResponseHeaderHandlerChain<SetObjectTaggingResult>(new Unmarshallers.SetObjectTaggingResponseUnmarshaller(), new SetObjectTaggingResponseHeaderHandler());
return invoke(request, handlerChain);
}
Aggregations