Skip to content

Commit

Permalink
Merge pull request #1508 from mocenas/sse_test
Browse files Browse the repository at this point in the history
Add test coverage for issue 36402
  • Loading branch information
michalvavrik authored Nov 8, 2023
2 parents 7c442f4 + 5e88613 commit 69d46ff
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.quarkus.ts.http.advanced;

import java.util.Arrays;
import java.util.concurrent.locks.LockSupport;

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.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 SseResource {
@Context
Sse sse;

@GET
@Path("/client")
public String sseClient() {
try {
return consumeSse();
}
// in case that https://github.com/quarkusio/quarkus/issues/36402 throws java.lang.RuntimeException: java.lang.ClassNotFoundException:
// catch it and return the error message
catch (RuntimeException exception) {
return exception.getMessage();
}
}

private String consumeSse() {
StringBuilder response = new StringBuilder();
int port = ConfigProvider.getConfig().getValue("quarkus.http.port", Integer.class);

/*
* Client connects to itself (to server endpoint running on same app),
* because for https://github.com/quarkusio/quarkus/issues/36402 to reproduce client must run on native app.
* Which cannot be done in test code itself.
* This method acts just as a client
*/
WebTarget target = ClientBuilder.newClient().target("http://localhost:" + port + "/api/sse/server");
SseEventSource updateSource = SseEventSource.target(target).build();
updateSource.register(ev -> {
response.append("event: ").append(ev.getName()).append(" ").append(ev.readData());
response.append("\n");

}, thr -> {
response.append("Error in SSE, message: ").append(thr.getMessage()).append("\n");
response.append(Arrays.toString(thr.getStackTrace()));
});
updateSource.open();

LockSupport.parkNanos(1_000_000_000L);
return response.toString();
}

@GET
@Path("/server")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void sendSseEvents(@Context SseEventSink eventSink) {
eventSink.send(createEvent("test234", "test"));
}

private OutboundSseEvent createEvent(String name, String data) {
return sse.newEventBuilder()
.name(name)
.data(data)
.build();
}
}
2 changes: 2 additions & 0 deletions http/http-advanced/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ quarkus.keycloak.policy-enforcer.paths.version.enforcement-mode=DISABLED
# Application endpoints
quarkus.keycloak.policy-enforcer.paths.hello.path=/api/hello/*
quarkus.keycloak.policy-enforcer.paths.hello.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.sse.path=/api/sse/*
quarkus.keycloak.policy-enforcer.paths.sse.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.details.path=/api/details/*
quarkus.keycloak.policy-enforcer.paths.details.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.grpc.path=/api/grpc/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import static org.hamcrest.Matchers.in;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import java.net.URISyntaxException;
Expand Down Expand Up @@ -60,6 +62,7 @@ public abstract class BaseHttpAdvancedIT {
private static final String PASSWORD = "password";
private static final String KEY_STORE_PATH = "META-INF/resources/server.keystore";
private static final int ASSERT_TIMEOUT_SECONDS = 10;
private static final String SSE_ERROR_MESSAGE = "java.lang.ClassNotFoundException: Provider for jakarta.ws.rs.sse.SseEventSource.Builder cannot be found";

protected abstract RestService getApp();

Expand Down Expand Up @@ -242,6 +245,16 @@ public void keepRequestScopeValuesAfterEventPropagation() {
"Unexpected requestScope custom context value");
}

@Test
@Tag("https://github.com/quarkusio/quarkus/issues/36402")
public void sseConnectionTest() {
String response = getApp().given().get("/api/sse/client").thenReturn().body().asString();

assertFalse(response.contains(SSE_ERROR_MESSAGE),
"SSE failed, https://github.com/quarkusio/quarkus/issues/36402 not fixed");
assertTrue(response.contains("event: test234 test"), "SSE failed, unknown bug. Response: " + response);
}

protected Protocol getProtocol() {
return Protocol.HTTPS;
}
Expand Down

0 comments on commit 69d46ff

Please sign in to comment.