Skip to content

Commit

Permalink
Share HttpClientBalancers for the same configured service
Browse files Browse the repository at this point in the history
  • Loading branch information
johngmyers committed Sep 15, 2023
1 parent 1face02 commit 089937c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 11 deletions.
7 changes: 7 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 089937c

Please sign in to comment.