Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/main/java/com/aliyun/oss/OSS.java
Original file line number Diff line number Diff line change
Expand Up @@ -4185,7 +4185,7 @@ public String generateRtmpUri(GenerateRtmpUriRequest generatePushflowUrlRequest)
* must be closed by the calller to release connection via calling
* getResponse().getContent().close().
* </p>
*
*
* @param processObjectRequest
* A {@link ProcessObjectRequest} instance that specifies the
* bucket name, the object key and the process (such as
Expand Down Expand Up @@ -5101,4 +5101,27 @@ public UdfApplicationLog getUdfApplicationLog(GetUdfApplicationLogRequest getUdf
* If any errors occurred in OSS while processing the request.
*/
VoidResult closeMetaQuery(String bucketName) throws OSSException, ClientException;

/**
* Apply async process on the specified image file.
* <p>
* The supported async process includes resize, rotate, crop, watermark, format,
* udf, customized style, etc. The {@link GenericResult} instance returned
* must be closed by the calller to release connection via calling
* getResponse().getContent().close().
* </p>
*
* @param asyncProcessObjectRequest
* A {@link AsyncProcessObjectRequest} instance that specifies the
* bucket name, the object key and the process (such as
* video/convert,f_mp4,vcodec_h265,s_1920x1080,vb_2000000,fps_30,acodec_aac,ab_100000,sn_1)
* @return A {@link AsyncProcessObjectResult} instance which must be closed after the
* usage by the caller.
* @throws OSSException
* If any errors are encountered in the client while making the
* request or handling the response.
* @throws ClientException
* If any errors occurred in OSS while processing the request.
*/
public AsyncProcessObjectResult asyncProcessObject(AsyncProcessObjectRequest asyncProcessObjectRequest) throws OSSException, ClientException;
}
5 changes: 5 additions & 0 deletions src/main/java/com/aliyun/oss/OSSClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -1957,6 +1957,11 @@ public VoidResult closeMetaQuery(String bucketName) throws OSSException, ClientE
return this.bucketOperation.closeMetaQuery(new GenericRequest(bucketName));
}

@Override
public AsyncProcessObjectResult asyncProcessObject(AsyncProcessObjectRequest asyncProcessObjectRequest) throws OSSException, ClientException {
return this.objectOperation.asyncProcessObject(asyncProcessObjectRequest);
}

