[bs-17], [bs-146] Add some ApplicationContextInitializers

* One for Cloud Foundry and one for the application context ID
* If app runs in Cloud Foundry vcap.application.* and vcap.services.*
will be populated in the Environment
* The ApplicationContext ID is set to something supposedly unique
(e.g. name:index in a Cloud Foundry app)

[#50968415] [#48153639]
This commit is contained in:
Dave Syer 2013-06-04 16:18:12 +01:00
parent e0d7fc2240
commit e60efc7e55
15 changed files with 813 additions and 4 deletions

View File

@ -40,7 +40,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ClassUtils;
@ -103,8 +102,6 @@ public class ManagementAutoConfiguration implements ApplicationContextAware {
.getPort()) {
AnnotationConfigEmbeddedWebApplicationContext context = new AnnotationConfigEmbeddedWebApplicationContext();
context.setParent(ManagementAutoConfiguration.this.parent);
context.setEnvironment((ConfigurableEnvironment) ManagementAutoConfiguration.this.parent
.getEnvironment());
context.register(assembleConfigClasses(ManagementAutoConfiguration.this.parent));
context.refresh();
ManagementAutoConfiguration.this.context = context;

View File

@ -138,7 +138,7 @@ public class ServiceBootstrapApplicationTests {
@SuppressWarnings("unchecked")
Map<String, Object> body = (Map<String, Object>) entity.getBody().get(0);
assertTrue("Wrong body: " + body,
((String) body.get("context")).startsWith("org.springframework"));
((String) body.get("context")).startsWith("application"));
}
private RestTemplate getRestTemplate() {

View File

@ -39,6 +39,11 @@
<artifactId>snakeyaml</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>

View File

@ -0,0 +1,51 @@
/*
* Copyright 2012-2013 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.bootstrap.config;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author Dave Syer
*
*/
public class JacksonParser implements JsonParser {
@Override
public Map<String, Object> parseMap(String json) {
try {
@SuppressWarnings("unchecked")
Map<String, Object> map = new ObjectMapper().readValue(json, Map.class);
return map;
} catch (Exception e) {
throw new IllegalArgumentException("Cannot parse JSON", e);
}
}
@Override
public List<Object> parseList(String json) {
try {
@SuppressWarnings("unchecked")
List<Object> list = new ObjectMapper().readValue(json, List.class);
return list;
} catch (Exception e) {
throw new IllegalArgumentException("Cannot parse JSON", e);
}
}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2012-2013 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.bootstrap.config;
import java.util.List;
import java.util.Map;
/**
* @author Dave Syer
*
*/
public interface JsonParser {
Map<String, Object> parseMap(String json);
List<Object> parseList(String json);
}

View File

@ -0,0 +1,148 @@
/*
* Copyright 2012-2013 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.bootstrap.config;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* @author Dave Syer
*
*/
public class SimpleJsonParser implements JsonParser {
public static JsonParser instance() {
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
return new YamlParser();
}
if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) {
return new JacksonParser();
}
return new SimpleJsonParser();
}
@Override
public Map<String, Object> parseMap(String json) {
if (json.startsWith("{")) {
return parseMapInternal(json);
} else if (json.trim().equals("")) {
return new HashMap<String, Object>();
}
return null;
}
@Override
public List<Object> parseList(String json) {
if (json.startsWith("[")) {
return parseListInternal(json);
} else if (json.trim().equals("")) {
return new ArrayList<Object>();
}
return null;
}
private List<Object> parseListInternal(String json) {
List<Object> list = new ArrayList<Object>();
json = trimLeadingCharacter(trimTrailingCharacter(json, ']'), '[');
;
for (String value : tokenize(json)) {
list.add(parseInternal(value));
}
return list;
}
private Object parseInternal(String json) {
if (json.startsWith("[")) {
return parseListInternal(json);
}
if (json.startsWith("{")) {
return parseMapInternal(json);
}
if (json.startsWith("\"")) {
return trimTrailingCharacter(trimLeadingCharacter(json, '"'), '"');
}
return json; // TODO: numbers maybe?
}
private static String trimTrailingCharacter(String string, char c) {
if (string.length() >= 0 && string.charAt(string.length() - 1) == c) {
return string.substring(0, string.length() - 1);
}
return string;
}
private static String trimLeadingCharacter(String string, char c) {
if (string.length() >= 0 && string.charAt(0) == c) {
return string.substring(1);
}
return string;
}
private Map<String, Object> parseMapInternal(String json) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
json = trimLeadingCharacter(trimTrailingCharacter(json, '}'), '{');
for (String pair : tokenize(json)) {
String[] values = StringUtils.trimArrayElements(StringUtils.split(pair, ":"));
String key = trimLeadingCharacter(trimTrailingCharacter(values[0], '"'), '"');
Object value = null;
if (values.length > 0) {
String string = trimLeadingCharacter(
trimTrailingCharacter(values[1], '"'), '"');
if (string.startsWith("{") && string.endsWith("}")) {
value = parseInternal(string);
} else {
value = string;
}
}
map.put(key, value);
}
return map;
}
private List<String> tokenize(String json) {
List<String> list = new ArrayList<String>();
int index = 0;
int inObject = 0;
StringBuilder build = new StringBuilder();
while (index < json.length()) {
char current = json.charAt(index);
if (current == '{') {
inObject++;
}
if (current == '}') {
inObject--;
}
if (current == ',' && inObject == 0) {
list.add(build.toString());
build.setLength(0);
} else {
build.append(current);
}
index++;
}
if (build.length() > 0) {
list.add(build.toString());
}
return list;
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2012-2013 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.bootstrap.config;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.Yaml;
/**
* @author Dave Syer
*
*/
public class YamlParser implements JsonParser {
@Override
public Map<String, Object> parseMap(String json) {
@SuppressWarnings("unchecked")
Map<String, Object> map = new Yaml().loadAs(json, Map.class);
return map;
}
@Override
public List<Object> parseList(String json) {
@SuppressWarnings("unchecked")
List<Object> list = new Yaml().loadAs(json, List.class);
return list;
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2010-2012 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.bootstrap.context.initializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils;
/**
*
* @author Dave Syer
*/
public class ContextIdApplicationContextInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
private String name = "${spring.application.name:${vcap.application.name:${spring.config.name:application}}}";
private int index = -1;
private int order = Integer.MAX_VALUE - 10;
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.setId(getApplicationId(applicationContext.getEnvironment()));
}
private String getApplicationId(ConfigurableEnvironment environment) {
String name = environment.resolvePlaceholders(this.name);
int index = environment.getProperty("PORT", Integer.class, this.index);
index = environment.getProperty("vcap.application.instance_index", Integer.class,
index);
index = environment.getProperty("spring.application.index", Integer.class, index);
if (index >= 0) {
name = name + ":" + index;
} else {
String profiles = StringUtils.arrayToCommaDelimitedString(environment
.getActiveProfiles());
if (StringUtils.hasText(profiles)) {
name = name + ":" + profiles;
}
}
return name;
}
}

View File

@ -0,0 +1,200 @@
/*
* Copyright 2010-2012 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.bootstrap.context.initializer;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.springframework.bootstrap.config.JsonParser;
import org.springframework.bootstrap.config.SimpleJsonParser;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.CommandLinePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.util.StringUtils;
/**
* An {@link ApplicationContextInitializer} that knows where to find VCAP (a.k.a. Cloud
* Foundry) meta data in the existing environment. It parses out the VCAP_APPLICATION and
* VCAP_SERVICES meta data and dumps it in a form that is easily consumed by
* {@link Environment} users. If the app is running in Cloud Foundry then both meta data
* items are JSON objects encoded in OS environment variables. VCAP_APPLICATION is a
* shallow hash with basic information about the application (name, instance id, instance
* index, etc.), and VCAP_SERVICES is a hash of lists where the keys are service labels
* and the values are lists of hashes of service instance meta data. Examples are:
*
* <pre>
* VCAP_APPLICATION: {"instance_id":"2ce0ac627a6c8e47e936d829a3a47b5b","instance_index":0,
* "version":"0138c4a6-2a73-416b-aca0-572c09f7ca53","name":"foo",
* "uris":["foo.cfapps.io"], ...}
* VCAP_SERVICES: {"rds-mysql-1.0":[{"name":"mysql","label":"rds-mysql-1.0","plan":"10mb",
* "credentials":{"name":"d04fb13d27d964c62b267bbba1cffb9da","hostname":"mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com",
* "host":"mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com","port":3306,"user":"urpRuqTf8Cpe6",
* "username":"urpRuqTf8Cpe6","password":"pxLsGVpsC9A5S"}
* }]}
* </pre>
*
* These objects are flattened into properties. The VCAP_APPLICATION object goes straight
* to <code>vcap.application.*</code> in a fairly obvious way, and the VCAP_SERVICES
* object is unwrapped so that it is a hash of objects with key equal to the service
* instance name (e.g. "mysql" in the example above), and value equal to that instances
* properties, and then flattened in the smae way. E.g.
*
* <pre>
* vcap.application.instance_id: 2ce0ac627a6c8e47e936d829a3a47b5b
* vcap.application.version: 0138c4a6-2a73-416b-aca0-572c09f7ca53
* vcap.application.name: foo
* vcap.application.uris[0]: foo.cfapps.io
*
* vcap.services.mysql.name: mysql
* vcap.services.mysql.label: rds-mysql-1.0
* vcap.services.mysql.credentials.name: d04fb13d27d964c62b267bbba1cffb9da
* vcap.services.mysql.credentials.port: 3306
* vcap.services.mysql.credentials.host: mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com
* vcap.services.mysql.credentials.username: urpRuqTf8Cpe6
* vcap.services.mysql.credentials.password: pxLsGVpsC9A5S
* ...
* </pre>
*
* @author Dave Syer
*/
public class VcapApplicationContextInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
private static final String VCAP_APPLICATION = "VCAP_APPLICATION";
private static final String VCAP_SERVICES = "VCAP_SERVICES";
private int order = Integer.MIN_VALUE + 11;
private JsonParser parser = SimpleJsonParser.instance();
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
if (!environment.containsProperty(VCAP_APPLICATION)
&& !environment.containsProperty(VCAP_SERVICES)) {
return;
}
Properties properties = new Properties();
addWithPrefix(properties, getPropertiesFromApplication(environment),
"vcap.application.");
addWithPrefix(properties, getPropertiesFromServices(environment),
"vcap.services.");
MutablePropertySources propertySources = environment.getPropertySources();
if (propertySources
.contains(CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME)) {
propertySources.addAfter(
CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME,
new PropertiesPropertySource("vcap", properties));
} else {
propertySources.addFirst(new PropertiesPropertySource("vcap", properties));
}
}
private void addWithPrefix(Properties properties, Properties other, String prefix) {
for (String key : other.stringPropertyNames()) {
String prefixed = prefix + key;
properties.setProperty(prefixed, other.getProperty(key));
}
}
private Properties getPropertiesFromApplication(Environment environment) {
Map<String, Object> map = this.parser.parseMap(environment.getProperty(
VCAP_APPLICATION, "{}"));
Properties properties = new Properties();
properties.putAll(map);
return properties;
}
private Properties getPropertiesFromServices(Environment environment) {
Map<String, Object> map = this.parser.parseMap(environment.getProperty(
VCAP_SERVICES, "{}"));
Properties properties = new Properties();
for (Object services : map.values()) {
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>) services;
for (Object object : list) {
@SuppressWarnings("unchecked")
Map<String, Object> service = (Map<String, Object>) object;
String key = (String) service.get("name");
if (key == null) {
key = (String) service.get("label");
}
flatten(properties, service, key);
}
}
return properties;
}
private void flatten(Properties properties, Map<String, Object> input, String path) {
for (Entry<String, Object> entry : input.entrySet()) {
String key = entry.getKey();
if (StringUtils.hasText(path)) {
if (key.startsWith("[")) {
key = path + key;
} else {
key = path + "." + key;
}
}
Object value = entry.getValue();
if (value instanceof String) {
properties.put(key, value);
} else if (value instanceof Map) {
// Need a compound key
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) value;
flatten(properties, map, key);
} else if (value instanceof Collection) {
// Need a compound key
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) value;
properties.put(key,
StringUtils.collectionToCommaDelimitedString(collection));
int count = 0;
for (Object object : collection) {
flatten(properties,
Collections.singletonMap("[" + (count++) + "]", object), key);
}
} else {
properties.put(key, value == null ? "" : value);
}
}
}
}

