diff --git a/CHANGES b/CHANGES index ae16eeff5..acfd71d1b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +Platform 3.00 + +* HttpClient + + We now share a HttpClientBalancer across all BalancingHttpClients that share the same + statically configured service. + Platform 2.99 * Library Upgrades diff --git a/http-client/src/main/java/com/proofpoint/http/client/ConfiguredStaticHttpServiceBalancerProvider.java b/http-client/src/main/java/com/proofpoint/http/client/ConfiguredStaticHttpServiceBalancerProvider.java index e28595471..ee75484e6 100644 --- a/http-client/src/main/java/com/proofpoint/http/client/ConfiguredStaticHttpServiceBalancerProvider.java +++ b/http-client/src/main/java/com/proofpoint/http/client/ConfiguredStaticHttpServiceBalancerProvider.java @@ -29,6 +29,7 @@ import jakarta.inject.Provider; import java.util.Map; +import java.util.Objects; import static java.lang.String.format; import static java.util.Objects.requireNonNull; @@ -82,4 +83,23 @@ public HttpServiceBalancer get() balancer.updateHttpUris(injector.getInstance(uriConfigKey).getUris()); return balancer; } + + @Override + public boolean equals(Object o) + { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConfiguredStaticHttpServiceBalancerProvider that = (ConfiguredStaticHttpServiceBalancerProvider) o; + return Objects.equals(type, that.type) && Objects.equals(balancerConfigKey, that.balancerConfigKey) && Objects.equals(uriConfigKey, that.uriConfigKey); + } + + @Override + public int hashCode() + { + return Objects.hash(type, balancerConfigKey, uriConfigKey); + } } diff --git a/http-client/src/main/java/com/proofpoint/http/client/HttpClientBinder.java b/http-client/src/main/java/com/proofpoint/http/client/HttpClientBinder.java index aedab0caa..a3cc3549c 100644 --- a/http-client/src/main/java/com/proofpoint/http/client/HttpClientBinder.java +++ b/http-client/src/main/java/com/proofpoint/http/client/HttpClientBinder.java @@ -305,14 +305,19 @@ public BalancingHttpClientBindingBuilder bindBalancingHttpClient(String name, An { requireNonNull(name, "name is null"); requireNonNull(annotation, "annotation is null"); + requireNonNull(serviceName, "serviceName is null"); + + ServiceType serviceType = ServiceTypes.serviceType(serviceName); + bindConfig(binder).bind(HttpServiceBalancerConfig.class).annotatedWith(serviceType).prefixedWith("service-client." + serviceName); + bindConfig(binder).bind(HttpServiceBalancerUriConfig.class).annotatedWith(serviceType).prefixedWith("service-client." + serviceName); + binder.bind(HttpServiceBalancer.class).annotatedWith(serviceType) + .toProvider(new ConfiguredStaticHttpServiceBalancerProvider(serviceName, + Key.get(HttpServiceBalancerConfig.class, serviceType), + Key.get(HttpServiceBalancerUriConfig.class, serviceType))); - bindConfig(binder).bind(HttpServiceBalancerConfig.class).annotatedWith(annotation).prefixedWith("service-client." + serviceName); - bindConfig(binder).bind(HttpServiceBalancerUriConfig.class).annotatedWith(annotation).prefixedWith("service-client." + serviceName); PrivateBinder privateBinder = binder.newPrivateBinder(); privateBinder.bind(HttpServiceBalancer.class).annotatedWith(ForBalancingHttpClient.class) - .toProvider(new ConfiguredStaticHttpServiceBalancerProvider(serviceName, - Key.get(HttpServiceBalancerConfig.class, annotation), - Key.get(HttpServiceBalancerUriConfig.class, annotation))); + .to(Key.get(HttpServiceBalancer.class, serviceType)); return createBalancingHttpClientBindingBuilder(privateBinder, name, annotation, serviceName); } @@ -334,13 +339,17 @@ public BalancingHttpClientBindingBuilder bindBalancingHttpClient(String name, Cl requireNonNull(name, "name is null"); requireNonNull(annotation, "annotation is null"); - bindConfig(binder).bind(HttpServiceBalancerConfig.class).annotatedWith(annotation).prefixedWith("service-client." + serviceName); - bindConfig(binder).bind(HttpServiceBalancerUriConfig.class).annotatedWith(annotation).prefixedWith("service-client." + serviceName); + ServiceType serviceType = ServiceTypes.serviceType(serviceName); + bindConfig(binder).bind(HttpServiceBalancerConfig.class).annotatedWith(serviceType).prefixedWith("service-client." + serviceName); + bindConfig(binder).bind(HttpServiceBalancerUriConfig.class).annotatedWith(serviceType).prefixedWith("service-client." + serviceName); + binder.bind(HttpServiceBalancer.class).annotatedWith(serviceType) + .toProvider(new ConfiguredStaticHttpServiceBalancerProvider(serviceName, + Key.get(HttpServiceBalancerConfig.class, serviceType), + Key.get(HttpServiceBalancerUriConfig.class, serviceType))); + PrivateBinder privateBinder = binder.newPrivateBinder(); privateBinder.bind(HttpServiceBalancer.class).annotatedWith(ForBalancingHttpClient.class) - .toProvider(new ConfiguredStaticHttpServiceBalancerProvider(serviceName, - Key.get(HttpServiceBalancerConfig.class, annotation), - Key.get(HttpServiceBalancerUriConfig.class, annotation))); + .to(Key.get(HttpServiceBalancer.class, serviceType)); return createBalancingHttpClientBindingBuilder(privateBinder, name, annotation); } @@ -436,7 +445,7 @@ private BalancingHttpClientBindingBuilder createBalancingHttpClientBindingBuilde reportBinder(binder).export(HttpClient.class).annotatedWith(annotation).withNamePrefix("HttpClient." + serviceName); newExporter(binder).export(HttpClient.class).annotatedWith(annotation).as(new ObjectNameBuilder(HttpClient.class.getPackage().getName()) .withProperty("type", "HttpClient") - .withProperty("name", serviceName) + .withProperty("name", name) .build() ); binder.bind(ScheduledExecutorService.class).annotatedWith(ForBalancingHttpClient.class).toProvider(RetryExecutorProvider.class); diff --git a/http-client/src/test/java/com/proofpoint/http/client/TestHttpClientBinder.java b/http-client/src/test/java/com/proofpoint/http/client/TestHttpClientBinder.java index 9fb6e6d9c..c38270440 100644 --- a/http-client/src/test/java/com/proofpoint/http/client/TestHttpClientBinder.java +++ b/http-client/src/test/java/com/proofpoint/http/client/TestHttpClientBinder.java @@ -19,6 +19,7 @@ import com.google.inject.Key; import com.google.inject.PrivateBinder; import com.proofpoint.bootstrap.LifeCycleManager; +import com.proofpoint.http.client.balancing.HttpServiceBalancer; import com.proofpoint.http.client.jetty.JettyHttpClient; import com.proofpoint.reporting.ReportingModule; import jakarta.inject.Inject; @@ -202,6 +203,7 @@ public void testBindBalancingHttpClientConfigured() .initialize(); assertNotNull(injector.getInstance(Key.get(HttpClient.class, serviceType("foo")))); + assertNotNull(injector.getInstance(Key.get(HttpServiceBalancer.class, serviceType("foo")))); } @Test @@ -233,6 +235,25 @@ public void testBindBalancingHttpClientConfiguredUris() assertNotNull(injector.getInstance(Key.get(HttpClient.class, FooClient.class))); } + @Test + public void testBindBalancingHttpClientConfiguredQualifier() + throws Exception + { + Injector injector = bootstrapTest() + .withModules( + binder -> httpClientBinder(binder).bindBalancingHttpClient("foo", FooClient.class, "testservice"), + binder -> httpClientBinder(binder).bindBalancingHttpClient("foo", BarClient.class, "testservice"), + new ReportingModule(), + new TestingMBeanModule()) + .setRequiredConfigurationProperty("service-client.testservice.uri", "http://nonexistent.nonexistent") + .initialize(); + + assertNotNull(injector.getInstance(Key.get(HttpClient.class, FooClient.class))); + assertNotNull(injector.getInstance(Key.get(HttpClient.class, BarClient.class))); + assertNotNull(injector.getInstance(Key.get(HttpServiceBalancer.class, serviceType("testservice")))); + + } + @Test public void testBindBalancingHttpClientUris() throws Exception @@ -254,12 +275,15 @@ public void testBindBalancingHttpClientConfigParameterizedAnnotation() Injector injector = bootstrapTest() .withModules( binder -> httpClientBinder(binder).bindBalancingHttpClient("foo", named("bar"), "baz"), + binder -> httpClientBinder(binder).bindBalancingHttpClient("second", named("quux"), "baz"), new ReportingModule(), new TestingMBeanModule()) .setRequiredConfigurationProperty("service-client.baz.uri", "http://nonexistent.nonexistent") .initialize(); assertNotNull(injector.getInstance(Key.get(HttpClient.class, named("bar")))); + assertNotNull(injector.getInstance(Key.get(HttpClient.class, named("quux")))); + assertNotNull(injector.getInstance(Key.get(HttpServiceBalancer.class, serviceType("baz")))); } @Test