package io.undertow.server.handlers.proxy.mod_cluster;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import io.undertow.client.UndertowClient;
import io.undertow.server.HttpHandler;
import io.undertow.server.handlers.ResponseCodeHandler;
import io.undertow.server.handlers.proxy.ProxyHandler;
import io.undertow.server.handlers.proxy.RouteParsingStrategy;
import org.xnio.OptionMap;
import org.xnio.XnioWorker;
import org.xnio.ssl.XnioSsl;
public class ModCluster {
private static final HttpHandler NEXT_HANDLER = ResponseCodeHandler.HANDLE_404;
private final long healthCheckInterval;
private final long removeBrokenNodes;
private final NodeHealthChecker healthChecker;
private final int maxConnections;
private final int cacheConnections;
private final int requestQueueSize;
private final boolean queueNewRequests;
private final int maxRequestTime;
private final long ttl;
private final boolean useAlias;
private final XnioWorker xnioWorker;
private final ModClusterContainer container;
private final int maxRetries;
private final boolean deterministicFailover;
private final RouteParsingStrategy routeParsingStrategy;
private final String rankedAffinityDelimiter;
private final boolean reuseXForwarded;
private final String serverID = UUID.randomUUID().toString();
ModCluster(Builder builder) {
this.xnioWorker = builder.xnioWorker;
this.maxConnections = builder.maxConnections;
this.cacheConnections = builder.cacheConnections;
this.requestQueueSize = builder.requestQueueSize;
this.queueNewRequests = builder.queueNewRequests;
this.healthCheckInterval = builder.healthCheckInterval;
this.removeBrokenNodes = builder.removeBrokenNodes;
this.deterministicFailover = builder.deterministicFailover;
this.routeParsingStrategy = builder.routeParsingStrategy;
this.rankedAffinityDelimiter = builder.rankedAffinityDelimiter;
this.healthChecker = builder.healthChecker;
this.maxRequestTime = builder.maxRequestTime;
this.ttl = builder.ttl;
this.useAlias = builder.useAlias;
this.maxRetries = builder.maxRetries;
this.reuseXForwarded = builder.reuseXForwarded;
this.container = new ModClusterContainer(this, builder.xnioSsl, builder.client, builder.clientOptions);
}
protected String getServerID() {
return serverID;
}
protected ModClusterContainer getContainer() {
return container;
}
public ModClusterController getController() {
return container;
}
public int getMaxConnections() {
return maxConnections;
}
public int getCacheConnections() {
return cacheConnections;
}
public int getRequestQueueSize() {
return requestQueueSize;
}
public boolean isQueueNewRequests() {
return queueNewRequests;
}
public long getHealthCheckInterval() {
return healthCheckInterval;
}
public long getRemoveBrokenNodes() {
return removeBrokenNodes;
}
public NodeHealthChecker getHealthChecker() {
return healthChecker;
}
public long getTtl() {
return ttl;
}
public boolean isUseAlias() {
return useAlias;
}
public boolean isDeterministicFailover() {
return deterministicFailover;
}
public RouteParsingStrategy routeParsingStrategy() {
return this.routeParsingStrategy;
}
public String rankedAffinityDelimiter() {
return this.rankedAffinityDelimiter;
}
@Deprecated
public HttpHandler getProxyHandler() {
return createProxyHandler();
}
public HttpHandler createProxyHandler() {
return ProxyHandler.builder()
.setProxyClient(container.getProxyClient())
.setMaxRequestTime(maxRequestTime)
.setMaxConnectionRetries(maxRetries)
.setReuseXForwarded(reuseXForwarded)
.build();
}
public HttpHandler createProxyHandler(HttpHandler next) {
return ProxyHandler.builder()
.setProxyClient(container.getProxyClient())
.setNext(next)
.setMaxRequestTime(maxRequestTime)
.setMaxConnectionRetries(maxRetries)
.setReuseXForwarded(reuseXForwarded)
.build();
}
public synchronized void start() {
}
public synchronized void advertise(MCMPConfig config) throws IOException {
final MCMPConfig.AdvertiseConfig advertiseConfig = config.getAdvertiseConfig();
if (advertiseConfig == null) {
throw new IllegalArgumentException("advertise not enabled");
}
MCMPAdvertiseTask.advertise(container, advertiseConfig, xnioWorker);
}
public synchronized void stop() {
}
public static Builder builder(final XnioWorker worker) {
return builder(worker, UndertowClient.getInstance(), null);
}
public static Builder builder(final XnioWorker worker, final UndertowClient client) {
return builder(worker, client, null);
}
public static Builder builder(final XnioWorker worker, final UndertowClient client, final XnioSsl xnioSsl) {
return new Builder(worker, client, xnioSsl);
}
public static class Builder {
private final XnioSsl xnioSsl;
private final UndertowClient client;
private final XnioWorker xnioWorker;
private int maxConnections = 16;
private int cacheConnections = 1;
private int requestQueueSize = 0;
private boolean queueNewRequests = false;
private int maxRequestTime = -1;
private long ttl = TimeUnit.SECONDS.toMillis(60);
private boolean useAlias = false;
private NodeHealthChecker healthChecker = NodeHealthChecker.NO_CHECK;
private long healthCheckInterval = TimeUnit.SECONDS.toMillis(10);
private long removeBrokenNodes = TimeUnit.MINUTES.toMillis(1);
private OptionMap clientOptions = OptionMap.EMPTY;
private int maxRetries;
private boolean deterministicFailover = false;
private RouteParsingStrategy routeParsingStrategy = RouteParsingStrategy.SINGLE;
private String rankedAffinityDelimiter = ".";
private boolean reuseXForwarded;
private Builder(XnioWorker xnioWorker, UndertowClient client, XnioSsl xnioSsl) {
this.xnioSsl = xnioSsl;
this.client = client;
this.xnioWorker = xnioWorker;
}
public ModCluster build() {
return new ModCluster(this);
}
public Builder setMaxRequestTime(int maxRequestTime) {
this.maxRequestTime = maxRequestTime;
return this;
}
public Builder setHealthCheckInterval(long healthCheckInterval) {
this.healthCheckInterval = healthCheckInterval;
return this;
}
public Builder setRemoveBrokenNodes(long removeBrokenNodes) {
this.removeBrokenNodes = removeBrokenNodes;
return this;
}
public Builder setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
return this;
}
public Builder setCacheConnections(int cacheConnections) {
this.cacheConnections = cacheConnections;
return this;
}
public Builder setRequestQueueSize(int requestQueueSize) {
this.requestQueueSize = requestQueueSize;
return this;
}
public Builder setQueueNewRequests(boolean queueNewRequests) {
this.queueNewRequests = queueNewRequests;
return this;
}
public Builder setHealthChecker(NodeHealthChecker healthChecker) {
this.healthChecker = healthChecker;
return this;
}
public Builder setUseAlias(boolean useAlias) {
this.useAlias = useAlias;
return this;
}
public Builder setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
return this;
}
public Builder setDeterministicFailover(boolean deterministicFailover) {
this.deterministicFailover = deterministicFailover;
return this;
}
public Builder setRouteParsingStrategy(RouteParsingStrategy routeParsingStrategy) {
this.routeParsingStrategy = routeParsingStrategy;
return this;
}
public Builder setRankedAffinityDelimiter(String rankedAffinityDelimiter) {
this.rankedAffinityDelimiter = rankedAffinityDelimiter;
return this;
}
public Builder setTtl(long ttl) {
this.ttl = ttl;
return this;
}
public Builder setClientOptions(OptionMap clientOptions) {
this.clientOptions = clientOptions;
return this;
}
public Builder setReuseXForwarded(boolean reuseXForwarded) {
this.reuseXForwarded = reuseXForwarded;
return this;
}
}
}