diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/sse/SseParserTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/sse/SseParserTest.java index cd018c190b115..9584c5efd89f1 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/sse/SseParserTest.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/deployment/src/test/java/io/quarkus/resteasy/reactive/jsonb/deployment/test/sse/SseParserTest.java @@ -43,8 +43,8 @@ public void testParser() { // all fields testParser("data:DATA\nid:ID\n:COMMENT\nretry:23\nevent:NAME\n\n", "DATA", "COMMENT", "ID", "NAME", 23); - // all fields and no data: no event - testParser("id:ID\n:COMMENT\nretry:23\nevent:NAME\n\n", null, null, null, null, SseEvent.RECONNECT_NOT_SET); + // all fields and no data + testParser("id:ID\n:COMMENT\nretry:23\nevent:NAME\n\n", null, "COMMENT", "ID", "NAME", 23); // optional space after colon testParser("data:foo\n\n", "foo", null, null, null, SseEvent.RECONNECT_NOT_SET); @@ -147,6 +147,13 @@ private void testParser(String event, String data, String comment, String lastId .setId(lastId) .setName(name) .setReconnectDelay(reconnectDelay))); + } else if (comment != null) { + testParser(Collections.singletonList(event), Collections.singletonList(new InboundSseEventImpl(null, null) + .setData(null) + .setComment(comment) + .setId(lastId) + .setName(name) + .setReconnectDelay(reconnectDelay))); } else { testParser(Collections.singletonList(event), Collections.emptyList()); } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/stream/StreamResource.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/stream/StreamResource.java index 307d5b77d5d81..31f931789d3de 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/stream/StreamResource.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/stream/StreamResource.java @@ -160,7 +160,8 @@ public Multi sseThrows() { @GET @Produces(MediaType.SERVER_SENT_EVENTS) public Multi sseRaw(@Context Sse sse) { - return Multi.createFrom().items(sse.newEventBuilder().id("one").data("uno").name("eins").build(), + return Multi.createFrom().items(sse.newEventBuilder().comment("dummy").build(), + sse.newEventBuilder().id("one").data("uno").name("eins").build(), sse.newEventBuilder().id("two").data("dos").name("zwei").build(), sse.newEventBuilder().id("three").data("tres").name("drei").build()); } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/stream/StreamTestCase.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/stream/StreamTestCase.java index d43b1ddb1249b..f1615e674ad80 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/stream/StreamTestCase.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/stream/StreamTestCase.java @@ -3,7 +3,6 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.time.Duration; -import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; @@ -211,7 +210,7 @@ public void testSse() throws InterruptedException { }); sse.open(); Assertions.assertTrue(latch.await(20, TimeUnit.SECONDS)); - Assertions.assertEquals(Arrays.asList("a", "b", "c"), results); + org.assertj.core.api.Assertions.assertThat(results).containsExactly("a", "b", "c"); Assertions.assertEquals(0, errors.size()); } } @@ -248,7 +247,9 @@ public void testSseForMultiWithOutboundSseEvent() throws InterruptedException { List results = new CopyOnWriteArrayList<>(); List ids = new CopyOnWriteArrayList<>(); List names = new CopyOnWriteArrayList<>(); + List comments = new CopyOnWriteArrayList<>(); sse.register(event -> { + comments.add(event.getComment()); results.add(event.readData()); ids.add(event.getId()); names.add(event.getName()); @@ -259,9 +260,10 @@ public void testSseForMultiWithOutboundSseEvent() throws InterruptedException { }); sse.open(); Assertions.assertTrue(latch.await(20, TimeUnit.SECONDS)); - Assertions.assertEquals(Arrays.asList("uno", "dos", "tres"), results); - Assertions.assertEquals(Arrays.asList("one", "two", "three"), ids); - Assertions.assertEquals(Arrays.asList("eins", "zwei", "drei"), names); + org.assertj.core.api.Assertions.assertThat(results).containsExactly(null, "uno", "dos", "tres"); + org.assertj.core.api.Assertions.assertThat(ids).containsExactly(null, "one", "two", "three"); + org.assertj.core.api.Assertions.assertThat(names).containsExactly(null, "eins", "zwei", "drei"); + org.assertj.core.api.Assertions.assertThat(comments).containsExactly("dummy", null, null, null); Assertions.assertEquals(0, errors.size()); } } diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/SseParser.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/SseParser.java index e503570b36274..47b8e54957a69 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/SseParser.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/SseParser.java @@ -145,7 +145,7 @@ private void parseEvent() { private void dispatchEvent() { // ignore empty events - if (dataBuffer.length() == 0) + if (dataBuffer.length() == 0 && commentBuffer.length() == 0) return; WebTargetImpl webTarget = sseEventSource.getWebTarget(); InboundSseEventImpl event; @@ -159,7 +159,7 @@ private void dispatchEvent() { event.setComment(commentBuffer.length() == 0 ? null : commentBuffer.toString()); // SSE spec says empty string is the default, but JAX-RS says null if not specified event.setId(lastEventId); - event.setData(dataBuffer.toString()); + event.setData(dataBuffer.length() == 0 ? null : dataBuffer.toString()); // SSE spec says "message" is the default, but JAX-RS says null if not specified event.setName(eventType); event.setReconnectDelay(eventReconnectTime); diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java index b0969d595fc1b..24de690d468c9 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java @@ -69,8 +69,10 @@ private static String serialiseEvent(ResteasyReactiveRequestContext context, Out if (event.getReconnectDelay() >= 0) serialiseField(context, sb, "retry", Long.toString(event.getReconnectDelay()), false); } - String data = serialiseDataToString(context, event, eventMediaType); - serialiseField(context, sb, "data", data, true); + if (event.getData() != null) { + String data = serialiseDataToString(context, event, eventMediaType); + serialiseField(context, sb, "data", data, true); + } sb.append(NL); // return a UTF8 buffer return sb.toString();