@Override
public void shutdown() {
try {
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/aliyun/oss/common/parser/RequestMarshallers.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public final class RequestMarshallers {
public static final PutBucketTransferAccelerationRequestMarshaller putBucketTransferAccelerationRequestMarshaller = new PutBucketTransferAccelerationRequestMarshaller();
public static final PutBucketAccessMonitorRequestMarshaller putBucketAccessMonitorRequestMarshaller = new PutBucketAccessMonitorRequestMarshaller();
public static final DoMetaQueryRequestMarshaller doMetaQueryRequestMarshaller = new DoMetaQueryRequestMarshaller();
public static final AsyncProcessObjectRequestMarshaller asyncProcessObjectRequestMarshaller = new AsyncProcessObjectRequestMarshaller();

public interface RequestMarshaller<R> extends Marshaller<FixedLengthInputStream, R> {

Expand Down Expand Up @@ -1863,6 +1864,26 @@ public byte[] marshall(DoMetaQueryRequest input) {
}
}

public static final class AsyncProcessObjectRequestMarshaller implements RequestMarshaller2<AsyncProcessObjectRequest> {

@Override
public byte[] marshall(AsyncProcessObjectRequest request) {
StringBuffer processBody = new StringBuffer();

processBody.append(RequestParameters.X_OSS_ASYNC_PROCESS);
processBody.append("=" + request.getProcess());

byte[] rawData = null;
try {
rawData = processBody.toString().getBytes(DEFAULT_CHARSET_NAME);
} catch (UnsupportedEncodingException e) {
throw new ClientException("Unsupported encoding " + e.getMessage(), e);
}
return rawData;
}

}

private static enum EscapedChar {
// "\r"
RETURN("&#x000D;"),
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/com/aliyun/oss/internal/OSSObjectOperation.java
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,36 @@ private static void populateGetObjectRequestHeaders(GetObjectRequest getObjectRe
populateTrafficLimitHeader(headers, getObjectRequest.getTrafficLimit());
}

public AsyncProcessObjectResult asyncProcessObject(AsyncProcessObjectRequest asyncProcessObjectRequest) throws OSSException, ClientException {

assertParameterNotNull(asyncProcessObjectRequest, "asyncProcessObjectRequest");

String bucketName = asyncProcessObjectRequest.getBucketName();
String key = asyncProcessObjectRequest.getKey();
String process = asyncProcessObjectRequest.getProcess();

assertParameterNotNull(bucketName, "bucketName");
ensureBucketNameValid(bucketName);
assertParameterNotNull(key, "key");
ensureObjectKeyValid(key);
assertStringNotNullOrEmpty(process, "process");

Map<String, String> params = new HashMap<String, String>();
params.put(RequestParameters.X_OSS_ASYNC_PROCESS, null);

Map<String, String> headers = new HashMap<String, String>();
populateRequestPayerHeader(headers, asyncProcessObjectRequest.getRequestPayer());

byte[] rawContent = asyncProcessObjectRequestMarshaller.marshall(asyncProcessObjectRequest);

RequestMessage request = new OSSRequestMessageBuilder(getInnerClient()).setEndpoint(getEndpoint(asyncProcessObjectRequest))
.setMethod(HttpMethod.POST).setBucket(bucketName).setKey(key).setHeaders(headers).setParameters(params)
.setInputSize(rawContent.length).setInputStream(new ByteArrayInputStream(rawContent))
.setOriginalRequest(asyncProcessObjectRequest).build();

return doOperation(request, ResponseParsers.asyncProcessObjectResponseParser, bucketName, key, true);
}

private static void addDeleteObjectsRequiredHeaders(Map<String, String> headers, byte[] rawContent) {
headers.put(HttpHeaders.CONTENT_LENGTH, String.valueOf(rawContent.length));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,6 @@ public final class RequestParameters {
public static final String ACCESS_MONITOR = "accessmonitor";

public static final String SUBRESOURCE_REGION_LIST = "regionList";
public static final String X_OSS_ASYNC_PROCESS = "x-oss-async-process";

}
44 changes: 44 additions & 0 deletions src/main/java/com/aliyun/oss/internal/ResponseParsers.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static com.aliyun.oss.internal.OSSUtils.safeCloseResponse;
import static com.aliyun.oss.internal.OSSUtils.trimQuotes;

import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
Expand All @@ -37,8 +38,11 @@
import java.util.Map;
import java.util.zip.CheckedInputStream;

import com.aliyun.oss.common.utils.IOUtils;
import com.aliyun.oss.internal.model.OSSErrorResult;
import com.aliyun.oss.model.*;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.JDOMParseException;
Expand Down Expand Up @@ -141,6 +145,7 @@ public final class ResponseParsers {
public static final GetBucketAccessMonitorResponseParser getBucketAccessMonitorResponseParser = new GetBucketAccessMonitorResponseParser();
public static final GetMetaQueryStatusResponseParser getMetaQueryStatusResponseParser = new GetMetaQueryStatusResponseParser();
public static final DoMetaQueryResponseParser doMetaQueryResponseParser = new DoMetaQueryResponseParser();
public static final AsyncProcessObjectResponseParser asyncProcessObjectResponseParser = new AsyncProcessObjectResponseParser();

public static Long parseLongWithDefault(String defaultValue){
if(defaultValue == null || "".equals(defaultValue)){
Expand Down Expand Up @@ -4157,4 +4162,43 @@ private DoMetaQueryResult parseDoMetaQueryResult(InputStream inputStream) throws
}
}
}

public static final class AsyncProcessObjectResponseParser implements ResponseParser<AsyncProcessObjectResult> {

@Override
public AsyncProcessObjectResult parse(ResponseMessage response) throws ResponseParseException {
AsyncProcessObjectResult result = parseAsyncProcessObject(response.getContent());
setResultParameter(result, response);
return result;
}

private AsyncProcessObjectResult parseAsyncProcessObject(InputStream inputStream) throws ResponseParseException {
AsyncProcessObjectResult asyncProcessObjectResult = new AsyncProcessObjectResult();
if (inputStream == null) {
return asyncProcessObjectResult;
}

try {
String jsonStr = null;
try {
jsonStr = IOUtils.readStreamAsString(inputStream, "UTF-8");
JSONObject jsonObject = new JSONObject(jsonStr);
asyncProcessObjectResult.setAsyncRequestId(jsonObject.getString("RequestId"));
asyncProcessObjectResult.setEventId(jsonObject.getString("EventId"));
asyncProcessObjectResult.setTaskId(jsonObject.getString("TaskId"));
} catch (IOException e) {
throw new ResponseParseException(e.getMessage(), e);
} catch (JSONException e) {
throw new ResponseParseException(e.getMessage(), e);
} finally {
if (inputStream != null){
inputStream.close();
}
}
return asyncProcessObjectResult;
} catch (Exception e) {
throw new ResponseParseException(e.getMessage(), e);
}
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/aliyun/oss/internal/SignParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ public class SignParameters {
SUBRESOURCE_WORM_ID, SUBRESOURCE_WORM_EXTEND, SUBRESOURCE_CALLBACK, SUBRESOURCE_CALLBACK_VAR,
SUBRESOURCE_DIR, SUBRESOURCE_RENAME, SUBRESOURCE_DIR_DELETE, SUBRESOURCE_TRANSFER_ACCELERATION,
X_OSS_AC_SOURCE_IP, X_OSS_AC_SUBNET_MASK, X_OSS_AC_VPC_ID, X_OSS_AC_FORWARD_ALLOW, META_QUERY, SUBRESOURCE_RESOURCE_GROUP,
SUBRESOURCE_REGION_LIST});
SUBRESOURCE_REGION_LIST, X_OSS_ASYNC_PROCESS});

}
25 changes: 25 additions & 0 deletions src/main/java/com/aliyun/oss/model/AsyncProcessObjectRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.aliyun.oss.model;


public class AsyncProcessObjectRequest extends GenericRequest {

public AsyncProcessObjectRequest(String bucketName, String key, String process) {
super(bucketName, key);
this.process = process;
}

public String getProcess() {
return process;
}

public void setProcess(String process) {
this.process = process;
}

public AsyncProcessObjectRequest withProcess(String process) {
this.process = process;
return this;
}

private String process;
}
32 changes: 32 additions & 0 deletions src/main/java/com/aliyun/oss/model/AsyncProcessObjectResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.aliyun.oss.model;

public class AsyncProcessObjectResult extends GenericResult {

private String asyncRequestId;
private String eventId;
private String taskId;

public String getAsyncRequestId() {
return asyncRequestId;
}

public void setAsyncRequestId(String asyncRequestId) {
this.asyncRequestId = asyncRequestId;
}

public String getEventId() {
return eventId;
}

public void setEventId(String eventId) {
this.eventId = eventId;
}

public String getTaskId() {
return taskId;
}

public void setTaskId(String taskId) {
this.taskId = taskId;
}
}
52 changes: 52 additions & 0 deletions src/samples/AsyncProcessObjectSample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package samples;

import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.*;

public class AsyncProcessObjectSample {
private static String endpoint = "<endpoint, http://oss-cn-hangzhou.aliyuncs.com>";
private static String accessKeyId = "<accessKeyId>";
private static String accessKeySecret = "<accessKeySecret>";
private static String bucketName = "<bucketName>";
private static final String saveAsKey = "<syncSaveObjectName>";
private static final String key = "<objectName>";

public static void main(String[] args) {
/*
* Constructs a client instance with your account for accessing OSS
*/
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
StringBuilder styleBuilder = new StringBuilder();
styleBuilder.append("video/convert,f_mp4,vcodec_h265,s_1920x1080,vb_2000000,fps_30,acodec_aac,ab_100000,sn_1"); // resize
styleBuilder.append("|sys/saveas,");
styleBuilder.append("o_" + BinaryUtil.toBase64String(saveAsKey.getBytes()).replaceAll("=", ""));
styleBuilder.append(",");
styleBuilder.append("b_" + BinaryUtil.toBase64String(bucketName.getBytes()).replaceAll("=", ""));

AsyncProcessObjectRequest request = new AsyncProcessObjectRequest(bucketName, key, styleBuilder.toString());

AsyncProcessObjectResult asyncProcessObject = ossClient.asyncProcessObject(request);
System.out.println(asyncProcessObject.getAsyncRequestId());
System.out.println(asyncProcessObject.getEventId());
System.out.println(asyncProcessObject.getTaskId());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message: " + oe.getMessage());
System.out.println("Error Code: " + oe.getErrorCode());
System.out.println("Request ID: " + oe.getRequestId());
System.out.println("Host ID: " + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message: " + ce.getMessage());
} finally {
/*
* Do not forget to shut down the client finally to release all allocated resources.
*/
ossClient.shutdown();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.comm.io.FixedLengthInputStream;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.common.utils.DateUtil;
import com.aliyun.oss.model.*;
import junit.framework.Assert;
Expand Down Expand Up @@ -1413,4 +1414,27 @@ public void testPutLifeCycleRequestMarshaller() {
Assert.assertEquals("key2", root.getChild("Rule").getChild("Filter").getChildren("Not").get(1).getChild("Tag").getChildText("Key"));
Assert.assertEquals("value2", root.getChild("Rule").getChild("Filter").getChildren("Not").get(1).getChild("Tag").getChildText("Value"));
}

@Test
public void testAsyncProcessObjectRequestMarshaller() {
String saveAsKey = "outobjprefix.mp4";
String originalVideo = "test-video.mp4/example.mp4";
String bucketName = "example-bucket";
StringBuilder styleBuilder = new StringBuilder();
styleBuilder.append("test-video.mp4/convert,f_mp4,vcodec_h265,s_1920x1080,vb_2000000,fps_30,acodec_aac,ab_100000,sn_1"); // resize
styleBuilder.append("|sys/saveas,");
styleBuilder.append("o_" + BinaryUtil.toBase64String(saveAsKey.getBytes()).replaceAll("=", ""));
styleBuilder.append(",");
styleBuilder.append("b_" + BinaryUtil.toBase64String(bucketName.getBytes()).replaceAll("=", ""));
AsyncProcessObjectRequest request = new AsyncProcessObjectRequest(bucketName, originalVideo, styleBuilder.toString());

byte[] data = asyncProcessObjectRequestMarshaller.marshall(request);

String returnData = new String(data);

String style = styleBuilder.toString();

Assert.assertTrue(returnData.equals("x-oss-async-process="+style.replaceAll("=","")));
}

}
Loading