From 147755f396cad20c393e6b7a491416b2fac8fbb3 Mon Sep 17 00:00:00 2001 From: Ben Hale Date: Tue, 24 Mar 2015 15:55:25 +0000 Subject: [PATCH 1/2] Support VcapApplicationListener Number Credentials Update VcapApplicationListener to support Number based credentials. Previously, any service credential value that wasn't a String would be discarded. This was particularly a problem for services that exposed a port as a JSON Number. This change takes numbers in the credential payload into account, converting them to Strings so that they will pass through the properties system properly. There's no real downside to this as Spring will coerce them back into Numbers if needed by an application. Fixes gh-2707 --- .../boot/cloudfoundry/VcapApplicationListener.java | 5 ++++- .../cloudfoundry/VcapApplicationListenerTests.java | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/cloudfoundry/VcapApplicationListener.java b/spring-boot/src/main/java/org/springframework/boot/cloudfoundry/VcapApplicationListener.java index 72cff54bfed..3635f71d884 100644 --- a/spring-boot/src/main/java/org/springframework/boot/cloudfoundry/VcapApplicationListener.java +++ b/spring-boot/src/main/java/org/springframework/boot/cloudfoundry/VcapApplicationListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2014 the original author or authors. + * Copyright 2010-2015 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. @@ -213,6 +213,9 @@ public class VcapApplicationListener implements if (value instanceof String) { properties.put(key, value); } + else if (value instanceof Number) { + properties.put(key, value.toString()); + } else if (value instanceof Map) { // Need a compound key @SuppressWarnings("unchecked") diff --git a/spring-boot/src/test/java/org/springframework/boot/cloudfoundry/VcapApplicationListenerTests.java b/spring-boot/src/test/java/org/springframework/boot/cloudfoundry/VcapApplicationListenerTests.java index 6cce6e7685a..d0a0675d4fb 100644 --- a/spring-boot/src/test/java/org/springframework/boot/cloudfoundry/VcapApplicationListenerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/cloudfoundry/VcapApplicationListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -75,6 +75,10 @@ public class VcapApplicationListenerTests { this.initializer.onApplicationEvent(this.event); assertEquals("mysql", this.context.getEnvironment().getProperty("vcap.services.mysql.name")); + assertEquals( + "3306", + this.context.getEnvironment().getProperty( + "vcap.services.mysql.credentials.port")); } @Test @@ -86,5 +90,9 @@ public class VcapApplicationListenerTests { this.initializer.onApplicationEvent(this.event); assertEquals("mysql", this.context.getEnvironment().getProperty("vcap.services.mysql.name")); + assertEquals( + "3306", + this.context.getEnvironment().getProperty( + "vcap.services.mysql.credentials.port")); } } From 4d8cf7149658d7c4028b17c4c6cb5e6d25f18ed7 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 24 Mar 2015 13:38:16 -0700 Subject: [PATCH 2/2] Polish VcapApplicationListenerTests --- .../VcapApplicationListenerTests.java | 70 ++++++++++++++----- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/spring-boot/src/test/java/org/springframework/boot/cloudfoundry/VcapApplicationListenerTests.java b/spring-boot/src/test/java/org/springframework/boot/cloudfoundry/VcapApplicationListenerTests.java index d0a0675d4fb..2cc7025304a 100644 --- a/spring-boot/src/test/java/org/springframework/boot/cloudfoundry/VcapApplicationListenerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/cloudfoundry/VcapApplicationListenerTests.java @@ -34,7 +34,9 @@ import static org.junit.Assert.assertNull; public class VcapApplicationListenerTests { private final VcapApplicationListener initializer = new VcapApplicationListener(); + private final ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); + private final ApplicationEnvironmentPreparedEvent event = new ApplicationEnvironmentPreparedEvent( new SpringApplication(), new String[0], this.context.getEnvironment()); @@ -43,7 +45,18 @@ public class VcapApplicationListenerTests { EnvironmentTestUtils .addEnvironment( this.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}"); + "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.onApplicationEvent(this.event); assertEquals("bb7935245adf3e650dfb7c58a06e9ece", this.context.getEnvironment() .getProperty("vcap.application.instance_id")); @@ -53,7 +66,7 @@ public class VcapApplicationListenerTests { public void testUnparseableApplicationProperties() { EnvironmentTestUtils.addEnvironment(this.context, "VCAP_APPLICATION:"); this.initializer.onApplicationEvent(this.event); - assertNull(this.context.getEnvironment().getProperty("vcap")); + assertNull(getProperty("vcap")); } @Test @@ -61,9 +74,20 @@ public class VcapApplicationListenerTests { EnvironmentTestUtils .addEnvironment( this.context, - "VCAP_APPLICATION:{\"application_users\":null,\"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}"); + "VCAP_APPLICATION:{\"application_users\":null," + + "\"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.onApplicationEvent(this.event); - assertNull(this.context.getEnvironment().getProperty("vcap")); + assertNull(getProperty("vcap")); } @Test @@ -71,14 +95,17 @@ public class VcapApplicationListenerTests { EnvironmentTestUtils .addEnvironment( this.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\"}}]}"); + "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.onApplicationEvent(this.event); - assertEquals("mysql", - this.context.getEnvironment().getProperty("vcap.services.mysql.name")); - assertEquals( - "3306", - this.context.getEnvironment().getProperty( - "vcap.services.mysql.credentials.port")); + assertEquals("mysql", getProperty("vcap.services.mysql.name")); + assertEquals("3306", getProperty("vcap.services.mysql.credentials.port")); } @Test @@ -86,13 +113,20 @@ public class VcapApplicationListenerTests { EnvironmentTestUtils .addEnvironment( this.context, - "VCAP_SERVICES:{\"rds-mysql\":[{\"name\":\"mysql\",\"label\":\"rds-mysql\",\"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\"}}]}"); + "VCAP_SERVICES:{\"rds-mysql\":[{" + + "\"name\":\"mysql\",\"label\":\"rds-mysql\",\"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.onApplicationEvent(this.event); - assertEquals("mysql", - this.context.getEnvironment().getProperty("vcap.services.mysql.name")); - assertEquals( - "3306", - this.context.getEnvironment().getProperty( - "vcap.services.mysql.credentials.port")); + assertEquals("mysql", getProperty("vcap.services.mysql.name")); + assertEquals("3306", getProperty("vcap.services.mysql.credentials.port")); + } + + private String getProperty(String key) { + return this.context.getEnvironment().getProperty(key); } }