smallrye-mutiny-vertx-bindings icon indicating copy to clipboard operation
smallrye-mutiny-vertx-bindings copied to clipboard

Generate binding from io.vertx.httproxy.ProxyInterceptor interface ?

Open lucaspouzac opened this issue 2 years ago • 3 comments

Is it possible to generate the following interface from the io.vertx.httpproxy.ProxyInterceptor interface? Currently, it is a class that is generated and it is not easy to use ? Or another idea ?

package io.vertx.mutiny.httpproxy;

import io.vertx.codegen.annotations.VertxGen;
import io.smallrye.mutiny.Uni;

/**
 * A {@link HttpProxy} interceptor.
 */
@io.smallrye.mutiny.vertx.MutinyGen(io.vertx.httpproxy.ProxyInterceptor.class)
public interface ProxyInterceptor {

  /**
   * Handle the proxy request at the stage of this interceptor.
   *
   * @param context the proxy context
   * @return when the request has actually been sent to the origin
   */
  default Uni<io.vertx.mutiny.httpproxy.ProxyResponse> handleProxyRequest(io.vertx.mutiny.httpproxy.ProxyContext context) {
    return context.sendRequest();
  }

  /**
   * Handle the proxy response at the stage of this interceptor.
   *
   * @param context the proxy context
   * @return when the response has actually been sent to the user-agent
   */
  default Uni<Void> handleProxyResponse(io.vertx.mutiny.httpproxy.ProxyContext context) {
    return context.sendResponse();
  }
}

Example of expected use.

public class TestInterceptor implements io.vertx.mutiny.httpproxy.ProxyInterceptor {

  public Uni<io.vertx.mutiny.httpproxy.ProxyResponse> handleProxyRequest(io.vertx.mutiny.httpproxy.ProxyContext context) {
    System.out.println("handleProxyRequest");
    return context.sendRequest();
  }

  public Uni<Void> handleProxyResponse(io.vertx.mutiny.httpproxy.ProxyContext context) {
    System.out.println("handleProxyResponse");
    return context.sendResponse();
  }

}

io.vertx.mutiny.core.Vertx vertx = ...;
io.vertx.mutiny.httpproxy.HttpProxy httpProxy = io.vertx.mutiny.httpproxy.HttpProxy.reverseProxy(vertx.createHttpClient());
httpProxy.addInterceptor(new TestInterceptor());

lucaspouzac avatar Feb 23 '23 09:02 lucaspouzac

Vertx 4.4.0 has been released with the fix. I tested the generation and an interface was correctly generated.

@io.smallrye.mutiny.vertx.MutinyGen(io.vertx.httpproxy.ProxyInterceptor.class)
public interface ProxyInterceptor {

  static final io.smallrye.mutiny.vertx.TypeArg<io.vertx.mutiny.httpproxy.ProxyResponse> TYPE_ARG_0 = new TypeArg<io.vertx.mutiny.httpproxy.ProxyResponse>(o1 -> io.vertx.mutiny.httpproxy.ProxyResponse.newInstance((io.vertx.httpproxy.ProxyResponse)o1), o1 -> o1.getDelegate());
  io.vertx.httpproxy.ProxyInterceptor getDelegate();

  /**
   * @param context the proxy context
   * @return when the request has actually been sent to the origin
   */
  public io.smallrye.mutiny.Uni<io.vertx.mutiny.httpproxy.ProxyResponse> handleProxyRequest(io.vertx.mutiny.httpproxy.ProxyContext context);

  /**
   * @param context the proxy context
   * @return when the response has actually been sent to the user-agent
   */
  public io.smallrye.mutiny.Uni<Void> handleProxyResponse(io.vertx.mutiny.httpproxy.ProxyContext context);

  public static  ProxyInterceptor newInstance(io.vertx.httpproxy.ProxyInterceptor arg) {
    return arg != null ? new ProxyInterceptorImpl(arg) : null;
  }

}

class ProxyInterceptorImpl implements ProxyInterceptor {
   ...
}

However, a getDelegate() method is generated. I had trouble understanding how one can implement this interface? Below is an example implementation that I would like to do.

import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.httpproxy.ProxyContext;
import io.vertx.mutiny.httpproxy.ProxyInterceptor;
import io.vertx.mutiny.httpproxy.ProxyResponse;
import jakarta.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.rest.client.inject.RestClient;

@ApplicationScoped
public class TestRequestInterceptor implements ProxyInterceptor {

    @RestClient
    private Service1 service1;

    @RestClient
    private Service2 service2;

    @Override
    public final Uni<ProxyResponse> handleProxyRequest(ProxyContext context) {
        Uni<ProxyResponse> result = null;

        if (context.request().headers().contains("header-name")) {
            return service1.get()
                    .onItemOrFailure().transformToUni((resp, throwable) -> {
                        // process response
                        return context.sendRequest();
                    });
        } else {
            return service2.get()
                    .onItemOrFailure().transformToUni((resp, throwable) -> {
                        // process response
                        return context.sendRequest();
                    });
        }
    }

    public Uni<Void> handleProxyResponse(ProxyContext context) {
        return context.sendResponse();
    }
}
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.core.http.HttpClient;
import io.vertx.mutiny.ext.web.Router;
import io.vertx.mutiny.ext.web.proxy.handler.ProxyHandler;
import io.vertx.mutiny.httpproxy.HttpProxy;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;

@ApplicationScoped
public class TestHttpProxy {
    private final HttpProxy httpProxy;
    public TestHttpProxy(Vertx vertx, TestRequestInterceptor testRequestInterceptor) {
        HttpClient proxyClient = vertx.createHttpClient();
        httpProxy = HttpProxy.reverseProxy(proxyClient);
        httpProxy.origin(7000, "localhost");
        httpProxy.addInterceptor(testRequestInterceptor);
    }

    public void init(@Observes Router router) {
        router.routeWithRegex("^.*$").handler(ProxyHandler.create(httpProxy));
    }
}

lucaspouzac avatar Mar 02 '23 09:03 lucaspouzac

Mutiny APIs are implemented directly on top of the "Bare" API. The getDelegate provides a way to get the "bare" object.

cescoffier avatar Mar 02 '23 15:03 cescoffier

Hello, any idea to use ProxyInterceptor with mutiny ? I can't find a solution to chain interceptor...

lucaspouzac avatar Jul 13 '23 15:07 lucaspouzac