From 90803b3a7f73decc6dfb5ee9d133e06ce35fb37a Mon Sep 17 00:00:00 2001 From: ndr_brt Date: Tue, 25 Jul 2023 07:53:45 +0200 Subject: [PATCH] fix(jersey): bind controllers to the correct context (#3327) --- .../edc/web/jersey/JerseyRestService.java | 12 ++++-- .../edc/web/jersey/JerseyRestServiceTest.java | 39 +++++++++++-------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/JerseyRestService.java b/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/JerseyRestService.java index 9d9770c86d8..e36f52476ed 100644 --- a/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/JerseyRestService.java +++ b/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/JerseyRestService.java @@ -88,7 +88,7 @@ private void registerContext(String contextAlias, List controllers) { // Register controller (JAX-RS resources) with Jersey. Instances instead of classes are used so extensions may inject them with dependencies and manage their lifecycle. // In order to use instances with Jersey, the controller types must be registered along with an {@link AbstractBinder} that maps those types to the instances. resourceConfig.registerClasses(controllers.stream().map(Object::getClass).collect(toSet())); - resourceConfig.registerInstances(new Binder()); + resourceConfig.registerInstances(new Binder(controllers)); resourceConfig.registerInstances(new ObjectMapperProvider(typeManager.getMapper())); resourceConfig.registerInstances(new EdcApiExceptionMapper()); resourceConfig.registerInstances(new UnexpectedExceptionMapper(monitor)); @@ -109,11 +109,17 @@ private void registerContext(String contextAlias, List controllers) { /** * Maps (JAX-RS resource) instances to types. */ - private class Binder extends AbstractBinder { + private static class Binder extends AbstractBinder { + + private final List controllers; + + Binder(List controllers) { + this.controllers = controllers; + } @Override protected void configure() { - controllers.forEach((key, value) -> value.forEach(c -> bind(c).to((Class) c.getClass()))); + controllers.forEach(c -> bind(c).to((Class) c.getClass())); } } diff --git a/extensions/common/http/jersey-core/src/test/java/org/eclipse/edc/web/jersey/JerseyRestServiceTest.java b/extensions/common/http/jersey-core/src/test/java/org/eclipse/edc/web/jersey/JerseyRestServiceTest.java index f5556e4fa6a..4f62c3f700d 100644 --- a/extensions/common/http/jersey-core/src/test/java/org/eclipse/edc/web/jersey/JerseyRestServiceTest.java +++ b/extensions/common/http/jersey-core/src/test/java/org/eclipse/edc/web/jersey/JerseyRestServiceTest.java @@ -27,7 +27,6 @@ import org.eclipse.edc.web.jetty.JettyService; import org.eclipse.edc.web.jetty.PortMapping; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -42,6 +41,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -50,11 +50,11 @@ public class JerseyRestServiceTest { private final int httpPort = getFreePort(); private JerseyRestService jerseyRestService; private JettyService jettyService; - private Monitor monitorMock; + private final Monitor monitor = mock(Monitor.class); - @BeforeEach - void setup() { - monitorMock = mock(Monitor.class); + @AfterEach + void teardown() { + jettyService.shutdown(); } @Test @@ -79,8 +79,10 @@ void verifyAnotherContextPath() { PortMapping.getDefault(httpPort), new PortMapping("path", anotherPort, "/path") ); - jerseyRestService.registerResource("path", new TestController()); - jerseyRestService.registerResource(new TestController()); + var pathController = spy(new TestController()); + var defaultController = spy(new TestController()); + jerseyRestService.registerResource("path", pathController); + jerseyRestService.registerResource(defaultController); jerseyRestService.start(); given() @@ -89,11 +91,17 @@ void verifyAnotherContextPath() { .statusCode(200) .body(is("exists")); + verify(pathController).foo(); + verifyNoInteractions(defaultController); + given() .get("http://localhost:" + httpPort + "/api/test/resource") .then() .statusCode(200) .body(is("exists")); + + verifyNoMoreInteractions(pathController); + verify(defaultController).foo(); } @Test @@ -106,7 +114,9 @@ void verifyIdenticalContextPats_throwsException() { jerseyRestService.registerResource("path1", new TestController()); jerseyRestService.registerResource("path2", new TestController()); - assertThatThrownBy(() -> jerseyRestService.start()).isInstanceOf(EdcException.class).hasRootCauseInstanceOf(IllegalStateException.class); + + assertThatThrownBy(() -> jerseyRestService.start()).isInstanceOf(EdcException.class) + .hasRootCauseInstanceOf(IllegalStateException.class); } @Test @@ -197,6 +207,7 @@ void verifyIdenticalPathsRaiseException() { jerseyRestService.registerResource("another", new TestController()); jerseyRestService.registerResource("yet-another", new TestController()); + assertThatThrownBy(() -> jerseyRestService.start()).isInstanceOf(EdcException.class) .hasRootCauseInstanceOf(IllegalStateException.class); } @@ -211,20 +222,16 @@ void verifyInvalidContextAlias_shouldThrowException() { ); jerseyRestService.registerResource("not-exists", new TestController()); + assertThatThrownBy(() -> jerseyRestService.start()).isInstanceOf(EdcException.class) .hasRootCauseInstanceOf(IllegalArgumentException.class); } - @AfterEach - void teardown() { - jettyService.shutdown(); - } - private void startJetty(PortMapping... mapping) { - JettyConfiguration config = new JettyConfiguration(null, null); + var config = new JettyConfiguration(null, null); Arrays.stream(mapping).forEach(config::portMapping); - jettyService = new JettyService(config, monitorMock); - jerseyRestService = new JerseyRestService(jettyService, new TypeManager(), JerseyConfiguration.none(), monitorMock); + jettyService = new JettyService(config, monitor); + jerseyRestService = new JerseyRestService(jettyService, new TypeManager(), JerseyConfiguration.none(), monitor); jettyService.start(); }