Extract former config-client features to a new spring-cloud-context
Fixes gh-14
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
package org.springframework.cloud.bootstrap;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.bootstrap.BootstrapDisabledAutoConfigurationIntegrationTests.Application;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@IntegrationTest("spring.cloud.bootstrap.enabled:false")
|
||||
public class BootstrapDisabledAutoConfigurationIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Test
|
||||
public void noBootstrapProperties() {
|
||||
assertFalse(environment.getPropertySources().contains("bootstrap"));
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@Configuration
|
||||
protected static class Application {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.springframework.cloud.bootstrap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.bootstrap.BootstrapOrderingAutoConfigurationIntegrationTests.Application;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@IntegrationTest("encrypt.key:deadbeef")
|
||||
@ActiveProfiles("encrypt")
|
||||
public class BootstrapOrderingAutoConfigurationIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Test
|
||||
public void bootstrapPropertiesExist() {
|
||||
assertTrue(environment.getPropertySources().contains("bootstrap"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalPropertiesDecrypted() {
|
||||
assertEquals("foo", environment.resolvePlaceholders("${foo}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapPropertiesDecrypted() {
|
||||
assertEquals("bar", environment.resolvePlaceholders("${bar}"));
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@Configuration
|
||||
protected static class Application {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.bootstrap.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class BootstrapConfigurationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Rule
|
||||
public ExpectedException expected = ExpectedException.none();
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
// Expected.* is bound to the PropertySourceConfiguration below
|
||||
System.clearProperty("expected.name");
|
||||
System.clearProperty("expected.fail");
|
||||
// Used to test system properties override
|
||||
System.clearProperty("bootstrap.foo");
|
||||
PropertySourceConfiguration.MAP.clear();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pickupExternalBootstrapProperties() {
|
||||
String externalPropertiesPath = getExternalProperties();
|
||||
|
||||
this.context = new SpringApplicationBuilder().web(false)
|
||||
.sources(BareConfiguration.class)
|
||||
.properties("spring.cloud.bootstrap.location:" + externalPropertiesPath)
|
||||
.run();
|
||||
assertEquals("externalPropertiesInfoName", this.context.getEnvironment()
|
||||
.getProperty("info.name"));
|
||||
assertTrue(this.context.getEnvironment().getPropertySources()
|
||||
.contains("bootstrap"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Running the test from maven will start from a different directory then starting it
|
||||
* from intellij
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String getExternalProperties() {
|
||||
String externalPropertiesPath = "";
|
||||
File externalProperties = new File(
|
||||
"src/test/resources/external-properties/bootstrap.properties");
|
||||
if (externalProperties.exists()) {
|
||||
externalPropertiesPath = externalProperties.getAbsolutePath();
|
||||
}
|
||||
else {
|
||||
externalProperties = new File(
|
||||
"spring-cloud-config-client/src/test/resources/external-properties/bootstrap.properties");
|
||||
externalPropertiesPath = externalProperties.getAbsolutePath();
|
||||
}
|
||||
return externalPropertiesPath;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void picksUpAdditionalPropertySource() {
|
||||
PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar");
|
||||
System.setProperty("expected.name", "bootstrap");
|
||||
this.context = new SpringApplicationBuilder().web(false)
|
||||
.sources(BareConfiguration.class).run();
|
||||
assertEquals("bar", this.context.getEnvironment().getProperty("bootstrap.foo"));
|
||||
assertTrue(this.context.getEnvironment().getPropertySources()
|
||||
.contains("bootstrap"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failsOnPropertySource() {
|
||||
System.setProperty("expected.fail", "true");
|
||||
this.expected.expectMessage("Planned");
|
||||
this.context = new SpringApplicationBuilder().web(false)
|
||||
.sources(BareConfiguration.class).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideSystemPropertySourceByDefault() {
|
||||
PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar");
|
||||
System.setProperty("bootstrap.foo", "system");
|
||||
this.context = new SpringApplicationBuilder().web(false)
|
||||
.sources(BareConfiguration.class).run();
|
||||
assertEquals("bar", this.context.getEnvironment().getProperty("bootstrap.foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void systemPropertyOverrideFalse() {
|
||||
PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar");
|
||||
PropertySourceConfiguration.MAP.put(
|
||||
"spring.cloud.config.overrideSystemProperties", "false");
|
||||
System.setProperty("bootstrap.foo", "system");
|
||||
this.context = new SpringApplicationBuilder().web(false)
|
||||
.sources(BareConfiguration.class).run();
|
||||
assertEquals("system", this.context.getEnvironment().getProperty("bootstrap.foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void systemPropertyOverrideWhenOverrideDisallowed() {
|
||||
PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar");
|
||||
PropertySourceConfiguration.MAP.put(
|
||||
"spring.cloud.config.overrideSystemProperties", "false");
|
||||
// If spring.cloud.config.allowOverride=false is in the remote property sources
|
||||
// with sufficiently high priority it always wins. Admins can enforce it by adding
|
||||
// their own remote property source.
|
||||
PropertySourceConfiguration.MAP.put("spring.cloud.config.allowOverride", "false");
|
||||
System.setProperty("bootstrap.foo", "system");
|
||||
this.context = new SpringApplicationBuilder().web(false)
|
||||
.sources(BareConfiguration.class).run();
|
||||
assertEquals("bar", this.context.getEnvironment().getProperty("bootstrap.foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applicationNameInBootstrapAndMain() {
|
||||
System.setProperty("expected.name", "main");
|
||||
this.context = new SpringApplicationBuilder()
|
||||
.web(false)
|
||||
.properties("spring.cloud.bootstrap.name:other",
|
||||
"spring.config.name:plain").sources(BareConfiguration.class)
|
||||
.run();
|
||||
assertEquals("app",
|
||||
this.context.getEnvironment().getProperty("spring.application.name"));
|
||||
// The parent is called "main" because spring.application.name is specified in
|
||||
// other.properties (the bootstrap properties)
|
||||
assertEquals(
|
||||
"main",
|
||||
this.context.getParent().getEnvironment()
|
||||
.getProperty("spring.application.name"));
|
||||
// The bootstrap context has a different "bootstrap" property source
|
||||
assertNotSame(
|
||||
this.context.getEnvironment().getPropertySources().get("bootstrap"),
|
||||
((ConfigurableEnvironment) this.context.getParent().getEnvironment())
|
||||
.getPropertySources().get("bootstrap"));
|
||||
assertEquals("app", this.context.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applicationNameNotInBootstrap() {
|
||||
System.setProperty("expected.name", "main");
|
||||
this.context = new SpringApplicationBuilder()
|
||||
.web(false)
|
||||
.properties("spring.cloud.bootstrap.name:application",
|
||||
"spring.config.name:other").sources(BareConfiguration.class)
|
||||
.run();
|
||||
assertEquals("main",
|
||||
this.context.getEnvironment().getProperty("spring.application.name"));
|
||||
// The parent is called "application" because spring.application.name is not
|
||||
// defined in the bootstrap properties
|
||||
assertEquals("application", this.context.getParent().getEnvironment()
|
||||
.getProperty("spring.application.name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applicationNameOnlyInBootstrap() {
|
||||
System.setProperty("expected.name", "main");
|
||||
this.context = new SpringApplicationBuilder().web(false)
|
||||
.properties("spring.cloud.bootstrap.name:other")
|
||||
.sources(BareConfiguration.class).run();
|
||||
// The main context is called "main" because spring.application.name is specified
|
||||
// in other.properties (and not in the main config file)
|
||||
assertEquals("main",
|
||||
this.context.getEnvironment().getProperty("spring.application.name"));
|
||||
// The parent is called "main" because spring.application.name is specified in
|
||||
// other.properties (the bootstrap properties this time)
|
||||
assertEquals(
|
||||
"main",
|
||||
this.context.getParent().getEnvironment()
|
||||
.getProperty("spring.application.name"));
|
||||
assertEquals("main", this.context.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void environmentEnrichedOnceWhenSharedWithChildContext() {
|
||||
PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar");
|
||||
this.context = new SpringApplicationBuilder().sources(BareConfiguration.class)
|
||||
.environment(new StandardEnvironment()).child(BareConfiguration.class)
|
||||
.web(false).run();
|
||||
assertEquals("bar", this.context.getEnvironment().getProperty("bootstrap.foo"));
|
||||
assertEquals(this.context.getEnvironment(), this.context.getParent()
|
||||
.getEnvironment());
|
||||
MutablePropertySources sources = this.context.getEnvironment()
|
||||
.getPropertySources();
|
||||
PropertySource<?> bootstrap = sources.get("bootstrap");
|
||||
assertNotNull(bootstrap);
|
||||
assertEquals(0, sources.precedenceOf(bootstrap));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void environmentEnrichedInParentContext() {
|
||||
PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar");
|
||||
this.context = new SpringApplicationBuilder().sources(BareConfiguration.class)
|
||||
.child(BareConfiguration.class).web(false).run();
|
||||
assertEquals("bar", this.context.getEnvironment().getProperty("bootstrap.foo"));
|
||||
assertNotSame(this.context.getEnvironment(), this.context.getParent()
|
||||
.getEnvironment());
|
||||
assertTrue(this.context.getEnvironment().getPropertySources()
|
||||
.contains("bootstrap"));
|
||||
assertTrue(((ConfigurableEnvironment) this.context.getParent().getEnvironment())
|
||||
.getPropertySources().contains("bootstrap"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentProfileInChild() {
|
||||
PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar");
|
||||
// Profiles are always merged with the child
|
||||
ConfigurableApplicationContext parent = new SpringApplicationBuilder()
|
||||
.sources(BareConfiguration.class).profiles("parent").web(false).run();
|
||||
this.context = new SpringApplicationBuilder(BareConfiguration.class)
|
||||
.profiles("child").parent(parent).web(false).run();
|
||||
assertNotSame(this.context.getEnvironment(), this.context.getParent()
|
||||
.getEnvironment());
|
||||
// The ApplicationContext merges profiles (profiles and property sources), see
|
||||
// AbstractEnvironment.merge()
|
||||
assertTrue(this.context.getEnvironment().acceptsProfiles("child", "parent"));
|
||||
// But the parent is not a child
|
||||
assertFalse(this.context.getParent().getEnvironment().acceptsProfiles("child"));
|
||||
assertTrue(this.context.getParent().getEnvironment().acceptsProfiles("parent"));
|
||||
assertTrue(((ConfigurableEnvironment) this.context.getParent().getEnvironment())
|
||||
.getPropertySources().contains("bootstrap"));
|
||||
assertEquals("bar", this.context.getEnvironment().getProperty("bootstrap.foo"));
|
||||
// The "bootstrap" property source is not shared now, but it has the same
|
||||
// properties in it because they are pulled from the PropertySourceConfiguration
|
||||
// below
|
||||
assertEquals("bar",
|
||||
this.context.getParent().getEnvironment().getProperty("bootstrap.foo"));
|
||||
// The parent property source is there in the child because they are both in the
|
||||
// "parent" profile (by virtue of the merge in AbstractEnvironment)
|
||||
assertEquals("parent", this.context.getEnvironment().getProperty("info.name"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
protected static class BareConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties("expected")
|
||||
// This is added to bootstrap context as a source in bootstrap.properties
|
||||
protected static class PropertySourceConfiguration implements PropertySourceLocator {
|
||||
|
||||
public static Map<String, Object> MAP = new HashMap<String, Object>(
|
||||
Collections.<String, Object> singletonMap("bootstrap.foo", "bar"));
|
||||
|
||||
private String name;
|
||||
|
||||
private boolean fail = false;
|
||||
|
||||
@Override
|
||||
public PropertySource<?> locate(Environment environment) {
|
||||
if (this.name != null) {
|
||||
assertEquals(this.name,
|
||||
environment.getProperty("spring.application.name"));
|
||||
}
|
||||
if (this.fail) {
|
||||
throw new RuntimeException("Planned");
|
||||
}
|
||||
return new MapPropertySource("testBootstrap", MAP);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isFail() {
|
||||
return this.fail;
|
||||
}
|
||||
|
||||
public void setFail(boolean fail) {
|
||||
this.fail = fail;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.springframework.cloud.bootstrap.encrypt;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.security.crypto.encrypt.TextEncryptor;
|
||||
|
||||
public class EncryptionBootstrapConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void rsaKeyStore() {
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder(
|
||||
EncryptionBootstrapConfiguration.class).web(false).properties(
|
||||
"encrypt.keyStore.location:classpath:/server.jks",
|
||||
"encrypt.keyStore.password:letmein",
|
||||
"encrypt.keyStore.alias:mytestkey", "encrypt.keyStore.secret:changeme")
|
||||
.run();
|
||||
TextEncryptor encryptor = context.getBean(TextEncryptor.class);
|
||||
assertEquals("foo", encryptor.decrypt(encryptor.encrypt("foo")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.bootstrap.encrypt;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.security.crypto.encrypt.Encryptors;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class EnvironmentDecryptApplicationListenerTests {
|
||||
|
||||
private EnvironmentDecryptApplicationInitializer listener = new EnvironmentDecryptApplicationInitializer(Encryptors.noOpText());
|
||||
|
||||
@Test
|
||||
public void decryptCipherKey() {
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(context, "foo: {cipher}bar");
|
||||
listener.initialize(context);
|
||||
assertEquals("bar", context.getEnvironment().getProperty("foo"));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void errorOnDecrypt() {
|
||||
listener = new EnvironmentDecryptApplicationInitializer(Encryptors.text("deadbeef", "AFFE37"));
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(context, "foo: {cipher}bar");
|
||||
listener.initialize(context);
|
||||
assertEquals("bar", context.getEnvironment().getProperty("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorOnDecryptWithEmpty() {
|
||||
listener = new EnvironmentDecryptApplicationInitializer(Encryptors.text("deadbeef", "AFFE37"));
|
||||
listener.setFailOnError(false);
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(context, "foo: {cipher}bar");
|
||||
listener.initialize(context);
|
||||
// Empty is safest fallback for undecryptable cipher
|
||||
assertEquals("", context.getEnvironment().getProperty("foo"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.context.environment;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.cloud.context.environment.EnvironmentManagerIntegrationTests.TestConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
public class EnvironmentManagerIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private TestProperties properties;
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
private MockMvc mvc;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefresh() throws Exception {
|
||||
assertEquals("Hello scope!", properties.getMessage());
|
||||
// Change the dynamic property source...
|
||||
this.mvc.perform(post("/env").param("message", "Foo")).andExpect(status().isOk()).andExpect(
|
||||
content().string("{\"message\":\"Foo\"}"));
|
||||
assertEquals("Foo", properties.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshFails() throws Exception {
|
||||
try {
|
||||
this.mvc.perform(post("/env").param("delay", "foo")).andExpect(
|
||||
status().is5xxServerError());
|
||||
fail("expected ServletException");
|
||||
} catch (ServletException e) {
|
||||
// The underlying BindException is not handled by the dispatcher servlet
|
||||
}
|
||||
assertEquals(0, properties.getDelay());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TestConfiguration.class, args);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
protected TestProperties properties() {
|
||||
return new TestProperties();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties
|
||||
protected static class TestProperties {
|
||||
|
||||
private String message;
|
||||
|
||||
private int delay;
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
public void setDelay(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.context.properties;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderIntegrationTests.TestConfiguration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@SpringApplicationConfiguration(classes=TestConfiguration.class)
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class ConfigurationPropertiesRebinderIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private TestProperties properties;
|
||||
|
||||
@Autowired
|
||||
private ConfigurationPropertiesRebinder rebinder;
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testSimpleProperties() throws Exception {
|
||||
assertEquals("Hello scope!", properties.getMessage());
|
||||
// Change the dynamic property source...
|
||||
EnvironmentTestUtils.addEnvironment(environment, "message:Foo");
|
||||
// ...but don't refresh, so the bean stays the same:
|
||||
assertEquals("Hello scope!", properties.getMessage());
|
||||
assertEquals(1, properties.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testRefresh() throws Exception {
|
||||
assertEquals(1, properties.getCount());
|
||||
assertEquals("Hello scope!", properties.getMessage());
|
||||
// Change the dynamic property source...
|
||||
EnvironmentTestUtils.addEnvironment(environment, "message:Foo");
|
||||
// ...and then refresh, so the bean is re-initialized:
|
||||
rebinder.rebind();
|
||||
assertEquals("Foo", properties.getMessage());
|
||||
assertEquals(2, properties.getCount());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@Import({RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
protected TestProperties properties() {
|
||||
return new TestProperties();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties
|
||||
protected static class TestProperties {
|
||||
private String message;
|
||||
private int delay;
|
||||
private int count = 0;
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
}
|
||||
public void setDelay(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.count ++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.context.restart;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
public class RestartIntegrationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartTwice() throws Exception {
|
||||
|
||||
context = SpringApplication.run(TestConfiguration.class, "--endpoints.restart.enabled=true", "--server.port=0");
|
||||
RestartEndpoint endpoint = context.getBean(RestartEndpoint.class);
|
||||
assertNotNull(context.getParent());
|
||||
assertNull(context.getParent().getParent());
|
||||
context = endpoint.restart();
|
||||
|
||||
assertNotNull(context);
|
||||
assertNotNull(context.getParent());
|
||||
assertNull(context.getParent().getParent());
|
||||
|
||||
RestartEndpoint next = context.getBean(RestartEndpoint.class);
|
||||
assertNotSame(endpoint, next);
|
||||
context = next.restart();
|
||||
|
||||
assertNotNull(context);
|
||||
assertNotNull(context.getParent());
|
||||
assertNull(context.getParent().getParent());
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TestConfiguration.class, args);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
protected static class TestConfiguration {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.context.scope.refresh;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.cloud.context.scope.refresh.ImportRefreshScopeIntegrationTests.TestConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class ImportRefreshScopeIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Autowired
|
||||
private ExampleService service;
|
||||
|
||||
@Autowired
|
||||
private org.springframework.cloud.context.scope.refresh.RefreshScope scope;
|
||||
|
||||
@Test
|
||||
public void testSimpleProperties() throws Exception {
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
assertEquals("refresh", beanFactory.getBeanDefinition("scopedTarget.service").getScope());
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
}
|
||||
|
||||
@Configuration("service")
|
||||
@RefreshScope
|
||||
public static class ExampleService {
|
||||
|
||||
public String getMessage() {
|
||||
return "Hello scope!";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ RefreshAutoConfiguration.class, ExampleService.class })
|
||||
protected static class TestConfiguration {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.context.scope.refresh;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.cloud.context.scope.refresh.MoreRefreshScopeIntegrationTests.TestConfiguration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MoreRefreshScopeIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private TestService service;
|
||||
|
||||
@Autowired
|
||||
private TestProperties properties;
|
||||
|
||||
@Autowired
|
||||
private org.springframework.cloud.context.scope.refresh.RefreshScope scope;
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
TestService.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testSimpleProperties() throws Exception {
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
assertTrue(service instanceof Advised);
|
||||
// Change the dynamic property source...
|
||||
EnvironmentTestUtils.addEnvironment(environment, "message:Foo");
|
||||
// ...but don't refresh, so the bean stays the same:
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
assertEquals(1, TestService.getInitCount());
|
||||
assertEquals(0, TestService.getDestroyCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testRefresh() throws Exception {
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
String id1 = service.toString();
|
||||
// Change the dynamic property source...
|
||||
EnvironmentTestUtils.addEnvironment(environment, "message:Foo");
|
||||
// ...and then refresh, so the bean is re-initialized:
|
||||
scope.refreshAll();
|
||||
String id2 = service.toString();
|
||||
assertEquals("Foo", service.getMessage());
|
||||
assertEquals(2, TestService.getInitCount());
|
||||
assertEquals(1, TestService.getDestroyCount());
|
||||
assertNotSame(id1, id2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testRefreshFails() throws Exception {
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
// Change the dynamic property source...
|
||||
EnvironmentTestUtils.addEnvironment(environment, "message:Foo", "delay:foo");
|
||||
// ...and then refresh, so the bean is re-initialized:
|
||||
scope.refreshAll();
|
||||
try {
|
||||
// If a refresh fails (e.g. a binding error in this case) the application is
|
||||
// basically hosed.
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
fail("expected BeanCreationException");
|
||||
} catch (BeanCreationException e) {
|
||||
}
|
||||
// But we can fix it by fixing the binding error:
|
||||
EnvironmentTestUtils.addEnvironment(environment, "delay:0");
|
||||
// ...and then refresh, so the bean is re-initialized:
|
||||
scope.refreshAll();
|
||||
assertEquals("Foo", service.getMessage());
|
||||
}
|
||||
|
||||
public static class TestService implements InitializingBean, DisposableBean {
|
||||
|
||||
private static Log logger = LogFactory.getLog(TestService.class);
|
||||
|
||||
private volatile static int initCount = 0;
|
||||
|
||||
private volatile static int destroyCount = 0;
|
||||
|
||||
private String message = null;
|
||||
|
||||
private volatile long delay = 0;
|
||||
|
||||
public void setDelay(long delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
logger.debug("Initializing message: " + message);
|
||||
initCount++;
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
logger.debug("Destroying message: " + message);
|
||||
destroyCount++;
|
||||
message = null;
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
initCount = 0;
|
||||
destroyCount = 0;
|
||||
}
|
||||
|
||||
public static int getInitCount() {
|
||||
return initCount;
|
||||
}
|
||||
|
||||
public static int getDestroyCount() {
|
||||
return destroyCount;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
logger.debug("Setting message: " + message);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
logger.debug("Getting message: " + message);
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
logger.info("Returning message: " + message);
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
@RefreshScope
|
||||
protected TestProperties properties() {
|
||||
return new TestProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@RefreshScope
|
||||
public TestService service() {
|
||||
TestService service = new TestService();
|
||||
service.setMessage(properties().getMessage());
|
||||
service.setDelay(properties().getDelay());
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties
|
||||
@ManagedResource
|
||||
protected static class TestProperties {
|
||||
|
||||
private String message;
|
||||
|
||||
private int delay;
|
||||
|
||||
@ManagedAttribute
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
public void setDelay(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.context.scope.refresh;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.TestRestTemplate;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshEndpointIntegrationTests.ClientApp;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = ClientApp.class)
|
||||
@IntegrationTest("server.port:0")
|
||||
@WebAppConfiguration
|
||||
public class RefreshEndpointIntegrationTests {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
public void webAccess() throws Exception {
|
||||
TestRestTemplate template = new TestRestTemplate();
|
||||
template.exchange(
|
||||
getUrlEncodedEntity("http://localhost:" + port + "/env", "message",
|
||||
"Hello Dave!"), String.class);
|
||||
template.postForObject("http://localhost:" + port + "/refresh", "", String.class);
|
||||
String message = template.getForObject("http://localhost:" + port + "/",
|
||||
String.class);
|
||||
assertEquals("Hello Dave!", message);
|
||||
}
|
||||
|
||||
private RequestEntity<?> getUrlEncodedEntity(String uri, String key, String value)
|
||||
throws URISyntaxException {
|
||||
MultiValueMap<String, String> env = new LinkedMultiValueMap<String, String>(
|
||||
Collections.singletonMap("message", Arrays.asList("Hello Dave!")));
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
RequestEntity<MultiValueMap<String, String>> entity = new RequestEntity<MultiValueMap<String, String>>(
|
||||
env, headers, HttpMethod.POST, new URI(uri));
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
protected static class ClientApp {
|
||||
|
||||
@Bean
|
||||
@RefreshScope
|
||||
public Controller controller() {
|
||||
return new Controller();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ClientApp.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
protected static class Controller {
|
||||
|
||||
@Value("${message:Hello World!}")
|
||||
String message;
|
||||
|
||||
@RequestMapping("/")
|
||||
public String hello() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.context.scope.refresh;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScopeConcurrencyTests.TestConfiguration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.Repeat;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@SpringApplicationConfiguration(classes=TestConfiguration.class)
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class RefreshScopeConcurrencyTests {
|
||||
|
||||
private static Log logger = LogFactory.getLog(RefreshScopeConcurrencyTests.class);
|
||||
|
||||
private ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
@Autowired
|
||||
private Service service;
|
||||
|
||||
@Autowired
|
||||
private TestProperties properties;
|
||||
|
||||
@Autowired
|
||||
private org.springframework.cloud.context.scope.refresh.RefreshScope scope;
|
||||
|
||||
@Test
|
||||
@Repeat(10)
|
||||
@DirtiesContext
|
||||
public void testConcurrentRefresh() throws Exception {
|
||||
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
properties.setMessage("Foo");
|
||||
properties.setDelay(500);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Future<String> result = executor.submit(new Callable<String>() {
|
||||
public String call() throws Exception {
|
||||
logger.debug("Background started.");
|
||||
try {
|
||||
return service.getMessage();
|
||||
} finally {
|
||||
latch.countDown();
|
||||
logger.debug("Background done.");
|
||||
}
|
||||
}
|
||||
});
|
||||
assertTrue(latch.await(1500, TimeUnit.MILLISECONDS));
|
||||
logger.info("Refreshing");
|
||||
scope.refreshAll();
|
||||
assertEquals("Foo", service.getMessage());
|
||||
/*
|
||||
* This is the most important assertion: we don't want a null value because that means the bean was destroyed
|
||||
* and not re-initialized before we accessed it.
|
||||
*/
|
||||
assertNotNull(result.get());
|
||||
assertEquals("Hello scope!", result.get());
|
||||
}
|
||||
|
||||
public static interface Service {
|
||||
|
||||
String getMessage();
|
||||
|
||||
}
|
||||
|
||||
public static class ExampleService implements Service, InitializingBean, DisposableBean {
|
||||
|
||||
private static Log logger = LogFactory.getLog(ExampleService.class);
|
||||
|
||||
private String message = null;
|
||||
private volatile long delay = 0;
|
||||
|
||||
public void setDelay(long delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
logger.debug("Initializing message: " + message);
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
logger.debug("Destroying message: " + message);
|
||||
message = null;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
logger.debug("Setting message: " + message);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
logger.debug("Getting message: " + message);
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
logger.info("Returning message: " + message);
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(TestProperties.class)
|
||||
@Import({RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Autowired
|
||||
private TestProperties properties;
|
||||
|
||||
@Bean
|
||||
@RefreshScope
|
||||
public ExampleService service() {
|
||||
ExampleService service = new ExampleService();
|
||||
service.setMessage(properties.getMessage());
|
||||
service.setDelay(properties.getDelay());
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties
|
||||
@ManagedResource
|
||||
protected static class TestProperties {
|
||||
private String message;
|
||||
private int delay;
|
||||
@ManagedAttribute
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
@ManagedAttribute
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
}
|
||||
public void setDelay(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.context.scope.refresh;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.cloud.context.environment.EnvironmentManager;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScopeConfigurationTests.NestedApp.NestedController;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class RefreshScopeConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@Rule
|
||||
public ExpectedException expected = ExpectedException.none();
|
||||
|
||||
@After
|
||||
public void init() {
|
||||
if (context!=null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
EnvironmentManager environmentManager = context.getBean(EnvironmentManager.class);
|
||||
environmentManager.setProperty("message", "Hello Dave!");
|
||||
org.springframework.cloud.context.scope.refresh.RefreshScope scope = context.getBean(org.springframework.cloud.context.scope.refresh.RefreshScope.class);
|
||||
scope.refreshAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* See gh-43
|
||||
*/
|
||||
@Test
|
||||
public void configurationWithRefreshScope() throws Exception {
|
||||
context = new AnnotationConfigApplicationContext(Application.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class);
|
||||
Application application = context.getBean(Application.class);
|
||||
assertEquals("refresh", context.getBeanDefinition("scopedTarget.application").getScope());
|
||||
application.hello();
|
||||
refresh();
|
||||
String message = application.hello();
|
||||
assertEquals("Hello Dave!", message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshScopeOnBean() throws Exception {
|
||||
context = new AnnotationConfigApplicationContext(ClientApp.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class);
|
||||
Controller application = context.getBean(Controller.class);
|
||||
application.hello();
|
||||
refresh();
|
||||
String message = application.hello();
|
||||
assertEquals("Hello Dave!", message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshScopeOnNested() throws Exception {
|
||||
context = new AnnotationConfigApplicationContext(NestedApp.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class);
|
||||
NestedController application = context.getBean(NestedController.class);
|
||||
application.hello();
|
||||
refresh();
|
||||
String message = application.hello();
|
||||
assertEquals("Hello Dave!", message);
|
||||
}
|
||||
|
||||
// WTF? Maven can't compile without the FQN on this one (not the others).
|
||||
@org.springframework.context.annotation.Configuration
|
||||
protected static class NestedApp {
|
||||
|
||||
@RestController
|
||||
@RefreshScope
|
||||
protected static class NestedController {
|
||||
|
||||
@Value("${message:Hello World!}")
|
||||
String message;
|
||||
|
||||
@RequestMapping("/")
|
||||
public String hello() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ClientApp.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration("application")
|
||||
@RefreshScope
|
||||
protected static class Application {
|
||||
|
||||
@Value("${message:Hello World!}")
|
||||
String message = "Hello World";
|
||||
|
||||
@RequestMapping("/")
|
||||
public String hello() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ClientApp {
|
||||
|
||||
@Bean
|
||||
@RefreshScope
|
||||
public Controller controller() {
|
||||
return new Controller();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ClientApp.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
protected static class Controller {
|
||||
|
||||
@Value("${message:Hello World!}")
|
||||
String message;
|
||||
|
||||
@RequestMapping("/")
|
||||
public String hello() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.context.scope.refresh;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.cloud.context.scope.GenericScope;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScopeIntegrationTests.TestConfiguration;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class RefreshScopeIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private Service service;
|
||||
|
||||
@Autowired
|
||||
private TestProperties properties;
|
||||
|
||||
@Autowired
|
||||
private org.springframework.cloud.context.scope.refresh.RefreshScope scope;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
ExampleService.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testSimpleProperties() throws Exception {
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
assertTrue(service instanceof Advised);
|
||||
// Change the dynamic property source...
|
||||
properties.setMessage("Foo");
|
||||
// ...but don't refresh, so the bean stays the same:
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
assertEquals(1, ExampleService.getInitCount());
|
||||
assertEquals(0, ExampleService.getDestroyCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testRefresh() throws Exception {
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
String id1 = service.toString();
|
||||
// Change the dynamic property source...
|
||||
properties.setMessage("Foo");
|
||||
// ...and then refresh, so the bean is re-initialized:
|
||||
scope.refreshAll();
|
||||
String id2 = service.toString();
|
||||
assertEquals("Foo", service.getMessage());
|
||||
assertEquals(2, ExampleService.getInitCount());
|
||||
assertEquals(1, ExampleService.getDestroyCount());
|
||||
assertNotSame(id1, id2);
|
||||
assertNotNull(ExampleService.event);
|
||||
assertEquals(RefreshScopeRefreshedEvent.DEFAULT_NAME,
|
||||
ExampleService.event.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testRefreshBean() throws Exception {
|
||||
assertEquals("Hello scope!", service.getMessage());
|
||||
String id1 = service.toString();
|
||||
// Change the dynamic property source...
|
||||
properties.setMessage("Foo");
|
||||
// ...and then refresh, so the bean is re-initialized:
|
||||
scope.refresh("service");
|
||||
String id2 = service.toString();
|
||||
assertEquals("Foo", service.getMessage());
|
||||
assertEquals(2, ExampleService.getInitCount());
|
||||
assertEquals(1, ExampleService.getDestroyCount());
|
||||
assertNotSame(id1, id2);
|
||||
assertNotNull(ExampleService.event);
|
||||
assertEquals(GenericScope.SCOPED_TARGET_PREFIX + "service",
|
||||
ExampleService.event.getName());
|
||||
}
|
||||
|
||||
public static interface Service {
|
||||
|
||||
String getMessage();
|
||||
|
||||
}
|
||||
|
||||
public static class ExampleService implements Service, InitializingBean,
|
||||
DisposableBean, ApplicationListener<RefreshScopeRefreshedEvent> {
|
||||
|
||||
private static Log logger = LogFactory.getLog(ExampleService.class);
|
||||
|
||||
private volatile static int initCount = 0;
|
||||
private volatile static int destroyCount = 0;
|
||||
private volatile static RefreshScopeRefreshedEvent event;
|
||||
|
||||
private String message = null;
|
||||
private volatile long delay = 0;
|
||||
|
||||
public void setDelay(long delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
logger.debug("Initializing message: " + message);
|
||||
initCount++;
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
logger.debug("Destroying message: " + message);
|
||||
destroyCount++;
|
||||
message = null;
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
initCount = 0;
|
||||
destroyCount = 0;
|
||||
event = null;
|
||||
}
|
||||
|
||||
public static int getInitCount() {
|
||||
return initCount;
|
||||
}
|
||||
|
||||
public static int getDestroyCount() {
|
||||
return destroyCount;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
logger.debug("Setting message: " + message);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
logger.debug("Getting message: " + message);
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
logger.info("Returning message: " + message);
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(RefreshScopeRefreshedEvent e) {
|
||||
event = e;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(TestProperties.class)
|
||||
@Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Autowired
|
||||
private TestProperties properties;
|
||||
|
||||
@Bean
|
||||
@RefreshScope
|
||||
public ExampleService service() {
|
||||
ExampleService service = new ExampleService();
|
||||
service.setMessage(properties.getMessage());
|
||||
service.setDelay(properties.getDelay());
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties
|
||||
@ManagedResource
|
||||
protected static class TestProperties {
|
||||
private String message;
|
||||
private int delay;
|
||||
|
||||
@ManagedAttribute
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
public void setDelay(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.context.scope.refresh;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.cloud.context.environment.EnvironmentManager;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScopeWebIntegrationTests.Application;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
public class RefreshScopeWebIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private org.springframework.cloud.context.scope.refresh.RefreshScope scope;
|
||||
|
||||
@Autowired
|
||||
private EnvironmentManager environmentManager;
|
||||
|
||||
@Autowired
|
||||
private Client application;
|
||||
|
||||
@Autowired
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Test
|
||||
public void scopeOnBeanDefinition() throws Exception {
|
||||
assertEquals("refresh", beanFactory.getBeanDefinition("scopedTarget.application").getScope());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanAccess() throws Exception {
|
||||
application.hello();
|
||||
environmentManager.setProperty("message", "Hello Dave!");
|
||||
scope.refreshAll();
|
||||
String message = application.hello();
|
||||
assertEquals("Hello Dave!", message);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
protected static class Application {
|
||||
|
||||
@Bean
|
||||
@RefreshScope
|
||||
public Client application() {
|
||||
return new Client();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
protected static class Client {
|
||||
|
||||
@Value("${message:Hello World!}")
|
||||
String message;
|
||||
|
||||
@RequestMapping("/")
|
||||
public String hello() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.logging;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class LoggingRebinderTests {
|
||||
|
||||
private LoggingRebinder rebinder = new LoggingRebinder();
|
||||
private Logger logger = LoggerFactory.getLogger("org.springframework.web");
|
||||
|
||||
@After
|
||||
public void reset() {
|
||||
LoggingSystem.get(getClass().getClassLoader()).setLogLevel("org.springframework.web", LogLevel.INFO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logLevelsChanged() {
|
||||
assertFalse(logger.isTraceEnabled());
|
||||
StandardEnvironment environment = new StandardEnvironment();
|
||||
EnvironmentTestUtils.addEnvironment(environment, "logging.level.org.springframework.web=TRACE");
|
||||
rebinder.setEnvironment(environment);
|
||||
rebinder.onApplicationEvent(new EnvironmentChangeEvent(Collections.singleton("logging.level.org.springframework.web")));
|
||||
assertTrue(logger.isTraceEnabled());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user