Search code examples
spring-boottogglz

Expose Togglz Admin console in Spring Boot on management-port


By default Togglz admin console runs on application port (configured by server.port property). I want to expose it on management.port. My question: is it possible?


Solution

  • If you use Togglz >= 2.4.0 then this feature is available out of the box.

    For older releases solution is below:

    I managed to expose a raw servlet on management.port by wrapping it with MvcEndpoint. The easiest way to do it to use Spring Cloud module which does all the job for you (for example in the HystrixStreamEndpoint):

    public class HystrixStreamEndpoint extends ServletWrappingEndpoint {
    
        public HystrixStreamEndpoint() {
            super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream",
                    true, true);
        }
    
    }
    

    In the case of TogglzConsoleServlet there is unfortunately one more hack to do with path's due to the way it extracts prefix from request URI, so the whole solution looks a little bit ugly:

    @Component
    class TogglzConsoleEndpoint implements MvcEndpoint {
    
        private static final String ADMIN_CONSOLE_URL = "/togglz-console";
        private final TogglzConsoleServlet togglzConsoleServlet;
    
        @Autowired
        TogglzConsoleEndpoint(final ServletContext servletContext) throws ServletException {
            this.togglzConsoleServlet = new TogglzConsoleServlet();
            togglzConsoleServlet.init(new DelegatingServletConfig(servletContext));
        }
    
        @Override
        public String getPath() {
            return ADMIN_CONSOLE_URL;
        }
    
        @Override
        public boolean isSensitive() {
            return true;
        }
    
        @Override
        public Class<? extends Endpoint> getEndpointType() {
            return null;
        }
    
        @RequestMapping("**")
        public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
            HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) {
                @Override
                public String getServletPath() {
                    return ADMIN_CONSOLE_URL;
                }
            };
            togglzConsoleServlet.service(requestWrapper, response);
            return null;
        }
    
        private class DelegatingServletConfig implements ServletConfig {
    
            private final ServletContext servletContext;
    
            DelegatingServletConfig(final ServletContext servletContext) {
                this.servletContext = servletContext;
            }
    
            @Override
            public String getServletName() {
                return TogglzConsoleEndpoint.this.togglzConsoleServlet.getServletName();
            }
    
            @Override
            public ServletContext getServletContext() {
                return servletContext;
            }
    
            @Override
            public String getInitParameter(final String name) {
                return servletContext.getInitParameter(name);
            }
    
            @Override
            public Enumeration<String> getInitParameterNames() {
                return servletContext.getInitParameterNames();
            }
        }
    }