Search code examples
spring-bootjava-8netflix-zuulnetflix-eureka

Spring Zuul: Dynamically disable a route to a service


I'm trying to disable a Zuul route to a microservice registered with Eureka at runtime (I'm using spring boot).

This is an example:

localhost/hello
localhost/world

Those two are the registered microservices. I would like to disable the route to one of them at runtime without shutting it down.

Is there a way to do this?

Thank you,

Nano


Solution

  • After a lot of efforts I came up with this solution. First, I used Netflix Archaius to watch a property file. Then I proceeded as follows:

    public class ApplicationRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
    
    public ApplicationRouteLocator(String servletPath, ZuulProperties properties) {
        super(servletPath, properties );
    }
    
    
    @Override
    public void refresh() {
       doRefresh();
    }
    }
    

    Made the doRefresh() method public by extending SimpleRouteLocator and calling its method in the overridden one of the interface RefreshableRouteLocator.

    Then I redefined the bean RouteLocator with my custom implementation:

    @Configuration
    @EnableConfigurationProperties( { ZuulProperties.class } )
    public class ZuulConfig {
    
    public static ApplicationRouteLocator simpleRouteLocator;
    
    @Autowired
    private ZuulProperties zuulProperties;
    
    @Autowired
    private ServerProperties server;
    
    @Bean
    @Primary
    public RouteLocator routeLocator() {
        logger.info( "zuulProperties are: {}", zuulProperties );
        simpleRouteLocator = new ApplicationRouteLocator( this.server.getServletPrefix(),
                this.zuulProperties );
    
    
        ConfigurationManager.getConfigInstance().addConfigurationListener( configurationListener );
    
        return simpleRouteLocator;
    }
    
    
    private ConfigurationListener configurationListener =
            new ConfigurationListener() {
    
                @Override
                public void configurationChanged( ConfigurationEvent ce ) {
    
                                // zuulProperties.getRoutes() do something
                                // zuulProperties.getIgnoredPatterns() do something
                                simpleRouteLocator.refresh();
                            }
    
    
    
                    }
    
    }
    

    Every time a property in the file was modified an event was triggered and the ConfigurationEvent was able to deal with it (getPropertyName() and getPropertyValue() to extract data from the event). Since I also Autowired the ZuulProperties I was able to get access to it. With the right rule I could find whether the property of Zuul

    zuul.ignoredPatterns
    

    was modified changing its value in the ZuulProperties accordingly.