Change the name of the interpolation endpoint. Remove wrapping of service data with a 'VCAP_SERVICES' key in the interpolation implementation.

This commit is contained in:
Scott Frederick
2017-06-09 17:02:12 -05:00
parent 578f3b635d
commit 6bc39c2ad7
7 changed files with 54 additions and 124 deletions

View File

@@ -23,11 +23,11 @@ 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;
import org.springframework.credhub.support.ServicesData;
/**
* A Spring Cloud Connectors {@link ServiceDataPostProcessor} that post-processes service
* data from {@literal VCAP_SERVICES} using the CredHub {@literal vcap} interpolation API.
* data from {@literal VCAP_SERVICES} using the CredHub interpolation API.
*
* @author Scott Frederick
*/
@@ -63,7 +63,7 @@ public class CredHubInterpolationServiceDataPostProcessor implements ServiceData
/**
* Process the provided {@literal serviceData} parsed from {@literal VCAP_SERVICES} by
* Spring Cloud Connectors using the
* {@link CredHubOperations#interpolateServiceData(VcapServicesData)} API.
* {@link CredHubOperations#interpolateServiceData(ServicesData)} API.
*
* @param serviceData raw service data parsed from {@literal VCAP_SERVICES}
* @return serviceData with CredHub references replaced by stored credentials
@@ -75,7 +75,7 @@ public class CredHubInterpolationServiceDataPostProcessor implements ServiceData
}
try {
VcapServicesData interpolatedData = credHubOperations
ServicesData interpolatedData = credHubOperations
.interpolateServiceData(connectorsToCredHub(serviceData));
return credHubToConnectors(interpolatedData);
@@ -89,13 +89,13 @@ public class CredHubInterpolationServiceDataPostProcessor implements ServiceData
* Convert from the Spring Cloud Connectors service data structure to the Spring Credhub
* data structure.
*
* @param serviceData the Spring Cloud Connectors data structure
* @param rawServiceData 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;
private ServicesData connectorsToCredHub(CloudFoundryRawServiceData rawServiceData) {
ServicesData servicesData = new ServicesData();
servicesData.putAll(rawServiceData);
return servicesData;
}
/**
@@ -105,7 +105,7 @@ public class CredHubInterpolationServiceDataPostProcessor implements ServiceData
* @param interpolatedData the Spring CredHub data structure
* @return the equivalent Spring Cloud Connectors data structure
*/
private CloudFoundryRawServiceData credHubToConnectors(VcapServicesData interpolatedData) {
private CloudFoundryRawServiceData credHubToConnectors(ServicesData interpolatedData) {
CloudFoundryRawServiceData rawServicesData = new CloudFoundryRawServiceData();
rawServicesData.putAll(interpolatedData);
return rawServicesData;

View File

@@ -33,7 +33,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.cloud.cloudfoundry.CloudFoundryRawServiceData;
import org.springframework.credhub.core.CredHubException;
import org.springframework.credhub.core.CredHubOperations;
import org.springframework.credhub.support.VcapServicesData;
import org.springframework.credhub.support.ServicesData;
import org.springframework.http.HttpStatus;
import static org.hamcrest.core.IsEqual.equalTo;
@@ -50,7 +50,7 @@ public class CredHubInterpolationServiceDataPostProcessorTests {
@Test
public void processServiceData() {
CloudFoundryRawServiceData rawServiceData = buildRawServiceData();
VcapServicesData interpolatedServiceData = buildInterpolatedServiceData();
ServicesData interpolatedServiceData = buildInterpolatedServiceData();
when(credHubOperations.interpolateServiceData(argThat(matchesContent(rawServiceData))))
.thenReturn(interpolatedServiceData);
@@ -86,16 +86,16 @@ public class CredHubInterpolationServiceDataPostProcessorTests {
verifyZeroInteractions(credHubOperations);
}
private ArgumentMatcher<VcapServicesData> matchesContent(final CloudFoundryRawServiceData expected) {
return new ArgumentMatcher<VcapServicesData>() {
private ArgumentMatcher<ServicesData> matchesContent(final CloudFoundryRawServiceData expected) {
return new ArgumentMatcher<ServicesData>() {
@Override
public boolean matches(VcapServicesData actual) {
public boolean matches(ServicesData actual) {
return mapsAreEquivalent(actual, expected);
}
};
}
private Matcher<CloudFoundryRawServiceData> matchesContent(final VcapServicesData expected) {
private Matcher<CloudFoundryRawServiceData> matchesContent(final ServicesData expected) {
return new BaseMatcher<CloudFoundryRawServiceData>() {
@Override
@SuppressWarnings("unchecked")
@@ -125,12 +125,12 @@ public class CredHubInterpolationServiceDataPostProcessorTests {
}
};
HashMap<String, List<Map<String, Object>>> vcapServices = buildVcapServices(credentials);
HashMap<String, List<Map<String, Object>>> rawServiceData = buildRawServiceData(credentials);
return new CloudFoundryRawServiceData(vcapServices);
return new CloudFoundryRawServiceData(rawServiceData);
}
private VcapServicesData buildInterpolatedServiceData() {
private ServicesData buildInterpolatedServiceData() {
HashMap<String, String> credentials = new HashMap<String, String>() {
{
put("uri", "https://example.com");
@@ -139,12 +139,12 @@ public class CredHubInterpolationServiceDataPostProcessorTests {
}
};
HashMap<String, List<Map<String, Object>>> vcapServices = buildVcapServices(credentials);
HashMap<String, List<Map<String, Object>>> rawServiceData = buildRawServiceData(credentials);
return new VcapServicesData(vcapServices);
return new ServicesData(rawServiceData);
}
private HashMap<String, List<Map<String, Object>>> buildVcapServices(final HashMap<String, String> credentials) {
private HashMap<String, List<Map<String, Object>>> buildRawServiceData(final HashMap<String, String> credentials) {
return new HashMap<String, List<Map<String, Object>>>() {
{
put("service-offering", Collections.<Map<String, Object>> singletonList(

View File

@@ -22,7 +22,7 @@ import org.springframework.credhub.support.CredentialDetails;
import org.springframework.credhub.support.CredentialName;
import org.springframework.credhub.support.CredentialSummary;
import org.springframework.credhub.support.ParametersRequest;
import org.springframework.credhub.support.VcapServicesData;
import org.springframework.credhub.support.ServicesData;
import org.springframework.credhub.support.CredentialRequest;
import org.springframework.web.client.RestTemplate;
@@ -179,7 +179,7 @@ public interface CredHubOperations {
* @return the serviceData structure with CredHub references replaced by stored
* credential values
*/
VcapServicesData interpolateServiceData(VcapServicesData serviceData);
ServicesData interpolateServiceData(ServicesData serviceData);
/**
* Allow interaction with the configured {@link RestTemplate} not provided

View File

@@ -16,9 +16,7 @@
package org.springframework.credhub.core;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.credhub.support.CredentialDetails;
@@ -27,7 +25,7 @@ import org.springframework.credhub.support.CredentialName;
import org.springframework.credhub.support.CredentialSummary;
import org.springframework.credhub.support.CredentialSummaryData;
import org.springframework.credhub.support.ParametersRequest;
import org.springframework.credhub.support.VcapServicesData;
import org.springframework.credhub.support.ServicesData;
import org.springframework.credhub.support.CredentialRequest;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
@@ -54,7 +52,7 @@ public class CredHubTemplate implements CredHubOperations {
static final String NAME_URL_QUERY = BASE_URL_PATH + "?name={name}";
static final String NAME_LIKE_URL_QUERY = BASE_URL_PATH + "?name-like={name}";
static final String PATH_URL_QUERY = BASE_URL_PATH + "?path={path}";
static final String INTERPOLATE_URL_PATH = "/api/v1/vcap";
static final String INTERPOLATE_URL_PATH = "/api/v1/interpolate";
static final String VCAP_SERVICES_KEY = "VCAP_SERVICES";
@@ -250,21 +248,19 @@ public class CredHubTemplate implements CredHubOperations {
}
@Override
public VcapServicesData interpolateServiceData(final VcapServicesData serviceData) {
public ServicesData interpolateServiceData(final ServicesData serviceData) {
Assert.notNull(serviceData, "serviceData must not be null");
return doWithRest(new RestOperationsCallback<VcapServicesData>() {
return doWithRest(new RestOperationsCallback<ServicesData>() {
@Override
public VcapServicesData doWithRestOperations(RestOperations restOperations) {
Map<String, VcapServicesData> wrappedServiceData = wrapServiceDataRequest(serviceData);
ResponseEntity<Map<String, VcapServicesData>> response = restOperations
public ServicesData doWithRestOperations(RestOperations restOperations) {
ResponseEntity<ServicesData> response = restOperations
.exchange(INTERPOLATE_URL_PATH, POST,
new HttpEntity<Map<String, VcapServicesData>>(wrappedServiceData), mapType());
new HttpEntity<ServicesData>(serviceData), ServicesData.class);
throwExceptionOnError(response);
return response.getBody().get(VCAP_SERVICES_KEY);
return response.getBody();
}
});
}
@@ -281,28 +277,6 @@ public class CredHubTemplate implements CredHubOperations {
}
}
/**
* Wrap the service data structure with the "VCAP_SERVICES" key as required by the
* CredHub interpolation API.
*
* @param serviceData a {@literal Map} of services details
* @return the provided {@literal serviceData} structure wrapped with the "VCAP_SERVICES" key
*/
private Map<String, VcapServicesData> wrapServiceDataRequest(VcapServicesData serviceData) {
Map<String, VcapServicesData> wrappedServiceData = new HashMap<String, VcapServicesData>();
wrappedServiceData.put(VCAP_SERVICES_KEY, serviceData);
return wrappedServiceData;
}
/**
* Helper method to create a type reference for use by {@link RestTemplate}.
*
* @return the type reference for a {@literal Map} type
*/
private ParameterizedTypeReference<Map<String, VcapServicesData>> mapType() {
return new ParameterizedTypeReference<Map<String, VcapServicesData>>() {};
}
/**
* Helper method to throw an appropriate exception if a request to CredHub
* returns with an error code.

View File

@@ -28,7 +28,7 @@ import java.util.Map;
*
* <pre>
* {@code
* "VCAP_SERVICES": {
* {
* "mysql": [
* {
* "label": "mysql",
@@ -57,50 +57,19 @@ import java.util.Map;
* }
* </pre>
*
* Then the {@link VcapServicesData} data structure would expect to the equivalent of this JSON document:
*
* <pre>
* {@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",
* }
* }
* ]
* }
* }
* </pre>
*
* Then the {@link ServicesData} data structure would hold the equivalent of this JSON structure parsed
* to a {@literal Map}.
*/
public class VcapServicesData extends HashMap<String, List<Map<String, Object>>> {
public VcapServicesData() {
public class ServicesData extends HashMap<String, List<Map<String, Object>>> {
public ServicesData() {
}
/**
* Initialize with the provided {@link HashMap}.
*
* @param vcapServices a {@literal HashMap} to initialize this data structure from
* @param data a {@literal HashMap} to initialize this data structure from
*/
public VcapServicesData(HashMap<String, List<Map<String, Object>>> vcapServices) {
super(vcapServices);
public ServicesData(HashMap<String, List<Map<String, Object>>> data) {
super(data);
}
}

View File

@@ -17,18 +17,15 @@
package org.springframework.credhub.core;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.credhub.support.JsonUtils;
import org.springframework.credhub.support.ServiceInstanceCredentialName;
import org.springframework.credhub.support.VcapServicesData;
import org.springframework.credhub.support.ServicesData;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
@@ -39,7 +36,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.credhub.core.CredHubTemplate.INTERPOLATE_URL_PATH;
import static org.springframework.credhub.core.CredHubTemplate.NAME_URL_QUERY;
import static org.springframework.credhub.core.CredHubTemplate.VCAP_SERVICES_KEY;
import static org.springframework.http.HttpStatus.OK;
@RunWith(MockitoJUnitRunner.class)
@@ -60,24 +56,20 @@ public class CredHubTemplateUnitTests extends CredHubTemplateUnitTestsBase {
.credentialName("credential_json")
.build();
VcapServicesData vcapServices = buildVcapServices(credentialName.getName());
Map<String, VcapServicesData> wrappedVcapServices = wrapVcapServices(vcapServices);
ServicesData vcapServices = buildVcapServices(credentialName.getName());
Map<String, VcapServicesData> expectedResponse = new HashMap<String, VcapServicesData>();
ParameterizedTypeReference<Map<String, VcapServicesData>> type =
new ParameterizedTypeReference<Map<String, VcapServicesData>>() {};
ServicesData expectedResponse = new ServicesData();
when(restTemplate.exchange(INTERPOLATE_URL_PATH, HttpMethod.POST,
new HttpEntity<Map<String, VcapServicesData>>(wrappedVcapServices), type))
.thenReturn(new ResponseEntity<Map<String, VcapServicesData>>(expectedResponse, OK));
new HttpEntity<ServicesData>(vcapServices), ServicesData.class))
.thenReturn(new ResponseEntity<ServicesData>(expectedResponse, OK));
VcapServicesData response = credHubTemplate.interpolateServiceData(vcapServices);
ServicesData response = credHubTemplate.interpolateServiceData(vcapServices);
assertThat(response, equalTo(expectedResponse.get(VCAP_SERVICES_KEY)));
assertThat(response, equalTo(expectedResponse));
}
private VcapServicesData buildVcapServices(String credHubReferenceName) throws IOException {
private ServicesData buildVcapServices(String credHubReferenceName) throws IOException {
String vcapServices = "{" +
" \"service-offering\": [" +
" {" +
@@ -96,12 +88,7 @@ public class CredHubTemplateUnitTests extends CredHubTemplateUnitTestsBase {
"}";
ObjectMapper mapper = JsonUtils.buildObjectMapper();
return mapper.readValue(vcapServices, VcapServicesData.class);
return mapper.readValue(vcapServices, ServicesData.class);
}
private HashMap<String, VcapServicesData> wrapVcapServices(final VcapServicesData serviceData) {
return new HashMap<String, VcapServicesData>() {{
put(VCAP_SERVICES_KEY, serviceData);
}};
}
}

View File

@@ -33,7 +33,7 @@ import org.springframework.credhub.support.CredentialSummary;
import org.springframework.credhub.support.json.JsonCredential;
import org.springframework.credhub.support.json.JsonCredentialRequest;
import org.springframework.credhub.support.SimpleCredentialName;
import org.springframework.credhub.support.VcapServicesData;
import org.springframework.credhub.support.ServicesData;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@@ -140,8 +140,8 @@ public class CredHubDemoController {
private void interpolateServiceData(CredentialName name, Results results) {
try {
VcapServicesData request = buildVcapServicesData(name.getName());
VcapServicesData interpolatedServiceData = credHubTemplate.interpolateServiceData(request);
ServicesData request = buildServicesData(name.getName());
ServicesData interpolatedServiceData = credHubTemplate.interpolateServiceData(request);
saveResults(results, "Successfully interpolated service data: ", interpolatedServiceData);
} catch (Exception e) {
saveResults(results, "Error interpolating service data: ", e.getMessage());
@@ -157,7 +157,7 @@ public class CredHubDemoController {
}
}
private VcapServicesData buildVcapServicesData(String credHubReferenceName) throws IOException {
private ServicesData buildServicesData(String credHubReferenceName) throws IOException {
String vcapServices = "{" +
" \"service-offering\": [" +
" {" +
@@ -176,7 +176,7 @@ public class CredHubDemoController {
"}";
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(vcapServices, VcapServicesData.class);
return mapper.readValue(vcapServices, ServicesData.class);
}
private void saveResults(Results results, String message) {