2

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.

s7vr
  • 73,656
  • 11
  • 106
  • 127
  • When I say the title I was going to look for the issue you mentioned. What happens with Greenwich.RC2? – spencergibb Jan 11 '19 at 17:24
  • @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 https://github.com/spring-cloud/spring-cloud-consul/issues/302#issuecomment-342340582. It has been replaced with setPortIfNeeded but that is pacakge protected. Let me know if you need more info. – s7vr Jan 11 '19 at 18:58
  • 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 Jan 11 '19 at 19:03
  • the port isn't available until `WebServerInitializedEvent` if using a random port. – spencergibb Jan 11 '19 at 22:17
  • I think you can set `spring.cloud.consul.discovery.port=${server.port}` and don't need the `setPort()` method. – spencergibb Jan 11 '19 at 22:24
  • Thank you. It worked. Please feel free to add as an answer. – s7vr Jan 11 '19 at 23:31

2 Answers2

1

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

spencergibb
  • 24,471
  • 6
  • 69
  • 75
0

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.

bramvdwalle
  • 79
  • 1
  • 10