diff --git a/examples/build.gradle b/examples/build.gradle index a75ea9e..5c31b8f 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -10,11 +10,13 @@ sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { + mavenCentral() jcenter() } dependencies { implementation rootProject + implementation 'io.tus.java.client:tus-java-client:0.5.1' implementation 'org.json:json:20231013' } buildscript { @@ -37,3 +39,13 @@ compileTestKotlin { jvmTarget.set(JvmTarget.JVM_1_8) } } + +tasks.register('api2DevdockTemplateLifecycle', JavaExec) { + classpath = sourceSets.main.runtimeClasspath + mainClass = 'com.transloadit.examples.Api2DevdockTemplateLifecycle' +} + +tasks.register('api2DevdockTusAssembly', JavaExec) { + classpath = sourceSets.main.runtimeClasspath + mainClass = 'com.transloadit.examples.Api2DevdockTusAssembly' +} diff --git a/examples/src/main/java/com/transloadit/examples/Api2DevdockTemplateLifecycle.java b/examples/src/main/java/com/transloadit/examples/Api2DevdockTemplateLifecycle.java new file mode 100644 index 0000000..ee19673 --- /dev/null +++ b/examples/src/main/java/com/transloadit/examples/Api2DevdockTemplateLifecycle.java @@ -0,0 +1,177 @@ +package com.transloadit.examples; + +import com.transloadit.sdk.Transloadit; +import com.transloadit.sdk.response.ListResponse; +import com.transloadit.sdk.response.Response; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Runs API2's contract-owned Template lifecycle scenario against devdock. + */ +public final class Api2DevdockTemplateLifecycle { + /** + * Runs the Template lifecycle scenario. + * + * @param args ignored + * @throws Exception if the scenario cannot be completed + */ + public static void main(String[] args) throws Exception { + JSONObject scenario = loadScenario(); + Transloadit transloadit = new Transloadit( + requiredEnv("TRANSLOADIT_KEY"), + requiredEnv("TRANSLOADIT_SECRET"), + requiredEnv("TRANSLOADIT_ENDPOINT")); + + JSONObject templateConfig = scenario.getJSONObject("template"); + JSONObject updateConfig = scenario.getJSONObject("update"); + String templateName = templateConfig.getString("namePrefix") + "-" + System.currentTimeMillis(); + + Response created = transloadit.createTemplate(templatePayload(templateName, templateConfig)); + String templateId = created.json().getString("id"); + boolean deleteTemplate = true; + + try { + Response fetched = transloadit.getTemplate(templateId); + + Map listOptions = new HashMap(); + listOptions.put("pagesize", scenario.getJSONObject("list").getInt("pageSize")); + ListResponse listed = transloadit.listTemplates(listOptions); + + String updatedTemplateName = templateName + updateConfig.getString("nameSuffix"); + transloadit.updateTemplate(templateId, templatePayload(updatedTemplateName, updateConfig)); + Response updated = transloadit.getTemplate(templateId); + + transloadit.deleteTemplate(templateId); + deleteTemplate = false; + + JSONObject result = new JSONObject(); + JSONObject deletedGet = deletedGetResult(transloadit, templateId); + for (Iterator keys = deletedGet.keys(); keys.hasNext();) { + String key = keys.next(); + result.put(key, deletedGet.get(key)); + } + result.put("fetched", templateResult(fetched.json())); + result.put("listCount", listed.size()); + result.put("templateId", templateId); + result.put("templateName", templateName); + result.put("updated", templateResult(updated.json())); + result.put("updatedTemplateName", updatedTemplateName); + writeResult(result); + } finally { + if (deleteTemplate) { + transloadit.deleteTemplate(templateId); + } + } + + System.out.println("Java SDK devdock scenario " + scenario.getString("scenarioId") + + " passed for " + templateId); + } + + private static JSONObject deletedGetResult(Transloadit transloadit, String templateId) throws Exception { + Response response = transloadit.getTemplate(templateId); + JSONObject body = response.json(); + boolean succeeded = response.status() >= 200 && response.status() < 300 && !body.has("error"); + + JSONObject result = new JSONObject(); + result.put("deletedGetSucceeded", succeeded); + result.put("deletedErrorCode", body.optString("error", body.optString("ok", ""))); + return result; + } + + private static JSONObject loadScenario() throws Exception { + String scenarioPath = System.getenv("API2_SDK_EXAMPLE_SCENARIO"); + if (scenarioPath == null || scenarioPath.isEmpty()) { + scenarioPath = "examples/api2-devdock-template-lifecycle/api2-scenario.json"; + } + + byte[] contents = Files.readAllBytes(Paths.get(scenarioPath)); + return new JSONObject(new String(contents, StandardCharsets.UTF_8)); + } + + private static String requiredEnv(String name) { + String value = System.getenv(name); + if (value == null || value.isEmpty()) { + throw new IllegalStateException(name + " must be set"); + } + + return value; + } + + private static Map templatePayload(String name, JSONObject config) { + JSONObject content = config.getJSONObject("content"); + Map template = jsonObjectToMap(content.getJSONObject("additionalProperties")); + template.put("steps", jsonObjectToMap(content.getJSONObject("steps"))); + + Map payload = new HashMap(); + payload.put("name", name); + payload.put("require_signature_auth", config.getBoolean("requireSignatureAuth") ? 1 : 0); + payload.put("template", template); + return payload; + } + + private static JSONObject templateResult(JSONObject template) { + JSONObject result = new JSONObject(); + result.put("content", template.getJSONObject("content")); + result.put("id", template.getString("id")); + result.put("name", template.getString("name")); + result.put("requireSignatureAuth", template.getInt("require_signature_auth") != 0); + return result; + } + + private static Map jsonObjectToMap(JSONObject object) { + Map map = new HashMap(); + for (Iterator keys = object.keys(); keys.hasNext();) { + String key = keys.next(); + map.put(key, jsonValueToJava(object.get(key))); + } + + return map; + } + + private static Object jsonValueToJava(Object value) { + if (value == JSONObject.NULL) { + return null; + } + + if (value instanceof JSONObject) { + return jsonObjectToMap((JSONObject) value); + } + + if (value instanceof JSONArray) { + JSONArray array = (JSONArray) value; + List list = new ArrayList(); + for (int index = 0; index < array.length(); index += 1) { + list.add(jsonValueToJava(array.get(index))); + } + + return list; + } + + return value; + } + + private static void writeResult(JSONObject result) throws Exception { + String resultPath = System.getenv("API2_SDK_EXAMPLE_RESULT"); + if (resultPath == null || resultPath.isEmpty()) { + return; + } + + Files.write( + Paths.get(resultPath), + (result.toString(2) + "\n").getBytes(StandardCharsets.UTF_8)); + } + + private Api2DevdockTemplateLifecycle() { + throw new IllegalStateException("Utility class"); + } +} diff --git a/examples/src/main/java/com/transloadit/examples/Api2DevdockTusAssembly.java b/examples/src/main/java/com/transloadit/examples/Api2DevdockTusAssembly.java new file mode 100644 index 0000000..53ba376 --- /dev/null +++ b/examples/src/main/java/com/transloadit/examples/Api2DevdockTusAssembly.java @@ -0,0 +1,106 @@ +package com.transloadit.examples; + +import com.transloadit.sdk.Transloadit; +import com.transloadit.sdk.UploadTusAssemblyResult; +import org.json.JSONObject; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Runs API2's contract-owned TUS Assembly scenario against devdock. + */ +public final class Api2DevdockTusAssembly { + /** + * Runs the TUS Assembly scenario. + * + * @param args ignored + * @throws Exception if the scenario cannot be completed + */ + public static void main(String[] args) throws Exception { + JSONObject scenario = loadScenario(); + Transloadit transloadit = new Transloadit( + requiredEnv("TRANSLOADIT_KEY"), + requiredEnv("TRANSLOADIT_SECRET"), + requiredEnv("TRANSLOADIT_ENDPOINT")); + + JSONObject exampleInput = scenario.getJSONObject("exampleInput"); + JSONObject input = exampleInput + .getJSONObject("sdkFeatureInputs") + .getJSONObject("uploadTusAssembly"); + int fileCount = input.getInt("file_count"); + + JSONObject uploadConfig = input.getJSONObject("upload"); + byte[] bytes = uploadConfig.getString("content").getBytes(StandardCharsets.UTF_8); + UploadTusAssemblyResult uploadResult = transloadit.uploadTusAssembly( + fileCount, + bytes, + uploadConfig.getString("fieldname"), + uploadConfig.getString("filename"), + uploadUserMeta(uploadConfig)); + JSONObject status = uploadResult.getAssembly().json(); + + JSONObject result = new JSONObject(); + result.put("createResponse", status); + result.put("status", status); + result.put("uploadUrl", uploadResult.getUploadUrl()); + writeResult(result); + + System.out.println("Java SDK devdock scenario " + exampleInput.getString("scenarioId") + + " uploaded to " + uploadResult.getUploadUrl() + + " and finished with " + status.getString("ok")); + } + + private static JSONObject loadScenario() throws Exception { + String scenarioPath = System.getenv("API2_SDK_EXAMPLE_SCENARIO"); + if (scenarioPath == null || scenarioPath.isEmpty()) { + scenarioPath = "examples/api2-devdock-tus-assembly/api2-scenario.json"; + } + + byte[] contents = Files.readAllBytes(Paths.get(scenarioPath)); + return new JSONObject(new String(contents, StandardCharsets.UTF_8)); + } + + private static String requiredEnv(String name) { + String value = System.getenv(name); + if (value == null || value.isEmpty()) { + throw new IllegalStateException(name + " must be set"); + } + + return value; + } + + private static Map uploadUserMeta(JSONObject uploadConfig) { + Map metadata = new HashMap(); + if (!uploadConfig.has("user_meta")) { + return metadata; + } + + JSONObject userMeta = uploadConfig.getJSONObject("user_meta"); + for (Iterator keys = userMeta.keys(); keys.hasNext();) { + String key = keys.next(); + metadata.put(key, String.valueOf(userMeta.get(key))); + } + + return metadata; + } + + private static void writeResult(JSONObject result) throws Exception { + String resultPath = System.getenv("API2_SDK_EXAMPLE_RESULT"); + if (resultPath == null || resultPath.isEmpty()) { + return; + } + + Files.write( + Paths.get(resultPath), + (result.toString(2) + "\n").getBytes(StandardCharsets.UTF_8)); + } + + private Api2DevdockTusAssembly() { + throw new IllegalStateException("Utility class"); + } +} diff --git a/settings.gradle b/settings.gradle index 6110b74..dc30395 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ // Uncomment following line if you want to use the local java-sdk // for the example instead of pulling the JARs from JCenter. // This is useful for debugging and testing new features. -// include ':examples' -rootProject.name = 'transloadit' \ No newline at end of file +include ':examples' +rootProject.name = 'transloadit' diff --git a/src/main/java/com/transloadit/sdk/Transloadit.java b/src/main/java/com/transloadit/sdk/Transloadit.java index 57b95f8..ecb6e8a 100644 --- a/src/main/java/com/transloadit/sdk/Transloadit.java +++ b/src/main/java/com/transloadit/sdk/Transloadit.java @@ -319,6 +319,166 @@ public Assembly newAssembly() { return new Assembly(this); } + /** + * Creates an assembly. + * + * @param options a Map of options to create. + * @param extraData extra form data to create the assembly with. + * @return {@link AssemblyResponse} + * @throws RequestException if request to transloadit server fails. + * @throws LocalOperationException if something goes wrong while running non-http operations. + */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + + public AssemblyResponse createAssembly(Map options, Map extraData) + throws RequestException, LocalOperationException { + Request request = new Request(this); + return new AssemblyResponse(request.post("/assemblies", options, extraData, null, null)); + } + + // + + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + + /** + * Creates a TUS-ready Assembly that waits for the requested number of resumable uploads + * before execution continues. + */ + public AssemblyResponse createTusAssembly(int fileCount) + throws RequestException, LocalOperationException { + Map options = new HashMap(); + options.put("await", false); + Map optionsSteps = new HashMap(); + Map optionsStepsOriginal = new HashMap(); + optionsStepsOriginal.put("output_meta", true); + optionsStepsOriginal.put("result", "debug"); + optionsStepsOriginal.put("robot", "/upload/handle"); + optionsSteps.put(":original", optionsStepsOriginal); + options.put("steps", optionsSteps); + Map extraData = new HashMap(); + extraData.put("num_expected_upload_files", String.valueOf(fileCount)); + + return createAssembly(options, extraData); + } + + // + + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + + /** + * Create a TUS-ready Assembly, upload one file with the TUS protocol, and wait for the Assembly to finish. + */ + public UploadTusAssemblyResult uploadTusAssembly(int fileCount, byte[] content, String fieldname, String filename, Map userMeta) + throws RequestException, LocalOperationException { + AssemblyResponse createdAssembly = createTusAssembly(fileCount); + + java.net.URL endpointUrl; + try { + endpointUrl = new java.net.URL(createdAssembly.getTusUrl()); + } catch (java.net.MalformedURLException error) { + throw new LocalOperationException(error); + } + + Map metadataMap = new HashMap(); + if (userMeta != null) { + for (Map.Entry entry : userMeta.entrySet()) { + metadataMap.put(entry.getKey(), entry.getValue()); + } + } + metadataMap.put("assembly_url", String.valueOf(createdAssembly.getUrl())); + metadataMap.put("fieldname", String.valueOf(fieldname)); + metadataMap.put("filename", String.valueOf(filename)); + + okhttp3.OkHttpClient httpClient = new okhttp3.OkHttpClient(); + + String uploadUrlText; + okhttp3.Request.Builder createRequestBuilder = new okhttp3.Request.Builder() + .url(endpointUrl) + .method("POST", okhttp3.RequestBody.create(null, new byte[0])); + createRequestBuilder.addHeader("Tus-Resumable", "1.0.0"); + createRequestBuilder.addHeader("Upload-Length", String.valueOf(content.length)); + List createMetadataParts = new ArrayList(); + for (Map.Entry entry : metadataMap.entrySet()) { + createMetadataParts.add(entry.getKey() + " " + java.util.Base64.getEncoder().encodeToString(entry.getValue().getBytes(StandardCharsets.UTF_8))); + } + createRequestBuilder.addHeader("Upload-Metadata", String.join(",", createMetadataParts)); + okhttp3.Request createRequest = createRequestBuilder.build(); + + okhttp3.Response createResponse; + try { + createResponse = httpClient.newCall(createRequest).execute(); + } catch (java.io.IOException error) { + throw new RequestException(error); + } + try { + if (createResponse.code() != 201) { + throw new RequestException(String.format("TUS create returned HTTP %d, expected 201", createResponse.code())); + } + String uploadUrlLocation = createResponse.header("Location"); + if (uploadUrlLocation == null || uploadUrlLocation.isEmpty()) { + throw new RequestException("TUS create did not return a Location header"); + } + java.net.URL uploadUrl; + try { + uploadUrl = new java.net.URL(endpointUrl, uploadUrlLocation); + } catch (java.net.MalformedURLException error) { + throw new LocalOperationException(error); + } + uploadUrlText = uploadUrl.toString(); + } finally { + createResponse.close(); + } + + okhttp3.Request.Builder uploadRequestBuilder = new okhttp3.Request.Builder() + .url(uploadUrlText) + .method("PATCH", okhttp3.RequestBody.create(null, content)); + uploadRequestBuilder.addHeader("Tus-Resumable", "1.0.0"); + uploadRequestBuilder.addHeader("Upload-Offset", "0"); + uploadRequestBuilder.addHeader("Content-Type", "application/offset+octet-stream"); + okhttp3.Request uploadRequest = uploadRequestBuilder.build(); + + okhttp3.Response uploadResponse; + try { + uploadResponse = httpClient.newCall(uploadRequest).execute(); + } catch (java.io.IOException error) { + throw new RequestException(error); + } + try { + if (uploadResponse.code() != 204) { + throw new RequestException(String.format("TUS upload returned HTTP %d, expected 204", uploadResponse.code())); + } + int uploadOffset; + try { + uploadOffset = Integer.parseInt(uploadResponse.header("Upload-Offset")); + } catch (NumberFormatException error) { + throw new LocalOperationException(error); + } + if (uploadOffset != content.length) { + throw new RequestException(String.format("TUS upload offset %d, expected %d", uploadOffset, content.length)); + } + } finally { + uploadResponse.close(); + } + + AssemblyResponse completedAssembly = waitForAssembly(createdAssembly.getSslUrl()); + + return new UploadTusAssemblyResult(completedAssembly, uploadUrlText); + } + + // + /** * Returns a single assembly. * @@ -327,11 +487,19 @@ public Assembly newAssembly() { * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public AssemblyResponse getAssembly(String id) throws RequestException, LocalOperationException { Request request = new Request(this); return new AssemblyResponse(request.get("/assemblies/" + id)); } + // + /** * Returns a single assembly. * @@ -340,12 +508,59 @@ public AssemblyResponse getAssembly(String id) throws RequestException, LocalOpe * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public AssemblyResponse getAssemblyByUrl(String url) throws RequestException, LocalOperationException { Request request = new Request(this); return new AssemblyResponse(request.get(url)); } + // + + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + + /** + * Wait for an Assembly to finish uploading and executing. + * The assembly URL should be the assembly_ssl_url returned by createAssembly. + */ + public AssemblyResponse waitForAssembly(String assemblyUrl) + throws RequestException, LocalOperationException { + List responsePollValues = java.util.Arrays.asList( + "ASSEMBLY_UPLOADING", "ASSEMBLY_EXECUTING"); + while (true) { + AssemblyResponse response = getAssemblyByUrl(assemblyUrl); + org.json.JSONObject responseJson = response.json(); + + // Abort polling if the assembly has entered an error state + if (!responseJson.optString("error").isEmpty()) { + return response; + } + + // The polling is done if the assembly is not uploading or executing anymore. + if (!(responsePollValues.contains(responseJson.optString("ok")))) { + return response; + } + + try { + Thread.sleep(1000); + } catch (InterruptedException error) { + Thread.currentThread().interrupt(); + throw new LocalOperationException(error); + } + } + } + + // + /** * cancels a running assembly. * @@ -354,12 +569,20 @@ public AssemblyResponse getAssemblyByUrl(String url) * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public AssemblyResponse cancelAssembly(String url) throws RequestException, LocalOperationException { Request request = new Request(this); return new AssemblyResponse(request.delete(url, new HashMap())); } + // + /** * Returns a list of all assemblies under the user account. * @@ -368,12 +591,20 @@ public AssemblyResponse cancelAssembly(String url) * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public ListResponse listAssemblies(Map options) throws RequestException, LocalOperationException { Request request = new Request(this); return new ListResponse(request.get("/assemblies", options)); } + // + /** * Returns a list of all assemblies under the user account. * @return {@link ListResponse} @@ -394,6 +625,29 @@ public Template newTemplate(String name) { return new Template(this, name); } + /** + * Creates a template. + * + * @param options a Map of options to create. + * @return {@link Response} + * + * @throws RequestException if request to transloadit server fails. + * @throws LocalOperationException if something goes wrong while running non-http operations. + */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + + public Response createTemplate(Map options) + throws RequestException, LocalOperationException { + Request request = new Request(this); + return new Response(request.post("/templates", options)); + } + + // + /** * Returns a single template. * @@ -403,11 +657,19 @@ public Template newTemplate(String name) { * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public Response getTemplate(String id) throws RequestException, LocalOperationException { Request request = new Request(this); return new Response(request.get("/templates/" + id)); } + // + /** * Updates the template with the specified id. * @@ -418,12 +680,20 @@ public Response getTemplate(String id) throws RequestException, LocalOperationEx * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public Response updateTemplate(String id, Map options) throws RequestException, LocalOperationException { Request request = new Request(this); return new Response(request.put("/templates/" + id, options)); } + // + /** * Deletes a template. * @@ -433,12 +703,20 @@ public Response updateTemplate(String id, Map options) * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public Response deleteTemplate(String id) throws RequestException, LocalOperationException { Request request = new Request(this); return new Response(request.delete("/templates/" + id, new HashMap())); } + // + /** * Returns a list of all templates under the user account. * @@ -448,12 +726,20 @@ public Response deleteTemplate(String id) * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public ListResponse listTemplates(Map options) throws RequestException, LocalOperationException { Request request = new Request(this); return new ListResponse(request.get("/templates", options)); } + // + /** * Returns a list of all templates under the user account. * @@ -477,12 +763,20 @@ public ListResponse listTemplates() * @throws RequestException if request to transloadit server fails. * @throws LocalOperationException if something goes wrong while running non-http operations. */ + // + + // This block is generated from Transloadit API2 contracts. If it looks wrong, + // please report the issue instead of editing this block by hand; the source fix + // belongs in the contract generator so all SDKs stay in sync. + public Response getBill(int month, int year) throws RequestException, LocalOperationException { Request request = new Request(this); return new Response(request.get("/bill/" + year + String.format("-%02d", month))); } + // + /** * Returns Array List of String encoded Exceptions, which should be qualified for a retry attempt. * {@code "java.net.SocketTimeoutException" } is added by default diff --git a/src/main/java/com/transloadit/sdk/UploadTusAssemblyResult.java b/src/main/java/com/transloadit/sdk/UploadTusAssemblyResult.java new file mode 100644 index 0000000..78d522b --- /dev/null +++ b/src/main/java/com/transloadit/sdk/UploadTusAssemblyResult.java @@ -0,0 +1,24 @@ +package com.transloadit.sdk; + +import com.transloadit.sdk.response.AssemblyResponse; + +/** + * Result returned after uploading one file through a TUS Assembly. + */ +public class UploadTusAssemblyResult { + private final AssemblyResponse assembly; + private final String uploadUrl; + + public UploadTusAssemblyResult(AssemblyResponse assembly, String uploadUrl) { + this.assembly = assembly; + this.uploadUrl = uploadUrl; + } + + public AssemblyResponse getAssembly() { + return assembly; + } + + public String getUploadUrl() { + return uploadUrl; + } +}