diff --git a/etc/ide/eclipse-code-formatter.xml b/etc/ide/eclipse-code-formatter.xml index 6f7bc03..0d7893c 100644 --- a/etc/ide/eclipse-code-formatter.xml +++ b/etc/ide/eclipse-code-formatter.xml @@ -64,7 +64,7 @@ - + diff --git a/pom.xml b/pom.xml index c495785..185893a 100644 --- a/pom.xml +++ b/pom.xml @@ -14,8 +14,9 @@ spring-credhub-dependencies - spring-credhub-core - spring-credhub-demo + spring-credhub-core + spring-credhub-cloud-connector + spring-credhub-demo @@ -304,6 +305,15 @@ + + + spring-libs-snapshot + https://repo.spring.io/libs-snapshot + + true + + + @@ -409,7 +419,8 @@ provided zip - --> + +--> diff --git a/spring-credhub-cloud-connector/pom.xml b/spring-credhub-cloud-connector/pom.xml new file mode 100644 index 0000000..8305b92 --- /dev/null +++ b/spring-credhub-cloud-connector/pom.xml @@ -0,0 +1,72 @@ + + + + + 4.0.0 + + + org.springframework.credhub + spring-credhub-parent + 1.0.0.BUILD-SNAPSHOT + + + spring-credhub-cloud-connector + Spring CredHub Cloud Connector + Spring CredHub Spring Cloud Connectors Support + jar + + + 1.8.9 + + + + + org.springframework + spring-core + + + + org.springframework.credhub + spring-credhub-core + 1.0.0.BUILD-SNAPSHOT + + + + org.springframework.cloud + spring-cloud-cloudfoundry-connector + 1.2.5.BUILD-SNAPSHOT + + + + org.springframework + spring-test + test + + + + junit + junit + test + + + + org.mockito + mockito-core + test + + + diff --git a/spring-credhub-cloud-connector/src/main/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessor.java b/spring-credhub-cloud-connector/src/main/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessor.java new file mode 100644 index 0000000..760b9b6 --- /dev/null +++ b/spring-credhub-cloud-connector/src/main/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessor.java @@ -0,0 +1,109 @@ +/* + * Copyright 2016-2017 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.credhub.cloud; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.springframework.cloud.cloudfoundry.CloudFoundryRawServiceData; +import org.springframework.cloud.cloudfoundry.ServiceDataPostProcessor; +import org.springframework.credhub.configuration.CredHubConfiguration; +import org.springframework.credhub.core.CredHubOperations; +import org.springframework.credhub.support.VcapServicesData; + +/** + * A Spring Cloud Connectors {@link ServiceDataPostProcessor} that post-processes service + * data from {@literal VCAP_SERVICES} using the CredHub {@literal vcap} interpolation API. + * + * @author Scott Frederick + */ +public class CredHubInterpolationServiceDataPostProcessor implements ServiceDataPostProcessor { + private Logger logger = Logger + .getLogger(CredHubInterpolationServiceDataPostProcessor.class.getName()); + + private CredHubOperations credHubOperations; + + /** + * Initialize the service data post-processor. + */ + public CredHubInterpolationServiceDataPostProcessor() { + try { + credHubOperations = new CredHubConfiguration().credHubTemplate(); + } + catch (Exception e) { + logger.log(Level.INFO, "CredHubOperations cannot be initialized, " + + "disabling processing of service data: " + + e.getMessage()); + } + } + + /** + * Initialize the service data post-processor using the provided {@link CredHubOperations}. + * Intended for internal use. + * + * @param credHubOperations the CredHubOperations to use + */ + CredHubInterpolationServiceDataPostProcessor(CredHubOperations credHubOperations) { + this.credHubOperations = credHubOperations; + } + + /** + * Process the provided {@literal serviceData} parsed from {@literal VCAP_SERVICES} by + * Spring Cloud Connectors using the + * {@link CredHubOperations#interpolateServiceData(VcapServicesData)} API. + * + * @param serviceData raw service data parsed from {@literal VCAP_SERVICES} + * @return serviceData with CredHub references replaced by stored credentials + */ + @Override + public CloudFoundryRawServiceData process(CloudFoundryRawServiceData serviceData) { + if (credHubOperations == null) { + return serviceData; + } + + VcapServicesData interpolatedData = credHubOperations + .interpolateServiceData(connectorsToCredHub(serviceData)); + + return credHubToConnectors(interpolatedData); + } + + /** + * Convert from the Spring Cloud Connectors service data structure to the Spring Credhub + * data structure. + * + * @param serviceData the Spring Cloud Connectors data structure + * @return the equivalent Spring CredHub data structure + */ + private VcapServicesData connectorsToCredHub(CloudFoundryRawServiceData serviceData) { + VcapServicesData vcapServicesData = new VcapServicesData(); + vcapServicesData.putAll(serviceData); + return vcapServicesData; + } + + /** + * Convert from the Spring Credhub service data structure to the Spring Cloud Connectors + * data structure. + * + * @param interpolatedData the Spring CredHub data structure + * @return the equivalent Spring Cloud Connectors data structure + */ + private CloudFoundryRawServiceData credHubToConnectors(VcapServicesData interpolatedData) { + CloudFoundryRawServiceData rawServicesData = new CloudFoundryRawServiceData(); + rawServicesData.putAll(interpolatedData); + return rawServicesData; + } +} diff --git a/spring-credhub-cloud-connector/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.ServiceDataPostProcessor b/spring-credhub-cloud-connector/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.ServiceDataPostProcessor new file mode 100644 index 0000000..020ef8c --- /dev/null +++ b/spring-credhub-cloud-connector/src/main/resources/META-INF/services/org.springframework.cloud.cloudfoundry.ServiceDataPostProcessor @@ -0,0 +1 @@ +org.springframework.credhub.cloud.CredHubInterpolationServiceDataPostProcessor \ No newline at end of file diff --git a/spring-credhub-cloud-connector/src/test/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessorTests.java b/spring-credhub-cloud-connector/src/test/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessorTests.java new file mode 100644 index 0000000..f29cd7d --- /dev/null +++ b/spring-credhub-cloud-connector/src/test/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessorTests.java @@ -0,0 +1,145 @@ +/* + * Copyright 2016-2017 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.credhub.cloud; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.cloud.cloudfoundry.CloudFoundryRawServiceData; +import org.springframework.credhub.core.CredHubOperations; +import org.springframework.credhub.support.VcapServicesData; + +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class CredHubInterpolationServiceDataPostProcessorTests { + @Mock + private CredHubOperations credHubOperations; + + @Test + public void processServiceData() { + CloudFoundryRawServiceData rawServiceData = buildRawServiceData(); + VcapServicesData interpolatedServiceData = buildInterpolatedServiceData(); + + when(credHubOperations.interpolateServiceData(argThat(matchesContent(rawServiceData)))) + .thenReturn(interpolatedServiceData); + + CredHubInterpolationServiceDataPostProcessor processor = + new CredHubInterpolationServiceDataPostProcessor(credHubOperations); + + CloudFoundryRawServiceData actual = processor.process(rawServiceData); + assertThat(actual, matchesContent(interpolatedServiceData)); + } + + @Test + public void processServiceDataWithInitializationError() { + CredHubInterpolationServiceDataPostProcessor processor = + new CredHubInterpolationServiceDataPostProcessor(null); + + processor.process(new CloudFoundryRawServiceData()); + + verifyZeroInteractions(credHubOperations); + } + + private ArgumentMatcher matchesContent(final CloudFoundryRawServiceData expected) { + return new ArgumentMatcher() { + @Override + public boolean matches(VcapServicesData actual) { + return mapsAreEquivalent(actual, expected); + } + }; + } + + private Matcher matchesContent(final VcapServicesData expected) { + return new BaseMatcher() { + @Override + public boolean matches(Object actual) { + return mapsAreEquivalent((Map) actual, expected); + } + + @Override + public void describeMismatch(Object item, Description mismatchDescription) { + } + + @Override + public void describeTo(Description description) { + } + }; + } + + private boolean mapsAreEquivalent(Map actual, Map expected) { + return expected.equals(actual); + } + + private CloudFoundryRawServiceData buildRawServiceData() { + HashMap credentials = new HashMap() { + { + put("credhub-ref", + "((/c/service-broker/service-offering/1111-2222-3333-4444/credentials))"); + } + }; + + HashMap>> vcapServices = buildVcapServices(credentials); + + return new CloudFoundryRawServiceData(vcapServices); + } + + private VcapServicesData buildInterpolatedServiceData() { + HashMap credentials = new HashMap() { + { + put("uri", "https://example.com"); + put("username", "user"); + put("password", "secret"); + } + }; + + HashMap>> vcapServices = buildVcapServices(credentials); + + return new VcapServicesData(vcapServices); + } + + private HashMap>> buildVcapServices(final HashMap credentials) { + return new HashMap>>() { + { + put("service-offering", Collections.> singletonList( + new HashMap() { + { + put("credentials", credentials); + put("label", "service-offering"); + put("name", "service-instance"); + put("plan", "standard"); + } + })); + } + }; + } + +} \ No newline at end of file diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CloudFoundryAppInstanceProperties.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CloudFoundryAppInstanceProperties.java index f82285d..d2ebbc2 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CloudFoundryAppInstanceProperties.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CloudFoundryAppInstanceProperties.java @@ -35,6 +35,13 @@ public class CloudFoundryAppInstanceProperties { * Create a new instance without initializing properties. */ public CloudFoundryAppInstanceProperties() { + if (instanceCertLocation == null) { + instanceCertLocation = System.getenv("CF_INSTANCE_CERT"); + } + + if (instanceKeyLocation == null) { + instanceKeyLocation = System.getenv("CF_INSTANCE_KEY"); + } } /** diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubOperations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubOperations.java index 4ce3eed..dba984c 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubOperations.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubOperations.java @@ -17,11 +17,11 @@ package org.springframework.credhub.core; import java.util.List; -import java.util.Map; import org.springframework.credhub.support.CredentialDetails; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.CredentialSummary; +import org.springframework.credhub.support.VcapServicesData; import org.springframework.credhub.support.WriteRequest; import org.springframework.web.client.RestTemplate; @@ -167,7 +167,7 @@ public interface CredHubOperations { * @return the serviceData structure with CredHub references replaced by stored * credential values */ - Map interpolateServiceData(Map serviceData); + VcapServicesData interpolateServiceData(VcapServicesData serviceData); /** * Allow interaction with the configured {@link RestTemplate} not provided diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubProperties.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubProperties.java index 1f205b8..6b90761 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubProperties.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubProperties.java @@ -33,6 +33,9 @@ public class CredHubProperties { * Create a new instance without initializing properties. */ public CredHubProperties() { + if (apiUriBase == null) { + apiUriBase = System.getenv("CREDHUB_API"); + } } /** diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java index ad10050..995ab6e 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java @@ -26,6 +26,7 @@ import org.springframework.credhub.support.CredentialDetailsData; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.CredentialSummary; import org.springframework.credhub.support.CredentialSummaryData; +import org.springframework.credhub.support.VcapServicesData; import org.springframework.credhub.support.WriteRequest; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; @@ -214,17 +215,17 @@ public class CredHubTemplate implements CredHubOperations { } @Override - public Map interpolateServiceData(final Map serviceData) { + public VcapServicesData interpolateServiceData(final VcapServicesData serviceData) { Assert.notNull(serviceData, "serviceData must not be null"); - return doWithRest(new RestOperationsCallback>() { + return doWithRest(new RestOperationsCallback() { @Override - public Map doWithRestOperations(RestOperations restOperations) { - Map> wrappedServiceData = wrapServiceDataRequest(serviceData); + public VcapServicesData doWithRestOperations(RestOperations restOperations) { + Map wrappedServiceData = wrapServiceDataRequest(serviceData); - ResponseEntity>> response = restOperations + ResponseEntity> response = restOperations .exchange(INTERPOLATE_URL_PATH, HttpMethod.POST, - new HttpEntity>>(wrappedServiceData), mapType()); + new HttpEntity>(wrappedServiceData), mapType()); throwExceptionOnError(response); @@ -252,8 +253,8 @@ public class CredHubTemplate implements CredHubOperations { * @param serviceData a {@literal Map} of services details * @return the provided {@literal serviceData} structure wrapped with the "VCAP_SERVICES" key */ - private Map> wrapServiceDataRequest(Map serviceData) { - Map> wrappedServiceData = new HashMap>(); + private Map wrapServiceDataRequest(VcapServicesData serviceData) { + Map wrappedServiceData = new HashMap(); wrappedServiceData.put(VCAP_SERVICES_KEY, serviceData); return wrappedServiceData; } @@ -263,8 +264,8 @@ public class CredHubTemplate implements CredHubOperations { * * @return the type reference for a {@literal Map} type */ - private ParameterizedTypeReference>> mapType() { - return new ParameterizedTypeReference>>() {}; + private ParameterizedTypeReference> mapType() { + return new ParameterizedTypeReference>() {}; } /** diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/support/VcapServicesData.java b/spring-credhub-core/src/main/java/org/springframework/credhub/support/VcapServicesData.java new file mode 100644 index 0000000..7583ef2 --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/support/VcapServicesData.java @@ -0,0 +1,106 @@ +/* + * Copyright 2016-2017 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.credhub.support; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Service data parsed from the {@literal VCAP_SERVICES} environment variable provided to applications + * running on Cloud Foundry. + * + * If the {@literal VCAP_SERVICES} environment variable for an application contains the following: + * + *
+ * {@code
+ * "VCAP_SERVICES": {
+ *   "mysql": [
+ *     {
+ *       "label": "mysql",
+ *       "name": "mysql-db",
+ *       "plan": "100mb",
+ *       "tags": [ "mysql", "relational" ],
+ *       "credentials": {
+ *         "jdbcUrl": "jdbc:mysql://mysql-broker:3306/db?user=username\u0026password=password",
+ *         "uri": "mysql://username:password@mysql-broker:3306/db?reconnect=true",
+ *       }
+ *     }
+ *   ],
+ *   "rabbitmq": [
+ *     {
+ *       "label": "rabbitmq",
+ *       "name": "rabbit-queue",
+ *       "plan": "standard",
+ *       "tags": [ "rabbitmq", "messaging" ],
+ *       "credentials": {
+ *         "http_api_uri": "http://username:password@rabbitmq-broker:12345/api",
+ *         "uri": "amqp://username:password@rabbitmq-broker/vhost",
+ *       }
+ *     }
+ *   ]
+ * }
+ * }
+ * 
+ * + * Then the {@link VcapServicesData} data structure would expect to the equivalent of this JSON document: + * + *
+ * {@code
+ * {
+ *   "mysql": [
+ *     {
+ *       "label": "mysql",
+ *       "name": "mysql-db",
+ *       "plan": "100mb",
+ *       "tags": [ "mysql", "relational" ],
+ *       "credentials": {
+ *         "jdbcUrl": "jdbc:mysql://mysql-broker:3306/db?user=username\u0026password=password",
+ *         "uri": "mysql://username:password@mysql-broker:3306/db?reconnect=true",
+ *       }
+ *     }
+ *   ]
+ *   "rabbitmq": [
+ *     {
+ *       "label": "rabbitmq",
+ *       "name": "rabbit-queue",
+ *       "plan": "standard",
+ *       "tags": [ "rabbitmq", "messaging" ],
+ *       "credentials": {
+ *         "http_api_uri": "http://username:password@rabbitmq-broker:12345/api",
+ *         "uri": "amqp://username:password@rabbitmq-broker/vhost",
+ *       }
+ *     }
+ *   ]
+ * }
+ * }
+ * 
+ * + */ +public class VcapServicesData extends HashMap>> { + public VcapServicesData() { + } + + /** + * Initialize with the provided {@link HashMap}. + * + * @param vcapServices a {@literal HashMap} to initialize this data structure from + */ + public VcapServicesData(HashMap>> vcapServices) { + super(vcapServices); + } +} diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTests.java index b4fd07a..2cfdbf3 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTests.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTests.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; -import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,6 +27,7 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.core.ParameterizedTypeReference; import org.springframework.credhub.support.ServiceInstanceCredentialName; +import org.springframework.credhub.support.VcapServicesData; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; @@ -59,24 +59,24 @@ public class CredHubTemplateUnitTests extends CredHubTemplateUnitTestsBase { .credentialName("credential_json") .build(); - Map request = buildVcap(credentialName.getName()); - Map> wrappedRequest = wrapVcap(request); + VcapServicesData vcapServices = buildVcapServices(credentialName.getName()); + Map wrappedVcapServices = wrapVcapServices(vcapServices); - Map> expectedResponse = new HashMap>(); + Map expectedResponse = new HashMap(); - ParameterizedTypeReference>> type = - new ParameterizedTypeReference>>() {}; + ParameterizedTypeReference> type = + new ParameterizedTypeReference>() {}; when(restTemplate.exchange(INTERPOLATE_URL_PATH, HttpMethod.POST, - new HttpEntity>>(wrappedRequest), type)) - .thenReturn(new ResponseEntity>>(expectedResponse, OK)); + new HttpEntity>(wrappedVcapServices), type)) + .thenReturn(new ResponseEntity>(expectedResponse, OK)); - Map response = credHubTemplate.interpolateServiceData(request); + VcapServicesData response = credHubTemplate.interpolateServiceData(vcapServices); assertThat(response, equalTo(expectedResponse.get(VCAP_SERVICES_KEY))); } - private Map buildVcap(String credHubReferenceName) throws IOException { + private VcapServicesData buildVcapServices(String credHubReferenceName) throws IOException { String vcapServices = "{" + " \"service-offering\": [" + " {" + @@ -95,11 +95,11 @@ public class CredHubTemplateUnitTests extends CredHubTemplateUnitTestsBase { "}"; ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(vcapServices, new TypeReference>() {}); + return mapper.readValue(vcapServices, VcapServicesData.class); } - private Map> wrapVcap(final Map serviceData) { - return new HashMap>() {{ + private HashMap wrapVcapServices(final VcapServicesData serviceData) { + return new HashMap() {{ put(VCAP_SERVICES_KEY, serviceData); }}; } diff --git a/spring-credhub-demo/src/main/java/org/springframework/credhub/demo/CredHubDemoController.java b/spring-credhub-demo/src/main/java/org/springframework/credhub/demo/CredHubDemoController.java index c66bc4a..63c1003 100644 --- a/spring-credhub-demo/src/main/java/org/springframework/credhub/demo/CredHubDemoController.java +++ b/spring-credhub-demo/src/main/java/org/springframework/credhub/demo/CredHubDemoController.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Value; import org.springframework.credhub.core.CredHubTemplate; @@ -31,6 +30,7 @@ import org.springframework.credhub.support.CredentialDetails; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.CredentialSummary; import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.VcapServicesData; import org.springframework.credhub.support.WriteRequest; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PostMapping; @@ -136,8 +136,8 @@ public class CredHubDemoController { private void interpolateServiceData(CredentialName name, Results results) { try { - Map request = buildVcapServicesData(name.getName()); - Map interpolatedServiceData = credHubTemplate.interpolateServiceData(request); + VcapServicesData request = buildVcapServicesData(name.getName()); + VcapServicesData interpolatedServiceData = credHubTemplate.interpolateServiceData(request); saveResults(results, "Successfully interpolated service data: ", interpolatedServiceData); } catch (Exception e) { saveResults(results, "Error interpolating service data: ", e.getMessage()); @@ -153,7 +153,7 @@ public class CredHubDemoController { } } - private Map buildVcapServicesData(String credHubReferenceName) throws IOException { + private VcapServicesData buildVcapServicesData(String credHubReferenceName) throws IOException { String vcapServices = "{" + " \"service-offering\": [" + " {" + @@ -172,7 +172,7 @@ public class CredHubDemoController { "}"; ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(vcapServices, new TypeReference>() {}); + return mapper.readValue(vcapServices, VcapServicesData.class); } private void saveResults(Results results, String message) {