Helidon container example Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/bom/pom.xml b/bom/pom.xml index 1460faa..ffdfa03 100644 --- a/bom/pom.xml +++ b/bom/pom.xml
@@ -125,6 +125,11 @@ </dependency> <dependency> <groupId>org.glassfish.jersey.containers</groupId> + <artifactId>jersey-container-helidon-http</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-grizzly2-http</artifactId> <version>${project.version}</version> </dependency> @@ -391,6 +396,11 @@ </dependency> <dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> + <artifactId>jersey-test-framework-provider-helidon</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-grizzly2</artifactId> <version>${project.version}</version> </dependency>
diff --git a/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonHttpContainerBuilder.java b/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonHttpContainerBuilder.java index 4cccbd2..98d790f 100644 --- a/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonHttpContainerBuilder.java +++ b/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonHttpContainerBuilder.java
@@ -199,7 +199,7 @@ .host(baseUri.getHost()) .port(baseUri.getPort()); } else { - if (webServerBuilder.port() < 0) { + if (webServerBuilder.port() <= 0) { webServerBuilder.port(Container.DEFAULT_HTTP_PORT); }
diff --git a/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonHttpServer.java b/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonHttpServer.java index dbea20d..145bba0 100644 --- a/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonHttpServer.java +++ b/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonHttpServer.java
@@ -18,6 +18,7 @@ import jakarta.ws.rs.core.Application; import org.glassfish.jersey.server.JerseySeBootstrapConfiguration; +import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.spi.Container; import org.glassfish.jersey.server.spi.WebServer; @@ -26,10 +27,14 @@ import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; -final class HelidonHttpServer implements WebServer { +public final class HelidonHttpServer implements WebServer { private final HelidonHttpContainer helidonHttpContainer; + HelidonHttpServer(Application application) { + this(HelidonHttpContainerBuilder.builder().application(application), JerseySeBootstrapConfiguration.builder().build()); + } + HelidonHttpServer(Application application, JerseySeBootstrapConfiguration seBootstrapConfig) { this(HelidonHttpContainerBuilder.builder().application(application), seBootstrapConfig); }
diff --git a/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonJerseyRoutingService.java b/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonJerseyRoutingService.java index 8076956..6bbbe55 100644 --- a/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonJerseyRoutingService.java +++ b/containers/helidon/src/main/java/org/glassfish/jersey/helidon/HelidonJerseyRoutingService.java
@@ -25,6 +25,7 @@ import io.helidon.http.HeaderNames; import io.helidon.http.HeaderValues; import io.helidon.http.InternalServerException; +import io.helidon.http.ServerResponseHeaders; import io.helidon.http.Status; import io.helidon.webserver.KeyPerformanceIndicatorSupport; import io.helidon.webserver.http.HttpRules; @@ -94,7 +95,7 @@ } private ApplicationHandler appHandler() { - return bridge.getContainer().getApplicationHandler(); + return container().getApplicationHandler(); } private Container container() { @@ -114,9 +115,7 @@ @Override public void afterStop() { try { - final InjectionManager ij = appHandler().getInjectionManager(); - ij.shutdown(); - appHandler().onShutdown(bridge.getContainer()); + appHandler().onShutdown(container()); } catch (Exception e) { if (LOGGER.isLoggable(System.Logger.Level.DEBUG)) { LOGGER.log(System.Logger.Level.DEBUG, "Exception during shutdown of Jersey", e); @@ -138,6 +137,11 @@ } private void doHandle(final Context ctx, final ServerRequest req, final ServerResponse res) { + ServerResponseHeaders savedResponseHeaders = null; + if (req.listenerContext().config().restoreResponseHeaders()) { + savedResponseHeaders = ServerResponseHeaders.create(res.headers()); + } + final BaseUriRequestUri uris = BaseUriRequestUri.resolve(req); final ContainerRequest requestContext = new ContainerRequest(uris.baseUri, uris.requestUri, @@ -187,6 +191,9 @@ final RoutingResponse routing = (RoutingResponse) res; if (routing.reset()) { res.status(Status.OK_200); + if (savedResponseHeaders != null) { + savedResponseHeaders.forEach(res::header); + } routing.next(); } }
diff --git a/examples/helloworld-helidon/README.MD b/examples/helloworld-helidon/README.MD new file mode 100644 index 0000000..61a5dff --- /dev/null +++ b/examples/helloworld-helidon/README.MD
@@ -0,0 +1,33 @@ +[//]: # " Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. " +[//]: # " " +[//]: # " This program and the accompanying materials are made available under the " +[//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at " +[//]: # " http://www.eclipse.org/org/documents/edl-v10.php. " +[//]: # " " +[//]: # " SPDX-License-Identifier: BSD-3-Clause " + +Hello World Example +=================== + +This example demonstrates Hello World example running on top of Helidon container and using Helidon connector as a client +implementation for testing. JAX-RS resource returns the usual text `Hello World!`. + +Contents +-------- + +The mapping of the URI path space is presented in the following table: + +URI path | Resource class | HTTP methods | Notes +-------------------- | ------------------- | ------------ | -------------------------------------------------------- +**_/helloworld_** | HelloWorldResource | GET | Returns `Hello World!` + +Running the Example +------------------- + +Run the example as follows: + +> mvn clean compile exec:java + +This deploys the example using [Helidon](http://helidon.io/) container. + +- <http://localhost:8080/helloworld>
diff --git a/examples/helloworld-helidon/pom.xml b/examples/helloworld-helidon/pom.xml new file mode 100644 index 0000000..0b66ba7 --- /dev/null +++ b/examples/helloworld-helidon/pom.xml
@@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Distribution License v. 1.0, which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: BSD-3-Clause + +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.glassfish.jersey.examples</groupId> + <artifactId>project</artifactId> + <version>3.1.99-SNAPSHOT</version> + </parent> + + <artifactId>helloworld-helidon</artifactId> + <packaging>jar</packaging> + <name>jersey-examples-helloworld-helidon</name> + + <description>Jersey "Hello world" example on Helidon container.</description> + + <dependencies> + <dependency> + <groupId>org.glassfish.jersey.containers</groupId> + <artifactId>jersey-container-helidon-http</artifactId> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.inject</groupId> + <artifactId>jersey-hk2</artifactId> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.test-framework</groupId> + <artifactId>jersey-test-framework-util</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.glassfish.jersey.test-framework.providers</groupId> + <artifactId>jersey-test-framework-provider-helidon</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.connectors</groupId> + <artifactId>jersey-helidon-connector</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>io.helidon.jersey</groupId> + <artifactId>helidon-jersey-connector</artifactId> + <version>${helidon.connector.version}</version> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <configuration> + <mainClass>org.glassfish.jersey.examples.helloworld.helidon.App</mainClass> + </configuration> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>pre-release</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project>
diff --git a/examples/helloworld-helidon/src/main/java/org/glassfish/jersey/examples/helloworld/helidon/App.java b/examples/helloworld-helidon/src/main/java/org/glassfish/jersey/examples/helloworld/helidon/App.java new file mode 100644 index 0000000..e735863 --- /dev/null +++ b/examples/helloworld-helidon/src/main/java/org/glassfish/jersey/examples/helloworld/helidon/App.java
@@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package org.glassfish.jersey.examples.helloworld.helidon; + +import java.net.URI; +import java.util.logging.Level; +import java.util.logging.Logger; + +import jakarta.ws.rs.SeBootstrap; +import org.glassfish.jersey.helidon.HelidonHttpContainerProvider; +import org.glassfish.jersey.helidon.HelidonHttpServer; +import org.glassfish.jersey.server.JerseySeBootstrapConfiguration; +import org.glassfish.jersey.server.ResourceConfig; + +/** + * Hello world! + */ +public class App { + + static final String ROOT_PATH = "helloworld"; + + private static final URI BASE_URI = URI.create("http://localhost:8080/"); + + public static void main(String[] args) { + try { + System.out.println("\"Hello World\" Jersey Example App on Helidon container."); + + ResourceConfig resourceConfig = new ResourceConfig(HelloWorldResource.class); + final SeBootstrap.Configuration config = + JerseySeBootstrapConfiguration.builder().host("localhost").port(8080).build(); + /* + final WebServer server = HelidonHttpContainerBuilder.builder() + .host("localhost").port(8080).application(resourceConfig).build(); + */ + final HelidonHttpServer server = new HelidonHttpContainerProvider() + .createServer(HelidonHttpServer.class, resourceConfig, config); + server.start(); + + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + @Override + public void run() { + server.stop(); + } + })); + + System.out.println(String.format("Application started. \nTry out %s%s\nStop the application using " + + "CTRL+C.", BASE_URI, ROOT_PATH)); + Thread.currentThread().join(); + } catch (InterruptedException ex) { + Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex); + } + + } +}
diff --git a/examples/helloworld-helidon/src/main/java/org/glassfish/jersey/examples/helloworld/helidon/HelloWorldResource.java b/examples/helloworld-helidon/src/main/java/org/glassfish/jersey/examples/helloworld/helidon/HelloWorldResource.java new file mode 100644 index 0000000..394e18f --- /dev/null +++ b/examples/helloworld-helidon/src/main/java/org/glassfish/jersey/examples/helloworld/helidon/HelloWorldResource.java
@@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package org.glassfish.jersey.examples.helloworld.helidon; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DefaultValue; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; + +@Path("helloworld") +public class HelloWorldResource { + public static final String CLICHED_MESSAGE = "Hello World!"; + + @GET + @Produces("text/plain") + public String getHello() { + return CLICHED_MESSAGE; + } + + @GET + @Path("query1") + @Produces("text/plain") + public String getQueryParameter(@DefaultValue("error1") @QueryParam(value = "test1") String test1, + @DefaultValue("error2") @QueryParam(value = "test2") String test2) { + return test1 + test2; + } + + @POST + @Path("query2") + @Consumes("text/plain") + @Produces("text/plain") + public String postQueryParameter(@DefaultValue("error1") @QueryParam(value = "test1") String test1, + @DefaultValue("error2") @QueryParam(value = "test2") String test2, String entity) { + return entity + test1 + test2; + } + +}
diff --git a/examples/helloworld-helidon/src/test/java/org/glassfish/jersey/examples/helloworld/helidon/CustomLoggingFilter.java b/examples/helloworld-helidon/src/test/java/org/glassfish/jersey/examples/helloworld/helidon/CustomLoggingFilter.java new file mode 100644 index 0000000..caf4575 --- /dev/null +++ b/examples/helloworld-helidon/src/test/java/org/glassfish/jersey/examples/helloworld/helidon/CustomLoggingFilter.java
@@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package org.glassfish.jersey.examples.helloworld.helidon; + +import java.io.IOException; +import java.util.logging.Logger; + +import jakarta.ws.rs.client.ClientRequestContext; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.client.ClientResponseContext; +import jakarta.ws.rs.client.ClientResponseFilter; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerRequestFilter; +import jakarta.ws.rs.container.ContainerResponseContext; +import jakarta.ws.rs.container.ContainerResponseFilter; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Custom logging filter. + * + */ +public class CustomLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter, + ClientRequestFilter, ClientResponseFilter { + + private static final Logger LOGGER = Logger.getLogger(CustomLoggingFilter.class.getName()); + + static int preFilterCalled = 0; + static int postFilterCalled = 0; + + @Override + public void filter(ClientRequestContext context) throws IOException { + LOGGER.info("CustomLoggingFilter.preFilter called"); + assertEquals("bar", context.getConfiguration().getProperty("foo")); + preFilterCalled++; + } + + @Override + public void filter(ClientRequestContext context, ClientResponseContext clientResponseContext) throws IOException { + LOGGER.info("CustomLoggingFilter.postFilter called"); + assertEquals("bar", context.getConfiguration().getProperty("foo")); + postFilterCalled++; + } + + @Override + public void filter(ContainerRequestContext context) throws IOException { + LOGGER.info("CustomLoggingFilter.preFilter called"); + assertEquals("bar", context.getProperty("foo")); + preFilterCalled++; + } + + @Override + public void filter(ContainerRequestContext context, ContainerResponseContext containerResponseContext) throws IOException { + LOGGER.info("CustomLoggingFilter.postFilter called"); + assertEquals("bar", context.getProperty("foo")); + postFilterCalled++; + } +} +
diff --git a/examples/helloworld-helidon/src/test/java/org/glassfish/jersey/examples/helloworld/helidon/HelloWorldTest.java b/examples/helloworld-helidon/src/test/java/org/glassfish/jersey/examples/helloworld/helidon/HelloWorldTest.java new file mode 100644 index 0000000..ae6d0f5 --- /dev/null +++ b/examples/helloworld-helidon/src/test/java/org/glassfish/jersey/examples/helloworld/helidon/HelloWorldTest.java
@@ -0,0 +1,263 @@ +/* + * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package org.glassfish.jersey.examples.helloworld.helidon; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.InvocationCallback; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; + +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.helidon.connector.HelidonConnectorProvider; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.TestProperties; +import org.glassfish.jersey.test.helidon.HelidonTestContainerFactory; +import org.glassfish.jersey.test.spi.TestContainerException; +import org.glassfish.jersey.test.spi.TestContainerFactory; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.api.parallel.ResourceAccessMode; +import org.junit.jupiter.api.parallel.ResourceLock; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class HelloWorldTest extends JerseyTest { + + @Override + protected ResourceConfig configure() { + enable(TestProperties.LOG_TRAFFIC); + // enable(TestProperties.DUMP_ENTITY); + return new ResourceConfig(HelloWorldResource.class); + } + + @Override + protected void configureClient(ClientConfig clientConfig) { + clientConfig.connectorProvider(new HelidonConnectorProvider()); + } + + @Override + protected TestContainerFactory getTestContainerFactory() throws TestContainerException { + return new HelidonTestContainerFactory(); + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ) + public void testHelloWorld() throws Exception { + URL getUrl = UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).build().toURL(); + HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection(); + try { + connection.setDoOutput(true); + connection.setInstanceFollowRedirects(false); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "text/plain"); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + } finally { + connection.disconnect(); + } + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ) + public void testConnection() { + Response response = target().path(App.ROOT_PATH).request("text/plain").get(); + assertEquals(200, response.getStatus()); + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ) + public void testClientStringResponse() { + String s = target().path(App.ROOT_PATH).request().get(String.class); + assertEquals(HelloWorldResource.CLICHED_MESSAGE, s); + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ) + public void testAsyncClientRequests() throws InterruptedException { + final int REQUESTS = 10; + final CountDownLatch latch = new CountDownLatch(REQUESTS); + final long tic = System.currentTimeMillis(); + for (int i = 0; i < REQUESTS; i++) { + final int id = i; + target().path(App.ROOT_PATH).request().async().get(new InvocationCallback<Response>() { + @Override + public void completed(Response response) { + try { + final String result = response.readEntity(String.class); + assertEquals(HelloWorldResource.CLICHED_MESSAGE, result); + } finally { + latch.countDown(); + } + } + + @Override + public void failed(Throwable error) { + error.printStackTrace(); + latch.countDown(); + } + }); + } + latch.await(10 * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS); + final long toc = System.currentTimeMillis(); + Logger.getLogger(HelloWorldTest.class.getName()).info("Executed in: " + (toc - tic)); + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ) + public void testHead() { + Response response = target().path(App.ROOT_PATH).request().head(); + assertEquals(200, response.getStatus()); + assertEquals(MediaType.TEXT_PLAIN_TYPE, response.getMediaType()); + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ) + public void testFooBarOptions() { + Response response = target().path(App.ROOT_PATH).request().header("Accept", "foo/bar").options(); + assertEquals(200, response.getStatus()); + final String allowHeader = response.getHeaderString("Allow"); + _checkAllowContent(allowHeader); + assertEquals("foo/bar", response.getMediaType().toString()); + assertEquals(0, response.getLength()); + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ) + public void testTextPlainOptions() { + Response response = target().path(App.ROOT_PATH).request().header("Accept", MediaType.TEXT_PLAIN).options(); + assertEquals(200, response.getStatus()); + final String allowHeader = response.getHeaderString("Allow"); + _checkAllowContent(allowHeader); + assertEquals(MediaType.TEXT_PLAIN_TYPE, response.getMediaType()); + final String responseBody = response.readEntity(String.class); + _checkAllowContent(responseBody); + } + + private void _checkAllowContent(final String content) { + assertTrue(content.contains("GET")); + assertTrue(content.contains("HEAD")); + assertTrue(content.contains("OPTIONS")); + } + + @Test + @Execution(ExecutionMode.CONCURRENT) + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ) + public void testMissingResourceNotFound() { + Response response; + + response = target().path(App.ROOT_PATH + "arbitrary").request().get(); + assertEquals(404, response.getStatus()); + + response = target().path(App.ROOT_PATH).path("arbitrary").request().get(); + assertEquals(404, response.getStatus()); + } + + @Test + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ_WRITE) + public void testLoggingFilterClientClass() { + Client client = client(); + client.register(CustomLoggingFilter.class).property("foo", "bar"); + CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0; + String s = target().path(App.ROOT_PATH).request().get(String.class); + assertEquals(HelloWorldResource.CLICHED_MESSAGE, s); + assertEquals(1, CustomLoggingFilter.preFilterCalled); + assertEquals(1, CustomLoggingFilter.postFilterCalled); + } + + @Test + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ_WRITE) + public void testLoggingFilterClientInstance() { + Client client = client(); + client.register(new CustomLoggingFilter()).property("foo", "bar"); + CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0; + String s = target().path(App.ROOT_PATH).request().get(String.class); + assertEquals(HelloWorldResource.CLICHED_MESSAGE, s); + assertEquals(1, CustomLoggingFilter.preFilterCalled); + assertEquals(1, CustomLoggingFilter.postFilterCalled); + } + + @Test + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ_WRITE) + public void testLoggingFilterTargetClass() { + WebTarget target = target().path(App.ROOT_PATH); + target.register(CustomLoggingFilter.class).property("foo", "bar"); + CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0; + String s = target.request().get(String.class); + assertEquals(HelloWorldResource.CLICHED_MESSAGE, s); + assertEquals(1, CustomLoggingFilter.preFilterCalled); + assertEquals(1, CustomLoggingFilter.postFilterCalled); + } + + @Test + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ_WRITE) + public void testLoggingFilterTargetInstance() { + WebTarget target = target().path(App.ROOT_PATH); + target.register(new CustomLoggingFilter()).property("foo", "bar"); + CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0; + String s = target.request().get(String.class); + assertEquals(HelloWorldResource.CLICHED_MESSAGE, s); + assertEquals(1, CustomLoggingFilter.preFilterCalled); + assertEquals(1, CustomLoggingFilter.postFilterCalled); + } + + @Test + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ_WRITE) + public void testConfigurationUpdate() { + Client client1 = client(); + client1.register(CustomLoggingFilter.class).property("foo", "bar"); + + Client client = ClientBuilder.newClient(client1.getConfiguration()); + CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0; + String s = target().path(App.ROOT_PATH).request().get(String.class); + assertEquals(HelloWorldResource.CLICHED_MESSAGE, s); + assertEquals(1, CustomLoggingFilter.preFilterCalled); + assertEquals(1, CustomLoggingFilter.postFilterCalled); + } + + @Test + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ_WRITE) + public void testQueryParameterGet() { + String result = target().path(App.ROOT_PATH + "/query1").queryParam("test1", "expected1") + .queryParam("test2", "expected2").request().get(String.class); + assertEquals("expected1expected2", result); + } + + @Test + @ResourceLock(value = "dummy", mode = ResourceAccessMode.READ_WRITE) + public void testQueryParameterPost() { + String result = target().path(App.ROOT_PATH + "/query2").queryParam("test1", "expected1") + .queryParam("test2", "expected2").request("text/plain").post(Entity.entity("entity", "text/plain")) + .readEntity(String.class); + assertEquals("entityexpected1expected2", result); + } + +}
diff --git a/examples/pom.xml b/examples/pom.xml index 72695a3..909db82 100644 --- a/examples/pom.xml +++ b/examples/pom.xml
@@ -292,6 +292,15 @@ <module>helloworld-spring-annotations</module> </modules> </profile> + <profile> + <id>jdk21</id> + <activation> + <jdk>[21,)</jdk> + </activation> + <modules> + <module>helloworld-helidon</module> + </modules> + </profile> </profiles> </project>
diff --git a/pom.xml b/pom.xml index 645d657..1f6bb54 100644 --- a/pom.xml +++ b/pom.xml
@@ -2191,9 +2191,9 @@ <microprofile.rest.client3.version>3.0.1</microprofile.rest.client3.version> <microprofile.rest.client.version>4.0</microprofile.rest.client.version> <helidon.config.version>3.2.12</helidon.config.version> - <helidon.container.version>4.2.4</helidon.container.version> + <helidon.container.version>4.3.1</helidon.container.version> <helidon3.connector.version>3.2.12</helidon3.connector.version> - <helidon.connector.version>4.2.4</helidon.connector.version> + <helidon.connector.version>4.3.1</helidon.connector.version> <helidon.config.11.version>1.4.15</helidon.config.11.version> <!-- JDK 11- support --> <smallrye.config.version>3.7.1</smallrye.config.version>
diff --git a/test-framework/providers/bundle/pom.xml b/test-framework/providers/bundle/pom.xml index 567e835..ac11835 100644 --- a/test-framework/providers/bundle/pom.xml +++ b/test-framework/providers/bundle/pom.xml
@@ -75,4 +75,19 @@ <version>${project.version}</version> </dependency> </dependencies> + <profiles> + <profile> + <id>helidon-container</id> + <activation> + <jdk>[21,)</jdk> + </activation> + <dependencies> + <dependency> + <groupId>org.glassfish.jersey.test-framework.providers</groupId> + <artifactId>jersey-test-framework-provider-helidon</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </profile> + </profiles> </project>
diff --git a/test-framework/providers/helidon-http/pom.xml b/test-framework/providers/helidon-http/pom.xml index 34a3eea..2fad9c1 100644 --- a/test-framework/providers/helidon-http/pom.xml +++ b/test-framework/providers/helidon-http/pom.xml
@@ -43,6 +43,17 @@ <artifactId>jersey-container-helidon-http</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>io.helidon.webserver</groupId> + <artifactId>helidon-webserver</artifactId> + <version>${helidon.container.version}</version> + </dependency> + <dependency> + <groupId>io.helidon.service</groupId> + <artifactId>helidon-service-registry</artifactId> + <version>${helidon.container.version}</version> + <scope>runtime</scope> + </dependency> </dependencies> </project>