diff --git a/2024/08/chat_demo1/chat_demo1_web/build.gradle.kts b/2024/08/chat_demo1/chat_demo1_web/build.gradle.kts index 209280f..161de2b 100644 --- a/2024/08/chat_demo1/chat_demo1_web/build.gradle.kts +++ b/2024/08/chat_demo1/chat_demo1_web/build.gradle.kts @@ -1,23 +1,25 @@ plugins { - id("java") + id("java") } group = "ch.polgrabia.demos" version = "1.0-SNAPSHOT" repositories { - mavenCentral() + mavenCentral() } +val vertxVersion = project.ext.get("vertx.version") dependencies { - implementation("commons-cli:commons-cli:1.9.0") - implementation("io.vertx:vertx-core:4.5.9") - implementation("ch.qos.logback:logback-classic:1.5.6") - implementation("org.apache.kafka:kafka-clients:3.9.0") - testImplementation(platform("org.junit:junit-bom:5.10.0")) - testImplementation("org.junit.jupiter:junit-jupiter") + implementation("commons-cli:commons-cli:1.9.0") + implementation("io.vertx:vertx-core:$vertxVersion") + implementation("io.vertx:vertx-web:$vertxVersion") + implementation("ch.qos.logback:logback-classic:1.5.6") + implementation("org.apache.kafka:kafka-clients:3.9.0") + testImplementation(platform("org.junit:junit-bom:5.10.0")) + testImplementation("org.junit.jupiter:junit-jupiter") } tasks.test { - useJUnitPlatform() + useJUnitPlatform() } \ No newline at end of file diff --git a/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebApiParticle.java b/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebApiParticle.java index 02ce433..e59fe35 100644 --- a/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebApiParticle.java +++ b/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebApiParticle.java @@ -1,26 +1,35 @@ package ch.polgrabia.demos.client; +import io.netty.handler.codec.http.HttpResponseStatus; import io.vertx.core.AbstractVerticle; import io.vertx.core.AsyncResult; +import io.vertx.core.Future; import io.vertx.core.buffer.Buffer; -import io.vertx.core.eventbus.EventBus; import io.vertx.core.http.HttpServer; import io.vertx.core.http.HttpServerOptions; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.HttpServerResponse; +import io.vertx.ext.web.Router; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class WebApiParticle extends AbstractVerticle { private static final Logger logger = LoggerFactory.getLogger(WebApiParticle.class); + private final int clientPort; private HttpServer server; + public WebApiParticle(int clientPort) { + this.clientPort = clientPort; + } + @Override public void start() throws Exception { HttpServerOptions httpServerOptions = new HttpServerOptions(); + var router = Router.router(getVertx()); this.server = getVertx().createHttpServer(httpServerOptions); - this.server.requestHandler(this::handleCommandRequests); - this.server.listen(8123, "localhost", this::handleListenCommand); + router.get("/message").respond(routingContext -> handleCommandRequests(routingContext.request())); + this.server.requestHandler(router); + this.server.listen(clientPort, "localhost", this::handleListenCommand); } @Override @@ -28,19 +37,18 @@ public class WebApiParticle extends AbstractVerticle { server.close(); } - private void handleCommandRequests(HttpServerRequest httpServerRequest) { - logger.info("Received command request on 8123"); + private Future handleCommandRequests(HttpServerRequest httpServerRequest) { + logger.info("Received command request on {}", clientPort); HttpServerResponse response = httpServerRequest.response(); String qParam = httpServerRequest.getParam("q"); if (qParam == null || qParam.isBlank()) { - response.setStatusCode(400); - response.end("bad request"); - return; + response.setStatusCode(HttpResponseStatus.BAD_REQUEST.code()); + return response.end("%s\n".formatted(HttpResponseStatus.BAD_REQUEST.reasonPhrase())); } logger.info("Sending binary message: {}", qParam); getVertx().eventBus().publish(Constants.CLIENT_WEBSOCKET_SENDER_EVENTBUS_KEY, Buffer.buffer(qParam)); - response.setStatusCode(202); - response.end("Ok"); + response.setStatusCode(HttpResponseStatus.ACCEPTED.code()); + return response.end("%s\n".formatted(HttpResponseStatus.ACCEPTED.reasonPhrase())); } private void handleListenCommand(AsyncResult httpServerAsyncResult) { diff --git a/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebsocketClientApp.java b/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebsocketClientApp.java index c5eb93c..3470494 100644 --- a/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebsocketClientApp.java +++ b/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebsocketClientApp.java @@ -9,7 +9,11 @@ public class WebsocketClientApp { public static void main(String[] args) { var vertx = Vertx.vertx(); logger.info("Deploying websocket particle"); - WebsocketClientParticle websocketClientParticle = new WebsocketClientParticle("localhost", 8080, "/test"); + WebsocketClientParticle websocketClientParticle = new WebsocketClientParticle( + "localhost", + 8080, + "/test", + 8123); vertx.deployVerticle(websocketClientParticle); logger.info("Deployed websocket particle"); websocketClientParticle diff --git a/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebsocketClientParticle.java b/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebsocketClientParticle.java index 4e560f9..1db5107 100644 --- a/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebsocketClientParticle.java +++ b/2024/08/chat_demo1/chat_demo1_web/src/main/java/ch/polgrabia/demos/client/WebsocketClientParticle.java @@ -16,26 +16,31 @@ import java.util.concurrent.CompletableFuture; public class WebsocketClientParticle extends AbstractVerticle { private static final Logger logger = LoggerFactory.getLogger(WebsocketClientParticle.class); - private final String hostname; - private final int port; + private final String webSocketHostname; + private final int webSocketPort; // path maps to channel - private final String path; + private final String webSocketPath; private final String channel; private final ClientPeriodicStdinScannerParticle clientPeriodicStdinScannerParticle = new ClientPeriodicStdinScannerParticle( System.in ); - private final WebApiParticle webApiParticle = new WebApiParticle(); + private final WebApiParticle webApiParticle; private HttpClient client; private boolean isShuttingDownActivated = false; private final Object runningMonitor = new Object(); private WebSocketSenderParticle webSocketSenderParticle; private WebSocketReceiverParticle webSocketReceiverParticle; - public WebsocketClientParticle(String hostname, int port, String path) { - this.hostname = hostname; - this.port = port; - this.path = path; - this.channel = TopicUtil.convertTopicName(path); + public WebsocketClientParticle( + String webSocketHostname, + int webSocketPort, + String webSocketPath, + int clientApiPort) { + this.webSocketHostname = webSocketHostname; + this.webSocketPort = webSocketPort; + this.webSocketPath = webSocketPath; + this.channel = TopicUtil.convertTopicName(webSocketPath); + this.webApiParticle = new WebApiParticle(clientApiPort); } @Override @@ -44,7 +49,7 @@ public class WebsocketClientParticle extends AbstractVerticle { .createHttpClient(); logger.info("Starting websocket client command server"); new WebSocketClientImpl((VertxInternal) getVertx(), new HttpClientOptions(), new CloseFuture()) - .webSocket(port, hostname, path, this::handleMessage); + .webSocket(webSocketPort, webSocketHostname, webSocketPath, this::handleMessage); getVertx().deployVerticle(clientPeriodicStdinScannerParticle); getVertx().deployVerticle(webApiParticle); } diff --git a/2024/08/chat_demo1/gradle.properties b/2024/08/chat_demo1/gradle.properties new file mode 100644 index 0000000..1f68c3c --- /dev/null +++ b/2024/08/chat_demo1/gradle.properties @@ -0,0 +1 @@ +vertx.version=4.5.12 \ No newline at end of file