diff --git a/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/InstrumentedHttpClientFactoryFactory.java b/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/InstrumentedHttpClientFactoryFactory.java index 2a76f2f..1e37ad4 100644 --- a/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/InstrumentedHttpClientFactoryFactory.java +++ b/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/InstrumentedHttpClientFactoryFactory.java @@ -21,9 +21,16 @@ import com.codahale.metrics.MetricRegistry; import io.bootique.annotation.BQConfig; import io.bootique.annotation.BQConfigProperty; +import io.bootique.di.Injector; import io.bootique.jersey.client.HttpClientFactoryFactory; +import io.bootique.jersey.client.JerseyClientFeatures; import io.bootique.jersey.client.instrumented.mdc.MDCAwareClientAsyncExecutorProvider; +import jakarta.ws.rs.core.Feature; import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.spi.ConnectorProvider; + +import javax.inject.Inject; +import java.util.Set; /** * @since 3.0 @@ -31,19 +38,31 @@ @BQConfig public class InstrumentedHttpClientFactoryFactory extends HttpClientFactoryFactory { + private final MetricRegistry metricRegistry; + private JerseyClientHealthChecksFactory health; + @Inject + public InstrumentedHttpClientFactoryFactory( + Injector injector, + @JerseyClientFeatures Set features, + ConnectorProvider connectorProvider, + MetricRegistry metricRegistry) { + super(injector, features, connectorProvider); + this.metricRegistry = metricRegistry; + } + @BQConfigProperty("Configures client healthcheck thresholds") public void setHealth(JerseyClientHealthChecksFactory health) { this.health = health; } - public JerseyClientHealthChecks createHealthChecks(MetricRegistry metricRegistry) { - return getHealth().createHealthChecks(metricRegistry); + public JerseyClientHealthChecks createHealthChecks() { + return getHealth().createHealthChecks(); } private JerseyClientHealthChecksFactory getHealth() { - return health != null ? health : new JerseyClientHealthChecksFactory(); + return health != null ? health : new JerseyClientHealthChecksFactory(metricRegistry); } @Override diff --git a/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/JerseyClientHealthChecksFactory.java b/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/JerseyClientHealthChecksFactory.java index 1dcd435..8f64b27 100644 --- a/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/JerseyClientHealthChecksFactory.java +++ b/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/JerseyClientHealthChecksFactory.java @@ -8,6 +8,7 @@ import io.bootique.metrics.health.check.ValueRange; import io.bootique.metrics.health.check.ValueRangeCheck; +import javax.inject.Inject; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; @@ -15,31 +16,38 @@ @BQConfig public class JerseyClientHealthChecksFactory { - public static final String REQUESTS_PER_MIN_CHECK = JerseyClientInstrumentedModule + public static final String REQUESTS_PER_MIN_CHECK = JerseyClientInstrumentedModule .METRIC_NAMING .name("Requests", "PerMin"); + private final MetricRegistry metricRegistry; + private DoubleRangeFactory requestsPerMin; + @Inject + public JerseyClientHealthChecksFactory(MetricRegistry metricRegistry) { + this.metricRegistry = metricRegistry; + } + @BQConfigProperty public void setRequestsPerMin(DoubleRangeFactory requestsPerMin) { this.requestsPerMin = requestsPerMin; } - public JerseyClientHealthChecks createHealthChecks(MetricRegistry metricRegistry) { - return new JerseyClientHealthChecks(createHealthChecksMap(metricRegistry)); + public JerseyClientHealthChecks createHealthChecks() { + return new JerseyClientHealthChecks(createHealthChecksMap()); } - protected Map createHealthChecksMap(MetricRegistry registry) { + protected Map createHealthChecksMap() { Map checks = new HashMap<>(3); - checks.put(REQUESTS_PER_MIN_CHECK, createTimeRequestsCheck(registry)); + checks.put(REQUESTS_PER_MIN_CHECK, createTimeRequestsCheck()); return checks; } - private HealthCheck createTimeRequestsCheck(MetricRegistry registry) { + private HealthCheck createTimeRequestsCheck() { ValueRange range = getRequestsPerMin(); Supplier deferredGauge = () - -> registry.timer(RequestTimer.TIMER_NAME).getOneMinuteRate(); + -> metricRegistry.timer(RequestTimer.TIMER_NAME).getOneMinuteRate(); return new ValueRangeCheck<>(range, deferredGauge); } diff --git a/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/JerseyClientInstrumentedModule.java b/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/JerseyClientInstrumentedModule.java index bea243d..392fe22 100644 --- a/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/JerseyClientInstrumentedModule.java +++ b/bootique-jersey-jakarta-client-instrumented/src/main/java/io/bootique/jersey/client/instrumented/JerseyClientInstrumentedModule.java @@ -80,7 +80,7 @@ InstrumentedHttpClientFactoryFactory providerInstrumentedHttpClientFactoryFactor @Provides @Singleton - JerseyClientHealthChecks provideThresholdHealthCheck(InstrumentedHttpClientFactoryFactory factory, MetricRegistry metricRegistry) { - return factory.createHealthChecks(metricRegistry); + JerseyClientHealthChecks provideThresholdHealthCheck(InstrumentedHttpClientFactoryFactory factory) { + return factory.createHealthChecks(); } } diff --git a/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/InstrumentedClientIT.java b/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/InstrumentedClientIT.java index e435870..28d92bc 100644 --- a/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/InstrumentedClientIT.java +++ b/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/InstrumentedClientIT.java @@ -31,8 +31,6 @@ import io.bootique.jetty.server.ServerHolder; import io.bootique.junit5.BQApp; import io.bootique.junit5.BQTest; -import io.bootique.junit5.BQTestFactory; -import io.bootique.junit5.BQTestTool; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.ProcessingException; @@ -40,7 +38,6 @@ import jakarta.ws.rs.client.Client; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.Collection; @@ -63,10 +60,9 @@ public class InstrumentedClientIT { .module(jetty.moduleReplacingConnectors()) .createRuntime(); - @BQTestTool - final BQTestFactory testFactory = new BQTestFactory(); - - BQRuntime client; + // important to recreate the client app before every test as it starts with zero metrics counters + @BQApp(skipRun = true) + final BQRuntime client = Bootique.app().autoLoadModules().createRuntime(); private static String getUrlBadPort(String getUrl) { ServerHolder serverHolder = server.getInstance(ServerHolder.class); @@ -75,12 +71,6 @@ private static String getUrlBadPort(String getUrl) { return getUrl.replace(":" + goodPort, ":" + badPort); } - @BeforeEach - public void resetClient() { - // important to recreate the client app before every test as it starts with zero metrics counters - client = testFactory.app().autoLoadModules().createRuntime(); - } - @Test public void metrics() { // fault filter to init metrics diff --git a/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/InstrumentedHttpClientFactoryFactoryTest.java b/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/InstrumentedHttpClientFactoryFactoryTest.java index 955c375..9604912 100644 --- a/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/InstrumentedHttpClientFactoryFactoryTest.java +++ b/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/InstrumentedHttpClientFactoryFactoryTest.java @@ -18,6 +18,7 @@ */ package io.bootique.jersey.client.instrumented; +import com.codahale.metrics.MetricRegistry; import io.bootique.di.Injector; import io.bootique.jersey.client.ClientAsyncExecutorProvider; import io.bootique.jersey.client.instrumented.mdc.MDCAwareClientAsyncExecutorProvider; @@ -38,8 +39,11 @@ public class InstrumentedHttpClientFactoryFactoryTest { @Test public void createClientFactory_AsyncThreadPool() { - Client client = new InstrumentedHttpClientFactoryFactory() - .createClientFactory(mockInjector, Set.of(), new HttpUrlConnectorProvider()).newClient(); + Client client = new InstrumentedHttpClientFactoryFactory( + mockInjector, + Set.of(), + new HttpUrlConnectorProvider(), + mock(MetricRegistry.class)).createClientFactory().newClient(); try { assertTrue(client.getConfiguration().isRegistered(MDCAwareClientAsyncExecutorProvider.class)); diff --git a/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/healthcheck/RangeHealthCheckTest.java b/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/healthcheck/RangeHealthCheckTest.java index f63b391..e748306 100644 --- a/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/healthcheck/RangeHealthCheckTest.java +++ b/bootique-jersey-jakarta-client-instrumented/src/test/java/io/bootique/jersey/client/instrumented/healthcheck/RangeHealthCheckTest.java @@ -24,7 +24,7 @@ public class RangeHealthCheckTest { @BeforeEach public void before() { this.registry = Mockito.mock(MetricRegistry.class); - this.healthCheckFactory = new JerseyClientHealthChecksFactory(); + this.healthCheckFactory = new JerseyClientHealthChecksFactory(registry); DoubleRangeFactory timeRequestsThresholds = new DoubleRangeFactory(); timeRequestsThresholds.setCritical(0.05); timeRequestsThresholds.setWarning(0.01); @@ -33,7 +33,7 @@ public void before() { Mockito.when(registry.timer(RequestTimer.TIMER_NAME)).thenReturn(Mockito.mock(Timer.class)); - JerseyClientHealthChecks rangeHealthCheck = healthCheckFactory.createHealthChecks(registry); + JerseyClientHealthChecks rangeHealthCheck = healthCheckFactory.createHealthChecks(); this.healthCheckRegistry = new HealthCheckRegistry(rangeHealthCheck.getHealthChecks()); } diff --git a/bootique-jersey-jakarta-client/src/main/java/io/bootique/jersey/client/HttpClientFactoryFactory.java b/bootique-jersey-jakarta-client/src/main/java/io/bootique/jersey/client/HttpClientFactoryFactory.java index 81c8867..4d1b5fb 100644 --- a/bootique-jersey-jakarta-client/src/main/java/io/bootique/jersey/client/HttpClientFactoryFactory.java +++ b/bootique-jersey-jakarta-client/src/main/java/io/bootique/jersey/client/HttpClientFactoryFactory.java @@ -38,6 +38,7 @@ import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.message.GZipEncoder; +import javax.inject.Inject; import java.security.KeyStore; import java.util.Collections; import java.util.HashMap; @@ -48,6 +49,10 @@ @BQConfig("Configures HttpClientFactory, including named authenticators, timeouts, SSL certificates, etc.") public class HttpClientFactoryFactory { + private final Injector injector; + private final Set features; + private final ConnectorProvider connectorProvider; + protected boolean followRedirects; protected boolean compression; protected int readTimeoutMs; @@ -57,7 +62,16 @@ public class HttpClientFactoryFactory { protected Map trustStores; protected Map targets; - public HttpClientFactoryFactory() { + @Inject + public HttpClientFactoryFactory( + Injector injector, + @JerseyClientFeatures Set features, + ConnectorProvider connectorProvider) { + + this.injector = injector; + this.features = features; + this.connectorProvider = connectorProvider; + this.followRedirects = true; this.compression = true; } @@ -130,10 +144,7 @@ public HttpTargets createTargets(HttpClientFactory clientFactory) { return new DefaultHttpTargets(createNamedTargets(clientFactory)); } - public HttpClientFactory createClientFactory( - Injector injector, - Set features, - ConnectorProvider connectorProvider) { + public HttpClientFactory createClientFactory() { ClientConfig config = createConfig(features, connectorProvider); diff --git a/bootique-jersey-jakarta-client/src/main/java/io/bootique/jersey/client/JerseyClientModule.java b/bootique-jersey-jakarta-client/src/main/java/io/bootique/jersey/client/JerseyClientModule.java index ab01596..65ea13e 100644 --- a/bootique-jersey-jakarta-client/src/main/java/io/bootique/jersey/client/JerseyClientModule.java +++ b/bootique-jersey-jakarta-client/src/main/java/io/bootique/jersey/client/JerseyClientModule.java @@ -26,12 +26,10 @@ import io.bootique.di.Injector; import io.bootique.di.Key; import io.bootique.di.Provides; -import jakarta.ws.rs.core.Feature; import org.glassfish.jersey.client.HttpUrlConnectorProvider; import org.glassfish.jersey.client.spi.ConnectorProvider; import javax.inject.Singleton; -import java.util.Set; public class JerseyClientModule implements BQModule { @@ -77,13 +75,8 @@ HttpClientFactoryFactory provideClientFactoryFactory(ConfigurationFactory config @Provides @Singleton - HttpClientFactory provideClientFactory( - HttpClientFactoryFactory factoryFactory, - Injector injector, - @JerseyClientFeatures Set features, - ConnectorProvider connectorProvider) { - - return factoryFactory.createClientFactory(injector, features, connectorProvider); + HttpClientFactory provideClientFactory(HttpClientFactoryFactory factoryFactory) { + return factoryFactory.createClientFactory(); } @Provides diff --git a/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactoryIT.java b/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactoryIT.java index 03d0cd2..2437e6d 100644 --- a/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactoryIT.java +++ b/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactoryIT.java @@ -63,9 +63,13 @@ public class HttpClientFactoryFactoryIT { @Test public void createClientFactory_FollowRedirect() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); + factoryFactory.setFollowRedirects(true); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target(jetty.getUrl()).path("/302").request().get(); assertEquals(Status.OK.getStatusCode(), r.getStatus()); @@ -75,9 +79,12 @@ public void createClientFactory_FollowRedirect() { @Test public void createClientFactory_NoFollowRedirect() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); factoryFactory.setFollowRedirects(false); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target(jetty.getUrl()).path("/302").request().get(); JettyTester.assertStatus(r, 307).assertHeader("location", jetty.getUrl() + "/get"); @@ -86,8 +93,11 @@ public void createClientFactory_NoFollowRedirect() { @Test public void createClientFactory_DefaultRedirect_Follow() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target(jetty.getUrl()).path("/302").request().get(); assertEquals(Status.OK.getStatusCode(), r.getStatus()); @@ -97,9 +107,12 @@ public void createClientFactory_DefaultRedirect_Follow() { @Test public void createClientFactory_Compression() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); factoryFactory.setCompression(true); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target(jetty.getUrl()).path("/getbig").request().get(); assertEquals(Status.OK.getStatusCode(), r.getStatus()); @@ -109,9 +122,12 @@ public void createClientFactory_Compression() { @Test public void createClientFactory_NoCompression() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); factoryFactory.setCompression(false); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target(jetty.getUrl()).path("/getbig").request().get(); assertEquals(Status.OK.getStatusCode(), r.getStatus()); @@ -121,9 +137,12 @@ public void createClientFactory_NoCompression() { @Test public void createClientFactory_CompressionDefault() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); factoryFactory.setCompression(true); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target(jetty.getUrl()).path("/getbig").request().get(); assertEquals(Status.OK.getStatusCode(), r.getStatus()); @@ -133,8 +152,11 @@ public void createClientFactory_CompressionDefault() { @Test public void createClientFactory_NoTimeout() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target(jetty.getUrl()).path("/slowget").request().get(); assertEquals(Status.OK.getStatusCode(), r.getStatus()); @@ -144,9 +166,12 @@ public void createClientFactory_NoTimeout() { @Test public void createClientFactory_LongTimeout() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); factoryFactory.setReadTimeoutMs(2000); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target(jetty.getUrl()).path("/slowget").request().get(); assertEquals(Status.OK.getStatusCode(), r.getStatus()); @@ -156,9 +181,12 @@ public void createClientFactory_LongTimeout() { @Test public void createClientFactory_ReadTimeout() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); factoryFactory.setReadTimeoutMs(50); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); assertThrows(ProcessingException.class, () -> client.target(jetty.getUrl()).path("/slowget").request().get()); @@ -167,7 +195,10 @@ public void createClientFactory_ReadTimeout() { @Test public void createClientFactory_BasicAuth() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory( + mockInjector, + Collections.emptySet(), + new HttpUrlConnectorProvider()); BasicAuthenticatorFactory authenticator = new BasicAuthenticatorFactory(); authenticator.setPassword("p1"); @@ -178,7 +209,7 @@ public void createClientFactory_BasicAuth() { factoryFactory.setAuth(auth); Client client = factoryFactory - .createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()) + .createClientFactory() .newBuilder().auth("a1") .build(); diff --git a/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactoryTest.java b/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactoryTest.java index 1af52b3..2ff3fc1 100644 --- a/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactoryTest.java +++ b/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactoryTest.java @@ -39,8 +39,10 @@ public class HttpClientFactoryFactoryTest { @Test public void createClientFactory_AsyncThreadPool() { - Client client = new HttpClientFactoryFactory() - .createClientFactory(mockInjector, Set.of(), new HttpUrlConnectorProvider()).newClient(); + Client client = new HttpClientFactoryFactory( + mockInjector, + Set.of(), + new HttpUrlConnectorProvider()).createClientFactory().newClient(); try { assertTrue(client.getConfiguration().isRegistered(ClientAsyncExecutorProvider.class)); @@ -52,13 +54,13 @@ public void createClientFactory_AsyncThreadPool() { @Test public void createClientFactory() { - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(mockInjector, Collections.emptySet(), mock(ConnectorProvider.class)); factoryFactory.setAsyncThreadPoolSize(5); factoryFactory.setConnectTimeoutMs(101); factoryFactory.setFollowRedirects(true); factoryFactory.setReadTimeoutMs(203); - HttpClientFactory factory = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), mock(ConnectorProvider.class)); + HttpClientFactory factory = factoryFactory.createClientFactory(); assertNotNull(factory); Client client = factory.newClient(); diff --git a/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactory_ConfigIT.java b/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactory_ConfigIT.java index 865ee84..7668666 100644 --- a/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactory_ConfigIT.java +++ b/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactory_ConfigIT.java @@ -19,57 +19,32 @@ package io.bootique.jersey.client; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.fasterxml.jackson.dataformat.yaml.YAMLParser; +import io.bootique.BQRuntime; +import io.bootique.Bootique; import io.bootique.config.ConfigurationFactory; -import io.bootique.config.PolymorphicConfiguration; -import io.bootique.config.TypesFactory; -import io.bootique.config.jackson.JsonConfigurationFactory; -import io.bootique.jackson.DefaultJacksonService; -import io.bootique.jackson.JacksonService; import io.bootique.jersey.client.auth.AuthenticatorFactory; import io.bootique.jersey.client.auth.BasicAuthenticatorFactory; -import io.bootique.log.DefaultBootLogger; -import org.junit.jupiter.api.BeforeEach; +import io.bootique.junit5.BQApp; +import io.bootique.junit5.BQTest; import org.junit.jupiter.api.Test; -import java.io.IOException; - import static org.junit.jupiter.api.Assertions.*; +@BQTest public class HttpClientFactoryFactory_ConfigIT { - private TypesFactory typesFactory; - - @BeforeEach - public void before() { - typesFactory = new TypesFactory<>( - getClass().getClassLoader(), - PolymorphicConfiguration.class, - new DefaultBootLogger(true)); - } - - private ConfigurationFactory factory(String yaml) { - - // not using a mock; making sure all Jackson extensions are loaded - JacksonService jacksonService = new DefaultJacksonService(typesFactory.getTypes()); - - YAMLParser parser; - try { - parser = new YAMLFactory().createParser(yaml); - JsonNode rootNode = jacksonService.newObjectMapper().readTree(parser); - return new JsonConfigurationFactory(rootNode, jacksonService.newObjectMapper()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + @BQApp(skipRun = true) + static final BQRuntime app = Bootique + .app("-c", "classpath:io/bootique/jersey/client/HttpClientFactoryFactory_ConfigIT.yml") + .autoLoadModules() + .createRuntime(); @Test public void clientFlags() { - HttpClientFactoryFactory factory = factory( - "r:\n followRedirects: true\n connectTimeoutMs: 78\n readTimeoutMs: 66\n asyncThreadPoolSize: 44\n") - .config(HttpClientFactoryFactory.class, "r"); + + HttpClientFactoryFactory factory = app + .getInstance(ConfigurationFactory.class) + .config(HttpClientFactoryFactory.class, "a"); assertEquals(true, factory.followRedirects); assertEquals(78, factory.connectTimeoutMs); @@ -79,9 +54,9 @@ public void clientFlags() { @Test public void authTypes() { - HttpClientFactoryFactory factory = factory( - "r:\n auth:\n a1:\n type: basic\n username: u1\n password: p1\n") - .config(HttpClientFactoryFactory.class, "r"); + HttpClientFactoryFactory factory = app + .getInstance(ConfigurationFactory.class) + .config(HttpClientFactoryFactory.class, "b"); assertNotNull(factory.auth); assertEquals(1, factory.auth.size()); diff --git a/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactory_LoggingIT.java b/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactory_LoggingIT.java index 200f274..4524438 100644 --- a/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactory_LoggingIT.java +++ b/bootique-jersey-jakarta-client/src/test/java/io/bootique/jersey/client/HttpClientFactoryFactory_LoggingIT.java @@ -94,9 +94,9 @@ public void createClientFactory_Debug() throws IOException, InterruptedException startApp("debug.yml"); - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()); factoryFactory.setFollowRedirects(true); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target("http://127.0.0.1:8080/get").request().get(); assertEquals(Response.Status.OK.getStatusCode(), r.getStatus()); @@ -118,9 +118,9 @@ public void createClientFactory_Warn() throws IOException, InterruptedException startApp("warn.yml"); - HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(); + HttpClientFactoryFactory factoryFactory = new HttpClientFactoryFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()); factoryFactory.setFollowRedirects(true); - Client client = factoryFactory.createClientFactory(mockInjector, Collections.emptySet(), new HttpUrlConnectorProvider()).newClient(); + Client client = factoryFactory.createClientFactory().newClient(); Response r = client.target("http://127.0.0.1:8080/get").request().get(); assertEquals(Response.Status.OK.getStatusCode(), r.getStatus()); diff --git a/bootique-jersey-jakarta-client/src/test/resources/io/bootique/jersey/client/HttpClientFactoryFactory_ConfigIT.yml b/bootique-jersey-jakarta-client/src/test/resources/io/bootique/jersey/client/HttpClientFactoryFactory_ConfigIT.yml new file mode 100644 index 0000000..19c31a3 --- /dev/null +++ b/bootique-jersey-jakarta-client/src/test/resources/io/bootique/jersey/client/HttpClientFactoryFactory_ConfigIT.yml @@ -0,0 +1,12 @@ +a: + followRedirects: true + connectTimeoutMs: 78 + readTimeoutMs: 66 + asyncThreadPoolSize: 44 + +b: + auth: + a1: + type: basic + username: u1 + password: p1 diff --git a/bootique-jersey-jakarta-jackson/src/main/java/io/bootique/jersey/jackson/JerseyJacksonFactory.java b/bootique-jersey-jakarta-jackson/src/main/java/io/bootique/jersey/jackson/JerseyJacksonFactory.java index 05132c5..063ac1b 100644 --- a/bootique-jersey-jakarta-jackson/src/main/java/io/bootique/jersey/jackson/JerseyJacksonFactory.java +++ b/bootique-jersey-jakarta-jackson/src/main/java/io/bootique/jersey/jackson/JerseyJacksonFactory.java @@ -28,6 +28,7 @@ import io.bootique.annotation.BQConfig; import io.bootique.annotation.BQConfigProperty; +import javax.inject.Inject; import java.util.Set; /** @@ -36,18 +37,25 @@ @BQConfig public class JerseyJacksonFactory { + private final Set serializers; + private boolean skipNullProperties; + @Inject + public JerseyJacksonFactory(Set serializers) { + this.serializers = serializers; + } + @BQConfigProperty public void setSkipNullProperties(boolean skipNullProperties) { this.skipNullProperties = skipNullProperties; } - public ObjectMapperResolver createObjectMapperResolver(Set serializers) { - return new ObjectMapperResolver(createObjectMapper(serializers)); + public ObjectMapperResolver createObjectMapperResolver() { + return new ObjectMapperResolver(createObjectMapper()); } - protected ObjectMapper createObjectMapper(Set serializers) { + protected ObjectMapper createObjectMapper() { ObjectMapper mapper = new ObjectMapper() .registerModule(new JavaTimeModule()) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); diff --git a/bootique-jersey-jakarta-jackson/src/main/java/io/bootique/jersey/jackson/JerseyJacksonModule.java b/bootique-jersey-jakarta-jackson/src/main/java/io/bootique/jersey/jackson/JerseyJacksonModule.java index 1540115..53cddf5 100644 --- a/bootique-jersey-jakarta-jackson/src/main/java/io/bootique/jersey/jackson/JerseyJacksonModule.java +++ b/bootique-jersey-jakarta-jackson/src/main/java/io/bootique/jersey/jackson/JerseyJacksonModule.java @@ -18,7 +18,6 @@ */ package io.bootique.jersey.jackson; -import com.fasterxml.jackson.databind.JsonSerializer; import io.bootique.BQModule; import io.bootique.ModuleCrate; import io.bootique.config.ConfigurationFactory; @@ -27,7 +26,6 @@ import io.bootique.jersey.JerseyModule; import javax.inject.Singleton; -import java.util.Set; /** * @since 2.0 @@ -56,13 +54,11 @@ public void configure(Binder binder) { @Singleton @Provides - ObjectMapperResolverFeature provideObjectMapperResolverFeature( - ConfigurationFactory configurationFactory, - Set serializers) { + ObjectMapperResolverFeature provideObjectMapperResolverFeature(ConfigurationFactory configFactory) { - ObjectMapperResolver omr = configurationFactory + ObjectMapperResolver omr = configFactory .config(JerseyJacksonFactory.class, CONFIG_PREFIX) - .createObjectMapperResolver(serializers); + .createObjectMapperResolver(); return new ObjectMapperResolverFeature(omr); } diff --git a/bootique-jersey-jakarta/src/main/java/io/bootique/jersey/JerseyModule.java b/bootique-jersey-jakarta/src/main/java/io/bootique/jersey/JerseyModule.java index 85ec8b5..beac772 100644 --- a/bootique-jersey-jakarta/src/main/java/io/bootique/jersey/JerseyModule.java +++ b/bootique-jersey-jakarta/src/main/java/io/bootique/jersey/JerseyModule.java @@ -160,9 +160,7 @@ protected ResourceConfig createResourceConfig(Injector injector) { @Provides @Singleton - private MappedServlet provideJerseyServlet( - ConfigurationFactory configFactory, - ResourceConfig config) { - return configFactory.config(JerseyServletFactory.class, CONFIG_PREFIX).createJerseyServlet(config); + private MappedServlet provideJerseyServlet(ConfigurationFactory configFactory) { + return configFactory.config(JerseyServletFactory.class, CONFIG_PREFIX).createJerseyServlet(); } } diff --git a/bootique-jersey-jakarta/src/main/java/io/bootique/jersey/JerseyServletFactory.java b/bootique-jersey-jakarta/src/main/java/io/bootique/jersey/JerseyServletFactory.java index a8552f8..daf7a3c 100644 --- a/bootique-jersey-jakarta/src/main/java/io/bootique/jersey/JerseyServletFactory.java +++ b/bootique-jersey-jakarta/src/main/java/io/bootique/jersey/JerseyServletFactory.java @@ -27,6 +27,7 @@ import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; +import javax.inject.Inject; import java.util.Collections; import java.util.Set; @@ -38,8 +39,15 @@ public class JerseyServletFactory { private static final String DEFAULT_URL_PATTERN = "/*"; + private final ResourceConfig application; + protected String urlPattern; + @Inject + public JerseyServletFactory(ResourceConfig application) { + this.application = application; + } + /** * @param urlPattern a URL: pattern for the Jersey servlet. Default is "/*". */ @@ -57,7 +65,7 @@ public void setUrlPattern(String urlPattern) { * @param urlPattern a URL: pattern for the Jersey servlet unless it was already * set. * @return self. - * @deprecated since 2.0 as we don't need to initialize the urlPattern explicitly to be able to returna default. + * @deprecated since 2.0 as we don't need to initialize the urlPattern explicitly to be able to return a default. */ @Deprecated public JerseyServletFactory initUrlPatternIfNotSet(String urlPattern) { @@ -69,9 +77,9 @@ public JerseyServletFactory initUrlPatternIfNotSet(String urlPattern) { return this; } - public MappedServlet createJerseyServlet(ResourceConfig resourceConfig) { - ServletContainer servlet = new ServletContainer(resourceConfig); - Set urlPatterns = Collections.singleton(getUrlPattern(resourceConfig)); + public MappedServlet createJerseyServlet() { + ServletContainer servlet = new ServletContainer(application); + Set urlPatterns = Collections.singleton(getUrlPattern(application)); return new MappedServlet<>(servlet, urlPatterns, "jersey"); } @@ -102,7 +110,7 @@ protected String getUrlPatternFromAnnotation(ResourceConfig resourceConfig) { return null; } - protected String normalizeAppPath(String path) { + protected static String normalizeAppPath(String path) { // TODO: %-encode per ApplicationPath javadoc? StringBuilder normal = new StringBuilder(); diff --git a/bootique-jersey-jakarta/src/test/java/io/bootique/jersey/JerseyServletFactoryTest.java b/bootique-jersey-jakarta/src/test/java/io/bootique/jersey/JerseyServletFactoryTest.java index ee3ac9e..829b8db 100644 --- a/bootique-jersey-jakarta/src/test/java/io/bootique/jersey/JerseyServletFactoryTest.java +++ b/bootique-jersey-jakarta/src/test/java/io/bootique/jersey/JerseyServletFactoryTest.java @@ -18,7 +18,6 @@ */ package io.bootique.jersey; -import io.bootique.jersey.JerseyServletFactory; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -27,12 +26,10 @@ public class JerseyServletFactoryTest { @Test public void normalizeAppPath() { - - JerseyServletFactory f = new JerseyServletFactory(); - assertEquals("/*", f.normalizeAppPath("")); - assertEquals("/*", f.normalizeAppPath("/")); - assertEquals("/a/*", f.normalizeAppPath("a")); - assertEquals("/a/*", f.normalizeAppPath("/a")); - assertEquals("/a/*", f.normalizeAppPath("/a/")); + assertEquals("/*", JerseyServletFactory.normalizeAppPath("")); + assertEquals("/*", JerseyServletFactory.normalizeAppPath("/")); + assertEquals("/a/*", JerseyServletFactory.normalizeAppPath("a")); + assertEquals("/a/*", JerseyServletFactory.normalizeAppPath("/a")); + assertEquals("/a/*", JerseyServletFactory.normalizeAppPath("/a/")); } }