Skip to content

Commit d7caa7d

Browse files
authored
Reproduce missing step (#100)
* Allow passing in env * Add asset * test: add embedded smart cdn fixture and ensure results * Rename JAVA_SDK_E2E_SMARTCDN * refactor: simplify sse listener post-finish handling * chore: release 2.2.4
1 parent 617dfa5 commit d7caa7d

File tree

7 files changed

+94
-16
lines changed

7 files changed

+94
-16
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.jpg binary

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
### 2.2.4 / 2025-10-28
2+
3+
- Bundle chameleon.jpg in the repository and enable the `directUploadOriginalStepProducesResult` integration test via `JAVA_SDK_E2E`.
4+
- Simplify the SSE listener by stopping immediately after `assembly_finished` now that trailing results are guaranteed.
5+
16
### 2.2.3 / 2025-10-27
27

38
- Extend the SSE listener grace window to 10 seconds so `assembly_result_finished` payloads are not dropped after `assembly_finished`.

scripts/test-in-docker.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,13 @@ if [[ -f .env ]]; then
7171
DOCKER_ARGS+=(--env-file "$PWD/.env")
7272
fi
7373

74+
75+
EXTRA_ENVS=(JAVA_SDK_E2E TRANSLOADIT_HOST TRANSLOADIT_KEY TRANSLOADIT_SECRET)
76+
for var in "${EXTRA_ENVS[@]}"; do
77+
value="${!var:-}"
78+
if [[ -n "$value" ]]; then
79+
DOCKER_ARGS+=(-e "$var=$value")
80+
fi
81+
done
82+
7483
exec docker run "${DOCKER_ARGS[@]}" "$IMAGE_NAME" bash -lc "$RUN_CMD"

src/main/java/com/transloadit/sdk/EventsourceRunnable.java

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
import java.util.Iterator;
2323

2424
class EventsourceRunnable implements Runnable {
25-
private static final long FINISH_DRAIN_TIMEOUT_MS = 10000L;
26-
2725
protected boolean assemblyFinished;
2826
protected AssemblyListener assemblyListener;
2927

@@ -33,7 +31,6 @@ class EventsourceRunnable implements Runnable {
3331
protected Transloadit transloadit;
3432
protected boolean stopRequested;
3533
protected boolean assemblyFinishedNotified;
36-
protected long assemblyFinishedAtMillis;
3734

3835
/**
3936
* Constructor for {@link EventsourceRunnable}. It creates a new {@link EventSource} instance, wrapped in a
@@ -72,7 +69,6 @@ public void run() {
7269
this.assemblyFinished = false;
7370
this.stopRequested = false;
7471
this.assemblyFinishedNotified = false;
75-
this.assemblyFinishedAtMillis = 0L;
7672
try {
7773
eventSource.start();
7874
} catch (StreamException e) {
@@ -100,16 +96,7 @@ public void run() {
10096

10197
if (!processedEvent) {
10298
ReadyState state = eventSource.getState();
103-
long now = System.currentTimeMillis();
104-
if (assemblyFinished) {
105-
if (assemblyFinishedAtMillis == 0L) {
106-
assemblyFinishedAtMillis = now;
107-
}
108-
boolean graceExpired = now - assemblyFinishedAtMillis >= FINISH_DRAIN_TIMEOUT_MS;
109-
if (graceExpired || state == ReadyState.CLOSED || state == ReadyState.SHUTDOWN) {
110-
stopRequested = true;
111-
}
112-
} else if (state == ReadyState.CLOSED || state == ReadyState.SHUTDOWN) {
99+
if (state == ReadyState.CLOSED || state == ReadyState.SHUTDOWN) {
113100
stopRequested = true;
114101
}
115102

@@ -145,7 +132,6 @@ protected void handleMessageEvent(MessageEvent messageEvent) {
145132
switch (data) {
146133
case "assembly_finished":
147134
assemblyFinished = true;
148-
assemblyFinishedAtMillis = System.currentTimeMillis();
149135
if (!assemblyFinishedNotified) {
150136
assemblyFinishedNotified = true;
151137
try {
@@ -154,6 +140,7 @@ protected void handleMessageEvent(MessageEvent messageEvent) {
154140
assemblyListener.onError(e);
155141
}
156142
}
143+
stopRequested = true;
157144
break;
158145
case "assembly_upload_meta_data_extracted":
159146
assemblyListener.onMetadataExtracted();
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
versionNumber='2.2.3'
1+
versionNumber='2.2.4'

src/test/java/com/transloadit/sdk/integration/AssemblyIntegrationTest.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import com.transloadit.sdk.Assembly;
44
import com.transloadit.sdk.Transloadit;
55
import com.transloadit.sdk.response.AssemblyResponse;
6+
7+
import java.io.File;
8+
import java.io.FileOutputStream;
69
import org.json.JSONArray;
710
import org.junit.jupiter.api.Assertions;
811
import org.junit.jupiter.api.Assumptions;
@@ -50,4 +53,77 @@ void createAssemblyAndWaitForCompletion() throws Exception {
5053
Assertions.assertNotNull(stepResult, "resize step result missing");
5154
Assertions.assertTrue(stepResult.length() > 0, "resize step result empty");
5255
}
56+
57+
@Test
58+
void directUploadOriginalStepProducesResult() throws Exception {
59+
Assumptions.assumeTrue("1".equals(System.getenv("JAVA_SDK_E2E")), "set JAVA_SDK_E2E=1 to run");
60+
61+
String key = System.getenv("TRANSLOADIT_KEY");
62+
String secret = System.getenv("TRANSLOADIT_SECRET");
63+
Assumptions.assumeTrue(key != null && !key.trim().isEmpty(), "TRANSLOADIT_KEY env var required");
64+
Assumptions.assumeTrue(secret != null && !secret.trim().isEmpty(), "TRANSLOADIT_SECRET env var required");
65+
66+
File upload = File.createTempFile("java-sdk-smartcdn", ".bin");
67+
try (java.io.InputStream in = AssemblyIntegrationTest.class.getResourceAsStream("/chameleon.jpg");
68+
FileOutputStream fos = new FileOutputStream(upload)) {
69+
if (in == null) {
70+
Assertions.fail("Embedded chameleon.jpg fixture missing");
71+
}
72+
byte[] buffer = new byte[8192];
73+
int read;
74+
while ((read = in.read(buffer)) != -1) {
75+
fos.write(buffer, 0, read);
76+
}
77+
long targetSize = 32L * 1024L * 1024L;
78+
long current = upload.length();
79+
if (current < targetSize) {
80+
byte[] padding = new byte[8192];
81+
while (current < targetSize) {
82+
long remaining = targetSize - current;
83+
int toWrite = (int) Math.min(padding.length, remaining);
84+
fos.write(padding, 0, toWrite);
85+
current += toWrite;
86+
}
87+
}
88+
}
89+
90+
Transloadit client = new Transloadit(key, secret);
91+
Assembly assembly = client.newAssembly();
92+
try {
93+
assembly.addFile(upload, "image");
94+
95+
Map<String, Object> resize = new HashMap<>();
96+
resize.put("use", ":original");
97+
resize.put("width", 32);
98+
resize.put("height", 32);
99+
resize.put("resize_strategy", "fit");
100+
resize.put("format", "jpg");
101+
resize.put("result", true);
102+
assembly.addStep("resize", "/image/resize", resize);
103+
104+
AssemblyResponse response = assembly.save(true);
105+
String assemblyId = response.getId();
106+
107+
long deadline = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5);
108+
while (!response.isFinished() && System.currentTimeMillis() < deadline) {
109+
Thread.sleep(5000);
110+
response = client.getAssembly(assemblyId);
111+
}
112+
113+
Assertions.assertTrue(response.isFinished(), "Assembly did not finish in time: " + assemblyId);
114+
String ok = response.json().optString("ok");
115+
if (!"ASSEMBLY_COMPLETED".equals(ok)) {
116+
Assertions.fail("Assembly " + assemblyId + " finished with status=" + ok + " payload=" + response.json());
117+
}
118+
119+
JSONArray resizeResult = response.getStepResult("resize");
120+
if (resizeResult == null) {
121+
Assertions.fail("resize step result missing for assembly " + assemblyId + " payload=" + response.json());
122+
}
123+
Assertions.assertTrue(resizeResult.length() > 0, "resize step result empty for assembly " + assemblyId);
124+
} finally {
125+
upload.delete();
126+
}
127+
}
128+
53129
}

src/test/resources/chameleon.jpg

8.88 MB
Loading

0 commit comments

Comments
 (0)