View File

@ -13,4 +13,6 @@ org.springframework.bootstrap.autoconfigure.web.WebMvcAutoConfiguration
org.springframework.context.ApplicationContextInitializer=\
org.springframework.bootstrap.context.initializer.ConfigFileApplicationContextInitializer,\
org.springframework.bootstrap.context.initializer.LoggingApplicationContextInitializer,\
org.springframework.bootstrap.context.initializer.VcapApplicationContextInitializer,\
org.springframework.bootstrap.context.initializer.ContextIdApplicationContextInitializer,\
org.springframework.bootstrap.context.initializer.EnvironmentDelegateApplicationContextInitializer

View File

@ -0,0 +1,28 @@
/*
* Copyright 2012-2013 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.bootstrap.config;
/**
* @author Dave Syer
*
*/
public class JacksonParserTests extends SimpleJsonParserTests {
@Override
protected JsonParser getParser() {
return new JacksonParser();
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 2012-2013 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.bootstrap.config;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
*
*/
public class SimpleJsonParserTests {
private JsonParser parser = getParser();
protected JsonParser getParser() {
return new SimpleJsonParser();
}
@Test
public void testSimpleMap() {
Map<String, Object> map = this.parser.parseMap("{\"foo\":\"bar\",\"spam\":1}");
assertEquals(2, map.size());
assertEquals("bar", map.get("foo"));
assertEquals("1", map.get("spam").toString());
}
@Test
public void testEmptyMap() {
Map<String, Object> map = this.parser.parseMap("{}");
assertEquals(0, map.size());
}
@Test
public void testSimpleList() {
List<Object> list = this.parser.parseList("[\"foo\",\"bar\",1]");
assertEquals(3, list.size());
assertEquals("bar", list.get(1));
}
@Test
public void testEmptyList() {
List<Object> list = this.parser.parseList("[]");
assertEquals(0, list.size());
}
@SuppressWarnings("unchecked")
@Test
public void testListOfMaps() {
List<Object> list = this.parser
.parseList("[{\"foo\":\"bar\",\"spam\":1},{\"foo\":\"baz\",\"spam\":2}]");
assertEquals(2, list.size());
assertEquals(2, ((Map<String, Object>) list.get(1)).size());
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2012-2013 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.bootstrap.config;
/**
* @author Dave Syer
*
*/
public class YamlParserTests extends SimpleJsonParserTests {
@Override
protected JsonParser getParser() {
return new YamlParser();
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright 2012-2013 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.bootstrap.context.initializer;
import org.junit.Test;
import org.springframework.bootstrap.TestUtils;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
*
*/
public class ContextIdApplicationContextInitializerTests {
private ContextIdApplicationContextInitializer initializer = new ContextIdApplicationContextInitializer();
@Test
public void testDefaults() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
this.initializer.initialize(context);
assertEquals("application", context.getId());
}
@Test
public void testNameAndPort() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TestUtils.addEnviroment(context, "spring.application.name:foo", "PORT:8080");
this.initializer.initialize(context);
assertEquals("foo:8080", context.getId());
}
@Test
public void testNameAndProfiles() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TestUtils.addEnviroment(context, "spring.application.name:foo",
"spring.profiles.active: spam,bar");
this.initializer.initialize(context);
assertEquals("foo:spam,bar", context.getId());
}
@Test
public void testCloudFoundry() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TestUtils.addEnviroment(context, "spring.config.name:foo", "PORT:8080",
"vcap.application.name:bar", "vcap.application.instance_index:2");
this.initializer.initialize(context);
assertEquals("bar:2", context.getId());
}
@Test
public void testExplicitName() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TestUtils.addEnviroment(context, "spring.application.name:spam",
"spring.config.name:foo", "PORT:8080",
"vcap.application.application_name:bar",
"vcap.application.instance_index:2");
this.initializer.initialize(context);
assertEquals("spam:2", context.getId());
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright 2012-2013 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.bootstrap.context.initializer;
import org.junit.Test;
import org.springframework.bootstrap.TestUtils;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
*
*/
public class VcapApplicationContextInitializerTests {
private VcapApplicationContextInitializer initializer = new VcapApplicationContextInitializer();
@Test
public void testApplicationProperties() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TestUtils
.addEnviroment(
context,
"VCAP_APPLICATION:{\"application_users\":[],\"instance_id\":\"bb7935245adf3e650dfb7c58a06e9ece\",\"instance_index\":0,\"version\":\"3464e092-1c13-462e-a47c-807c30318a50\",\"name\":\"foo\",\"uris\":[\"foo.cfapps.io\"],\"started_at\":\"2013-05-29 02:37:59 +0000\",\"started_at_timestamp\":1369795079,\"host\":\"0.0.0.0\",\"port\":61034,\"limits\":{\"mem\":128,\"disk\":1024,\"fds\":16384},\"version\":\"3464e092-1c13-462e-a47c-807c30318a50\",\"name\":\"dsyerenv\",\"uris\":[\"dsyerenv.cfapps.io\"],\"users\":[],\"start\":\"2013-05-29 02:37:59 +0000\",\"state_timestamp\":1369795079}");
this.initializer.initialize(context);
assertEquals("bb7935245adf3e650dfb7c58a06e9ece", context.getEnvironment()
.getProperty("vcap.application.instance_id"));
}
@Test
public void testServiceProperties() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TestUtils
.addEnviroment(
context,
"VCAP_SERVICES:{\"rds-mysql-n/a\":[{\"name\":\"mysql\",\"label\":\"rds-mysql-n/a\",\"plan\":\"10mb\",\"credentials\":{\"name\":\"d04fb13d27d964c62b267bbba1cffb9da\",\"hostname\":\"mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com\",\"host\":\"mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com\",\"port\":3306,\"user\":\"urpRuqTf8Cpe6\",\"username\":\"urpRuqTf8Cpe6\",\"password\":\"pxLsGVpsC9A5S\"}}]}");
this.initializer.initialize(context);
assertEquals("mysql",
context.getEnvironment().getProperty("vcap.services.mysql.name"));
}
}