2
votes

Spring cloud consul works as expected when run code inside a spring boot with embedded tomcat.

It doesn't work when we deploy code on the standalone tomcat.It appears there is a ConsulAutoServiceRegistrationListener which starts consul service registration on WebServerInitializedEvent. This event is only triggered when we run code inside a spring boot with embedded tomcat.

There are couple of workarounds provided at https://github.com/spring-cloud/spring-cloud-consul/issues/302 but none of them work any longer with latest Greenwich.RC2 release.

What are the other ways we can kick off the service registration on the standalone tomcat ?

Let me know if you need more details.

2
When I say the title I was going to look for the issue you mentioned. What happens with Greenwich.RC2?spencergibb
@spencergibb Thank you for response. for example in the Greenwich.RC2 there is no longer setPort method in the ConsulAutoServiceRegistration that we used to set the port as mentioned in the solution here github.com/spring-cloud/spring-cloud-consul/issues/…. It has been replaced with setPortIfNeeded but that is pacakge protected. Let me know if you need more info.s7vr
Also as a side question what was the reason behind initializing consul auto registration on the spring boot WebServerInitializedEvent instead of spring ContextRefreshedEvent event.s7vr
the port isn't available until WebServerInitializedEvent if using a random port.spencergibb
I think you can set spring.cloud.consul.discovery.port=${server.port} and don't need the setPort() method.spencergibb

2 Answers

1
votes

I think you can set spring.cloud.consul.discovery.port=${server.port} and don't need the setPort() method.

0
votes

This is just a follow-up post, the answer above is still valid. Today I had the same issue, my Spring Boot application didn't register itself to Consul while running on an external Tomcat Server. Although one could come up with a working solution based on all information mentioned in the posts above, I have provided all information here, in one post.

I did have to change one thing in the solution code, the annotation @AutoConfigurationAfter(...) was used. I had to change it to @AutoConfigureAfter(...)


Solution

Add following MyConsulLifecycle to your application, based on solution code:

@Configuration
@ConditionalOnConsulEnabled
@ConditionalOnMissingBean(type= "org.springframework.cloud.consul.discovery.ConsulLifecycle")
@AutoConfigureAfter(ConsulAutoServiceRegistrationAutoConfiguration.class)
public class MyConsulLifecycle implements ApplicationContextAware {

    private ConsulAutoServiceRegistration registration;

    public MyConsulLifecycle(ConsulAutoServiceRegistration registration) {
        this.registration = registration;
    }

    public void setApplicationContext(ApplicationContext context) throws BeansException {
        if (registration != null ) {
            registration.start();
        }
    }
}

As opposed to Brian Peterson's solution, the method setPort() is no longer available. This was already mentioned by Sagar Veeram in the comments on his post.

As spencergibb said, this is solved by setting the spring.cloud.consul.discovery.port=${server.port} in the application.properties file:

server.port=8080
spring.cloud.consul.discovery.port=${server.port}

Note that is is a bit strange to have a server.port property required when using a standalone Tomcat Server.