Skip to content

Commit

Permalink
Add test for check SSE reactive empty responce data
Browse files Browse the repository at this point in the history
  • Loading branch information
jedla97 committed Nov 14, 2023
1 parent 764e0f6 commit 63a9de1
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.quarkus.ts.http.advanced.reactive;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.sse.OutboundSseEvent;
import jakarta.ws.rs.sse.Sse;
import jakarta.ws.rs.sse.SseEventSink;
import jakarta.ws.rs.sse.SseEventSource;

import org.eclipse.microprofile.config.ConfigProvider;

@Path("sse")
public class SseEventUpdateResource {
public static final String DATA_VALUE = "random data value";

@Context
Sse sse;

@GET
@Path("client-update")
@Produces(MediaType.TEXT_PLAIN)
public Response clientUpdate() throws InterruptedException {
String host = ConfigProvider.getConfig().getValue("quarkus.http.host", String.class);
int port = ConfigProvider.getConfig().getValue("quarkus.http.port", Integer.class);
List<String> receivedData = new CopyOnWriteArrayList<>();

WebTarget target = ClientBuilder.newClient().target("http://" + host + ":" + port + "/api/sse/server-update");
try (SseEventSource eventSource = SseEventSource.target(target).build()) {
eventSource.register(ev -> {
String event = "event: name=" + ev.getName() + " data={" + ev.readData() + "} and is empty: " + ev.isEmpty()
+ "\n";
receivedData.add(event);
}, thr -> {
String event = "Error: " + thr.getMessage() + "\n" + Arrays.toString(thr.getStackTrace());
receivedData.add(event);
});

CountDownLatch latch = new CountDownLatch(2);
eventSource.open();
latch.await(1, TimeUnit.SECONDS);
}
return Response.ok(String.join("\n", receivedData)).build();
}

@GET
@Path("server-update")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void updates(@Context SseEventSink eventSink) {
eventSink.send(createEvent("NON EMPTY", DATA_VALUE));
eventSink.send(createEvent("EMPTY", ""));
}

private OutboundSseEvent createEvent(String name, String data) {
return sse.newEventBuilder()
.name(name)
.data(data)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ quarkus.keycloak.policy-enforcer.paths.grpc.path=/api/grpc/*
quarkus.keycloak.policy-enforcer.paths.grpc.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.client.path=/api/client/*
quarkus.keycloak.policy-enforcer.paths.client.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.sse.path=/api/sse/*
quarkus.keycloak.policy-enforcer.paths.sse.enforcement-mode=DISABLED
quarkus.oidc.client-id=test-application-client
quarkus.oidc.credentials.secret=test-application-client-secret
# tolerate 1 minute of clock skew between the Keycloak server and the application
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import static io.quarkus.ts.http.advanced.reactive.MultipleResponseSerializersResource.MULTIPLE_RESPONSE_SERIALIZERS_PATH;
import static io.quarkus.ts.http.advanced.reactive.NinetyNineBottlesOfBeerResource.QUARKUS_PLATFORM_VERSION_LESS_THAN_2_8_3;
import static io.quarkus.ts.http.advanced.reactive.NinetyNineBottlesOfBeerResource.QUARKUS_PLATFORM_VERSION_LESS_THAN_2_8_3_VAL;
import static io.quarkus.ts.http.advanced.reactive.SseEventUpdateResource.DATA_VALUE;
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static jakarta.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
import static jakarta.ws.rs.core.MediaType.APPLICATION_XML;
Expand Down Expand Up @@ -71,6 +72,7 @@
import io.quarkus.example.StreamingGrpc;
import io.quarkus.test.bootstrap.Protocol;
import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.scenarios.annotations.DisabledOnNative;
import io.quarkus.test.scenarios.annotations.EnabledOnQuarkusVersion;
import io.quarkus.ts.http.advanced.reactive.clients.HttpVersionClientService;
import io.quarkus.ts.http.advanced.reactive.clients.HttpVersionClientServiceAsync;
Expand Down Expand Up @@ -427,6 +429,17 @@ public void constraintsExist() throws JsonProcessingException {
Assertions.assertEquals("^[A-Za-z]+$", validation.get("pattern").asText());
}

@DisplayName("SSE check for event responses values containing empty data")
@Test
@DisabledOnNative(reason = "https://github.com/quarkusio/quarkus/issues/36986")
void testSseResponseForEmptyData() {
getApp().given()
.get(ROOT_PATH + "/sse/client-update")
.then().statusCode(SC_OK)
.body(containsString(String.format("event: name=NON EMPTY data={%s} and is empty: false", DATA_VALUE)),
containsString("event: name=EMPTY data={} and is empty: true"));
}

private void assertAcceptedMediaTypeEqualsResponseBody(String acceptedMediaType) {
getApp()
.given()
Expand Down

0 comments on commit 63a9de1

Please sign in to comment.