package netflix.karyon.transport.http;
import com.google.inject.Key;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.multibindings.MapBinder;
import io.reactivex.netty.protocol.http.server.HttpServer;
import io.reactivex.netty.protocol.http.server.RequestHandler;
import io.reactivex.netty.server.RxServer;
import netflix.karyon.transport.AbstractServerModule;
import netflix.karyon.transport.http.KaryonHttpModule.HttpServerConfigBuilder;
import static netflix.karyon.utils.TypeUtils.keyFor;
/**
* @author Tomasz Bak
*/
public abstract class KaryonHttpModule<I, O> extends AbstractServerModule<I, O, HttpServerConfigBuilder> {
protected final Key<RequestHandler<I, O>> routerKey;
protected final Key<HttpServer<I, O>> httpServerKey;
protected final Key<GovernatorHttpInterceptorSupport<I, O>> interceptorSupportKey;
private final GovernatorHttpInterceptorSupport<I, O> interceptorSupportInstance = new GovernatorHttpInterceptorSupport<I, O>();
protected KaryonHttpModule(String moduleName, Class<I> iType, Class<O> oType) {
super(moduleName, iType, oType);
routerKey = keyFor(RequestHandler.class, iType, oType, nameAnnotation);
interceptorSupportKey = keyFor(GovernatorHttpInterceptorSupport.class, iType, oType, nameAnnotation);
httpServerKey = keyFor(HttpServer.class, iType, oType, nameAnnotation);
}
@Override
protected void configure() {
configureServer();
bind(serverConfigKey).toInstance(serverConfigBuilder.build());
bind(interceptorSupportKey).toInstance(interceptorSupportInstance);
MapBinder.newMapBinder(binder(), String.class, RxServer.class).addBinding(nameAnnotation.value()).toProvider(
new HttpRxServerProvider<I, O, HttpServer<I, O>>(nameAnnotation.value(), iType, oType)
).asEagerSingleton();
}
@Override
protected HttpServerConfigBuilder newServerConfigBuilder() {
return new HttpServerConfigBuilder();
}
protected LinkedBindingBuilder<RequestHandler<I, O>> bindRouter() {
return bind(routerKey);
}
protected GovernatorHttpInterceptorSupport<I, O> interceptorSupport() {
return interceptorSupportInstance;
}
public static class HttpServerConfig extends AbstractServerModule.ServerConfig {
private final int threadPoolSize;
public HttpServerConfig(int port) {
super(port);
this.threadPoolSize = -1;
}
public HttpServerConfig(int port, int threadPoolSize) {
super(port);
this.threadPoolSize = threadPoolSize;
}
public int getThreadPoolSize() {
return threadPoolSize;
}
public boolean requiresThreadPool() {
return threadPoolSize > 0;
}
}
public static class HttpServerConfigBuilder
extends AbstractServerModule.ServerConfigBuilder<HttpServerConfigBuilder, HttpServerConfig> {
protected int poolSize = -1;
public HttpServerConfigBuilder threadPoolSize(int poolSize) {
this.poolSize = poolSize;
return this;
}
@Override
public HttpServerConfig build() {
return new HttpServerConfig(port, poolSize);
}
}
}