Skip to content

Commit

Permalink
Compactede ws/hjttp gateways
Browse files Browse the repository at this point in the history
  • Loading branch information
artem-v committed Sep 29, 2024
1 parent 57acbf9 commit 83c783b
Show file tree
Hide file tree
Showing 15 changed files with 262 additions and 269 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,148 +1,67 @@
package io.scalecube.services.gateway.http;

import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.cors.CorsConfig;
import io.netty.handler.codec.http.cors.CorsConfigBuilder;
import io.netty.handler.codec.http.cors.CorsHandler;
import io.scalecube.services.Address;
import io.scalecube.services.exceptions.DefaultErrorMapper;
import io.scalecube.services.exceptions.ServiceProviderErrorMapper;
import io.scalecube.services.gateway.Gateway;
import io.scalecube.services.gateway.GatewayOptions;
import io.scalecube.services.gateway.GatewayTemplate;
import java.net.InetSocketAddress;
import java.util.Map.Entry;
import java.util.StringJoiner;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.DisposableServer;
import reactor.netty.http.server.HttpServer;
import reactor.netty.resources.LoopResources;

public class HttpGateway extends GatewayTemplate {
public class HttpGateway implements Gateway {

private final GatewayOptions options;
private final ServiceProviderErrorMapper errorMapper;
private final boolean corsEnabled;
private final CorsConfigBuilder corsConfigBuilder;

private DisposableServer server;
private LoopResources loopResources;

private boolean corsEnabled = false;
private CorsConfigBuilder corsConfigBuilder =
CorsConfigBuilder.forAnyOrigin()
.allowNullOrigin()
.maxAge(3600)
.allowedRequestMethods(HttpMethod.POST);

public HttpGateway(GatewayOptions options) {
this(options, DefaultErrorMapper.INSTANCE);
}

public HttpGateway(GatewayOptions options, ServiceProviderErrorMapper errorMapper) {
super(options);
this.errorMapper = errorMapper;
private HttpGateway(Builder builder) {
this.options = builder.options;
this.errorMapper = builder.errorMapper;
this.corsEnabled = builder.corsEnabled;
this.corsConfigBuilder = builder.corsConfigBuilder;
}

private HttpGateway(HttpGateway other) {
super(other.options);
this.server = other.server;
this.loopResources = other.loopResources;
this.corsEnabled = other.corsEnabled;
this.corsConfigBuilder = copy(other.corsConfigBuilder);
this.errorMapper = other.errorMapper;
public HttpGateway(UnaryOperator<Builder> operator) {
this(operator.apply(new Builder()));
}

/**
* CORS enable.
*
* @param corsEnabled if set to true.
* @return HttpGateway with CORS settings.
*/
public HttpGateway corsEnabled(boolean corsEnabled) {
HttpGateway g = new HttpGateway(this);
g.corsEnabled = corsEnabled;
return g;
}

/**
* Configure CORS with options.
*
* @param op for CORS.
* @return HttpGateway with CORS settings.
*/
public HttpGateway corsConfig(UnaryOperator<CorsConfigBuilder> op) {
HttpGateway g = new HttpGateway(this);
g.corsConfigBuilder = copy(op.apply(g.corsConfigBuilder));
return g;
}

private CorsConfigBuilder copy(CorsConfigBuilder other) {
CorsConfig config = other.build();
CorsConfigBuilder corsConfigBuilder;
if (config.isAnyOriginSupported()) {
corsConfigBuilder = CorsConfigBuilder.forAnyOrigin();
} else {
corsConfigBuilder = CorsConfigBuilder.forOrigins(config.origins().toArray(new String[0]));
}

if (!config.isCorsSupportEnabled()) {
corsConfigBuilder.disable();
}

corsConfigBuilder
.exposeHeaders(config.exposedHeaders().toArray(new String[0]))
.allowedRequestHeaders(config.allowedRequestHeaders().toArray(new String[0]))
.allowedRequestMethods(config.allowedRequestMethods().toArray(new HttpMethod[0]))
.maxAge(config.maxAge());

for (Entry<String, String> header : config.preflightResponseHeaders()) {
corsConfigBuilder.preflightResponseHeader(header.getKey(), header.getValue());
}

if (config.isShortCircuit()) {
corsConfigBuilder.shortCircuit();
}

if (config.isNullOriginAllowed()) {
corsConfigBuilder.allowNullOrigin();
}

if (config.isCredentialsAllowed()) {
corsConfigBuilder.allowCredentials();
}

return corsConfigBuilder;
@Override
public String id() {
return options.id();
}

@Override
public Mono<Gateway> start() {
return Mono.defer(
() -> {
HttpGatewayAcceptor acceptor = new HttpGatewayAcceptor(options.call(), errorMapper);
HttpGatewayAcceptor gatewayAcceptor =
new HttpGatewayAcceptor(options.call(), errorMapper);

loopResources = LoopResources.create("http-gateway");
loopResources = LoopResources.create(options.id() + ":" + options.port());

return prepareHttpServer(loopResources, options.port())
.handle(acceptor)
.handle(gatewayAcceptor)
.bind()
.doOnSuccess(server -> this.server = server)
.thenReturn(this);
});
}

@Override
public Address address() {
InetSocketAddress address = (InetSocketAddress) server.address();
return Address.create(address.getHostString(), address.getPort());
}

@Override
public Mono<Void> stop() {
return Flux.concatDelayError(shutdownServer(server), shutdownLoopResources(loopResources))
.then();
}

protected HttpServer prepareHttpServer(LoopResources loopResources, int port) {
private HttpServer prepareHttpServer(LoopResources loopResources, int port) {
HttpServer httpServer = HttpServer.create();

if (loopResources != null) {
Expand All @@ -159,14 +78,101 @@ protected HttpServer prepareHttpServer(LoopResources loopResources, int port) {
});
}

@Override
public Address address() {
InetSocketAddress address = (InetSocketAddress) server.address();
return Address.create(address.getHostString(), address.getPort());
}

@Override
public Mono<Void> stop() {
return Flux.concatDelayError(shutdownServer(server), shutdownLoopResources(loopResources))
.then();
}

private Mono<Void> shutdownServer(DisposableServer server) {
return Mono.defer(
() -> {
if (server != null) {
server.dispose();
return server.onDispose();
}
return Mono.empty();
});
}

private Mono<Void> shutdownLoopResources(LoopResources loopResources) {
return loopResources != null ? loopResources.disposeLater() : Mono.empty();
}

@Override
public String toString() {
return new StringJoiner(", ", HttpGateway.class.getSimpleName() + "[", "]")
.add("server=" + server)
.add("loopResources=" + loopResources)
.add("options=" + options)
.add("errorMapper=" + errorMapper)
.add("corsEnabled=" + corsEnabled)
.add("corsConfigBuilder=" + corsConfigBuilder)
.add("options=" + options)
.add("server=" + server)
.add("loopResources=" + loopResources)
.toString();
}

public static class Builder {

private GatewayOptions options;
private ServiceProviderErrorMapper errorMapper = DefaultErrorMapper.INSTANCE;
private boolean corsEnabled = false;
private CorsConfigBuilder corsConfigBuilder =
CorsConfigBuilder.forAnyOrigin()
.allowNullOrigin()
.maxAge(3600)
.allowedRequestMethods(HttpMethod.POST);

public Builder() {}

public GatewayOptions options() {
return options;
}

public Builder options(GatewayOptions options) {
this.options = options;
return this;
}

public ServiceProviderErrorMapper errorMapper() {
return errorMapper;
}

public Builder errorMapper(ServiceProviderErrorMapper errorMapper) {
this.errorMapper = errorMapper;
return this;
}

public boolean corsEnabled() {
return corsEnabled;
}

public Builder corsEnabled(boolean corsEnabled) {
this.corsEnabled = corsEnabled;
return this;
}

public CorsConfigBuilder corsConfigBuilder() {
return corsConfigBuilder;
}

public Builder corsConfigBuilder(CorsConfigBuilder corsConfigBuilder) {
this.corsConfigBuilder = corsConfigBuilder;
return this;
}

public Builder corsConfigBuilder(Consumer<CorsConfigBuilder> consumer) {
consumer.accept(this.corsConfigBuilder);
return this;
}

public HttpGateway build() {
return new HttpGateway(this);
}
}
}
Loading

0 comments on commit 83c783b

Please sign in to comment.