Zuul compatability with Spring boot 3

1.6k views Asked by At

I migrated from spring boot 2.7 to 3.1.1, before I have redirection with Zuul and it can't find bean for RouteLocator and ZuulController:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.cglib.proxy.*;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.web.ZuulController;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/** Zuul configuration. */
@Configuration
public class ZuulConfiguration {

    /**
     * Constructs a new bean post-processor for Zuul.
     *
     * @param routeLocator
     *            the route locator.
     * @param zuulController
     *            the Zuul controller.
     * @param errorController
     *            the error controller.
     * @return the new bean post-processor.
     */
    @Bean
    @Primary
    public ZuulPostProcessor zuulPostProcessor(@Autowired RouteLocator routeLocator,
                                               @Autowired ZuulController zuulController,
                                               @Autowired ErrorController errorController) {
        return new ZuulPostProcessor(routeLocator, zuulController, errorController);
    }

    private static final class ZuulPostProcessor implements BeanPostProcessor {

        private final RouteLocator routeLocator;

        private final ZuulController zuulController;

        private final boolean hasErrorController;

        ZuulPostProcessor(RouteLocator routeLocator, ZuulController zuulController, ErrorController errorController) {
            this.routeLocator = routeLocator;
            this.zuulController = zuulController;
            this.hasErrorController = (errorController != null);
        }

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (hasErrorController && (bean instanceof ZuulHandlerMapping)) {
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(ZuulHandlerMapping.class);
                enhancer.setCallbackFilter(LookupHandlerCallbackFilter.INSTANCE); // only for lookupHandler
                enhancer.setCallbacks(new Callback[] { LookupHandlerMethodInterceptor.INSTANCE, NoOp.INSTANCE });
                Constructor<?> ctor = ZuulHandlerMapping.class.getConstructors()[0];
                return enhancer.create(ctor.getParameterTypes(), new Object[] { routeLocator, zuulController });
            }
            return bean;
        }

    }

    private enum LookupHandlerCallbackFilter implements CallbackFilter {

        INSTANCE;

        @Override
        public int accept(Method method) {
            if ("lookupHandler".equals(method.getName())) {
                return 0;
            }
            return 1;
        }

    }

    private enum LookupHandlerMethodInterceptor implements MethodInterceptor {

        INSTANCE;

        @Override
        public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            if ("/error".equals(args[0])) {

                /* by entering this branch we avoid the ZuulHandlerMapping.lookupHandler method to trigger the NoSuchMethodError */
                return null;
            }
            return methodProxy.invokeSuper(target, args);
        }

    }
}

Zuul not autowired dependencies

I can't migrate to api-gateway, cause we use spring-web-dependency (I read that webflux is needed)

If you know any another ways how to redirect /report page to kibana in elastic (main idea of task) let me know, but better to keep old Zuul Configuration and add some dependencies

I see that it not works cause of usage javax servlet, in spring boot 3.1.1 - jakarta

Please help me :)

0

There are 0 answers