Start discovery lifecycle in traditional war deployments.
fixes https://github.com/spring-cloud/spring-cloud-consul/issues/173
This commit is contained in:
@@ -16,25 +16,32 @@
|
||||
|
||||
package org.springframework.cloud.client.discovery;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
|
||||
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Lifecycle methods that may be useful and common to various DiscoveryClient implementations.
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public abstract class AbstractDiscoveryLifecycle implements DiscoveryLifecycle,
|
||||
ApplicationContextAware, ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
ApplicationContextAware {
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private boolean autoStartup = true;
|
||||
|
||||
@@ -48,6 +55,9 @@ public abstract class AbstractDiscoveryLifecycle implements DiscoveryLifecycle,
|
||||
|
||||
private AtomicInteger port = new AtomicInteger(0);
|
||||
|
||||
@Value("${server.port:${SERVER_PORT:${PORT:-1}}}")
|
||||
private Integer serverPort;
|
||||
|
||||
protected ApplicationContext getContext() {
|
||||
return context;
|
||||
}
|
||||
@@ -203,8 +213,8 @@ public abstract class AbstractDiscoveryLifecycle implements DiscoveryLifecycle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
|
||||
@EventListener
|
||||
public void handleContainerInit(EmbeddedServletContainerInitializedEvent event) {
|
||||
// TODO: take SSL into account
|
||||
// Don't register the management port as THE port
|
||||
if (!"management".equals(event.getApplicationContext().getNamespace())) {
|
||||
@@ -212,4 +222,26 @@ public abstract class AbstractDiscoveryLifecycle implements DiscoveryLifecycle,
|
||||
this.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the start() method for a traditional war deployment.
|
||||
* @param event
|
||||
*/
|
||||
@EventListener
|
||||
public void handleContextRefreshed(ContextRefreshedEvent event) {
|
||||
if (!isEmbeddedContext(event)) {
|
||||
if (this.serverPort == null || this.serverPort <= 0) {
|
||||
throw new IllegalStateException("Running as a traditional war and server.port is not set");
|
||||
} else {
|
||||
this.logger.info("Starting AbstractDiscoveryLifecycle during traditional war deployment using server.port: " + this.serverPort);
|
||||
this.port.compareAndSet(0, this.serverPort);
|
||||
this.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isEmbeddedContext(ContextRefreshedEvent event) {
|
||||
return event.getApplicationContext() instanceof EmbeddedWebApplicationContext
|
||||
&& ((EmbeddedWebApplicationContext) event.getApplicationContext()).getEmbeddedServletContainer() != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,12 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.WebIntegrationTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
@@ -38,6 +40,8 @@ public class AbstractDiscoveryLifecycleTests {
|
||||
assertTrue("Lifecycle not running", lifecycle.isRunning());
|
||||
assertTrue("Lifecycle not registered", lifecycle.isRegistered());
|
||||
assertEquals("Lifecycle appName is wrong", "application", lifecycle.getAppName());
|
||||
assertTrue("Lifecycle didn't handle containerInit", lifecycle.isContainerInitHandled());
|
||||
assertFalse("Lifecycle handled contextRefreshed", lifecycle.isContextRefreshedHandled());
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@@ -53,6 +57,8 @@ public class AbstractDiscoveryLifecycleTests {
|
||||
private int port = 0;
|
||||
private boolean registered = false;
|
||||
private boolean deregistered = false;
|
||||
private boolean containerInitHandled = false;
|
||||
private boolean contextRefreshedHandled = false;
|
||||
|
||||
@Override
|
||||
protected int getConfiguredPort() {
|
||||
@@ -84,6 +90,20 @@ public class AbstractDiscoveryLifecycleTests {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleContainerInit(EmbeddedServletContainerInitializedEvent event) {
|
||||
this.containerInitHandled = true;
|
||||
super.handleContainerInit(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleContextRefreshed(ContextRefreshedEvent event) {
|
||||
if (!super.isEmbeddedContext(event)) {
|
||||
this.contextRefreshedHandled = true;
|
||||
}
|
||||
super.handleContextRefreshed(event);
|
||||
}
|
||||
|
||||
public boolean isRegistered() {
|
||||
return registered;
|
||||
}
|
||||
@@ -91,5 +111,13 @@ public class AbstractDiscoveryLifecycleTests {
|
||||
public boolean isDeregistered() {
|
||||
return deregistered;
|
||||
}
|
||||
|
||||
public boolean isContainerInitHandled() {
|
||||
return containerInitHandled;
|
||||
}
|
||||
|
||||
public boolean isContextRefreshedHandled() {
|
||||
return contextRefreshedHandled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.cloud.client.discovery;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.test.ImportAutoConfiguration;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.cloud.client.discovery.AbstractDiscoveryLifecycleTests.TestDiscoveryLifecycle;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class AbstractDiscoveryLifecycleWarTests {
|
||||
|
||||
@Test
|
||||
public void portsWork() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(Config.class);
|
||||
EnvironmentTestUtils.addEnvironment(context.getEnvironment(), "server.port=7777");
|
||||
context.refresh();
|
||||
|
||||
TestDiscoveryLifecycle lifecycle = context.getBean(TestDiscoveryLifecycle.class);
|
||||
assertEquals("Lifecycle port is wrong", 7777, lifecycle.getPort().get());
|
||||
assertFalse("Lifecycle handled containerInit", lifecycle.isContainerInitHandled());
|
||||
assertTrue("Lifecycle didn't handle contextRefreshed", lifecycle.isContextRefreshedHandled());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void portsFailIfNotSet() {
|
||||
new AnnotationConfigApplicationContext(Config.class);
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration({PropertyPlaceholderAutoConfiguration.class})
|
||||
@Configuration
|
||||
public static class Config {
|
||||
@Bean
|
||||
public TestDiscoveryLifecycle testDiscoveryLifecycle() {
|
||||
return new TestDiscoveryLifecycle();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user