io.vrap.rmf.base.client.http.HandlerStack Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rmf-java-base Show documentation
Show all versions of rmf-java-base Show documentation
The e-commerce SDK from commercetools Composable Commerce for Java
package io.vrap.rmf.base.client.http;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import io.vrap.rmf.base.client.ApiHttpRequest;
import io.vrap.rmf.base.client.ApiHttpResponse;
import io.vrap.rmf.base.client.AutoCloseableService;
import io.vrap.rmf.base.client.VrapHttpClient;
/**
* The HandlerStack is used to execute the middlewares in order and transfer the request using the specified {@link HttpHandler}
*/
public class HandlerStack extends AutoCloseableService implements VrapHttpClient {
public String CLOSED_MESSAGE = "Handler is already closed.";
private final HttpHandler handler;
private final List middlewares;
private Function>> cached;
private HandlerStack(final HttpHandler handler, final List middlewares) {
this.handler = handler;
this.middlewares = middlewares;
this.cached = null;
}
public static HandlerStack create(final HttpHandler handler, final List middlewares) {
return new HandlerStack(handler, middlewares);
}
public static HandlerStack create(final HttpHandler handler) {
return create(handler, new ArrayList<>());
}
public void addMiddleware(final Middleware middleware) {
this.middlewares.add(middleware);
this.cached = null;
}
public void addMiddlewares(final List middlewares) {
this.middlewares.addAll(middlewares);
this.cached = null;
}
public void addMiddlewares(final Middleware... middlewares) {
this.middlewares.addAll(Arrays.asList(middlewares));
this.cached = null;
}
Function>> resolve() {
if (cached == null) {
List stack = new ArrayList<>(middlewares);
Function>> prev = handler::execute;
for (Middleware middleware : stack) {
Function>> finalPrev = prev;
prev = (request) -> middleware.invoke(request, finalPrev);
}
cached = prev;
}
return cached;
}
@Override
public CompletableFuture> execute(ApiHttpRequest request) {
rejectExecutionIfClosed(CLOSED_MESSAGE);
return invoke(request);
}
public CompletableFuture> invoke(final ApiHttpRequest request) {
final Function>> handler = resolve();
return handler.apply(request);
}
@Override
protected void internalClose() {
handler.close();
middlewares.forEach(middleware -> {
if (middleware instanceof AutoCloseable) {
closeQuietly((AutoCloseable) middleware);
}
});
}
}