se.fortnox.reactivewizard.client.RestClientFactory Maven / Gradle / Ivy
package se.fortnox.reactivewizard.client;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Scopes;
import com.google.inject.multibindings.Multibinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.fortnox.reactivewizard.binding.AutoBindModule;
import se.fortnox.reactivewizard.binding.scanners.HttpConfigClassScanner;
import se.fortnox.reactivewizard.binding.scanners.JaxRsClassScanner;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import static java.lang.String.format;
public class RestClientFactory implements AutoBindModule {
private static final Logger LOG = LoggerFactory.getLogger(RestClientFactory.class);
private final JaxRsClassScanner jaxRsClassScanner;
private final HttpConfigClassScanner httpConfigClassScanner;
@Inject
public RestClientFactory(JaxRsClassScanner jaxRsClassScanner, HttpConfigClassScanner httpConfigClassScanner) {
this.jaxRsClassScanner = jaxRsClassScanner;
this.httpConfigClassScanner = httpConfigClassScanner;
}
private Provider provider(Class iface,
Provider httpClientProvider, Provider extends HttpClientConfig> httpClientConfigProvider) {
return () -> {
HttpClientConfig httpClientConfig = httpClientConfigProvider.get();
//Create client based on config and create proxy
T httpProxy = httpClientProvider.get().createClient(httpClientConfig).create(iface);
LOG.debug("Created {} for {} with custom httpClient: {}", Proxy.getInvocationHandler(httpProxy), iface.getName(), httpClientConfig);
return httpProxy;
};
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public void configure(Binder binder) {
Multibinder.newSetBinder(binder, PreRequestHook.class);
Multibinder.newSetBinder(binder, RequestParameterSerializer.class);
Provider httpClientProvider = binder.getProvider(HttpClientProvider.class);
Map> httpClientConfigByResource = new HashMap<>();
httpConfigClassScanner
.getClasses()
.forEach(configClass -> {
if (configClass.isAnnotationPresent(UseInResource.class)) {
for (Class resource : configClass.getAnnotation(UseInResource.class).value()) {
if (!resource.isInterface()) {
throw new IllegalArgumentException(format(
"class %s pointed out in UseInResource annotation must be an interface",
resource.getCanonicalName()));
}
httpClientConfigByResource.put(resource, configClass);
}
}
});
jaxRsClassScanner.getClasses().forEach(cls -> {
Class httpClientConfigClass = httpClientConfigByResource.getOrDefault(cls, HttpClientConfig.class);
Provider extends HttpClientConfig> httpClientConfigProvider = binder.getProvider(httpClientConfigClass);
Provider> jaxRsClientProvider = provider(cls, httpClientProvider, httpClientConfigProvider);
binder.bind((Class)cls)
.toProvider(jaxRsClientProvider)
.in(Scopes.SINGLETON);
});
}
@Override
public Integer getPrio() {
// Low prio to allow for local implementations to bind to the interface
return 0;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy