Support Spring Boot autoconfiguration

- Added spring-credhub-starter project
- Updated demo app with spring-credhub-starter

[Closes #23]
This commit is contained in:
Daniel Lavoie
2017-11-03 08:02:00 -04:00
parent 86ba84f419
commit 0446b8f096
12 changed files with 205 additions and 80 deletions

View File

@@ -30,6 +30,7 @@ buildscript {
ext {
springVersion = "4.3.8.RELEASE"
springBootVersion = "1.5.6.RELEASE"
junitVersion = "4.12"
mockitoVersion = "2.7.22"

View File

@@ -2,6 +2,8 @@ rootProject.name = 'spring-credhub'
include ':spring-credhub-core'
include ':spring-credhub-cloud-connector'
include ':spring-credhub-starter'
project(':spring-credhub-core').projectDir = "$rootDir/spring-credhub-core" as File
project(':spring-credhub-cloud-connector').projectDir = "$rootDir/spring-credhub-cloud-connector" as File
project(':spring-credhub-starter').projectDir = "$rootDir/spring-credhub-starter" as File

View File

@@ -21,8 +21,9 @@ 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.configuration.CredHubTemplateFactory;
import org.springframework.credhub.core.CredHubOperations;
import org.springframework.credhub.core.CredHubProperties;
import org.springframework.credhub.support.ServicesData;
/**
@@ -30,8 +31,10 @@ import org.springframework.credhub.support.ServicesData;
* data from {@literal VCAP_SERVICES} using the CredHub interpolation API.
*
* @author Scott Frederick
* @author Daniel Lavoie
*/
public class CredHubInterpolationServiceDataPostProcessor implements ServiceDataPostProcessor {
public class CredHubInterpolationServiceDataPostProcessor
implements ServiceDataPostProcessor {
private Logger logger = Logger
.getLogger(CredHubInterpolationServiceDataPostProcessor.class.getName());
@@ -42,17 +45,31 @@ public class CredHubInterpolationServiceDataPostProcessor implements ServiceData
*/
public CredHubInterpolationServiceDataPostProcessor() {
try {
credHubOperations = new CredHubConfiguration().credHubTemplate();
CredHubTemplateFactory credHubTemplateFactroy = new CredHubTemplateFactory();
CredHubProperties credHubProperties = new CredHubProperties();
credHubProperties.setUrl(System.getProperty("spring.credhub.url"));
if (credHubProperties.getUrl() != null
&& !credHubProperties.getUrl().isEmpty()) {
credHubOperations = credHubTemplateFactroy.credHubTemplate(
credHubProperties,
credHubTemplateFactroy.clientHttpRequestFactoryWrapper());
}
else {
logger.log(Level.WARNING,
"System property spring.credhub.url is undefined. CredHubOperations cannot be initialized, disabling processing of service data");
}
}
catch (Exception e) {
logger.log(Level.WARNING, "CredHubOperations cannot be initialized, " +
"disabling processing of service data", e);
logger.log(Level.WARNING, "CredHubOperations cannot be initialized, "
+ "disabling processing of service data", e);
}
}
/**
* Initialize the service data post-processor using the provided {@link CredHubOperations}.
* Intended for internal use.
* Initialize the service data post-processor using the provided
* {@link CredHubOperations}. Intended for internal use.
*
* @param credHubOperations the CredHubOperations to use
*/
@@ -79,15 +96,17 @@ public class CredHubInterpolationServiceDataPostProcessor implements ServiceData
.interpolateServiceData(connectorsToCredHub(serviceData));
return credHubToConnectors(interpolatedData);
} catch (Exception e) {
logger.log(Level.WARNING, "Error interpolating service data from CredHub.", e);
}
catch (Exception e) {
logger.log(Level.WARNING, "Error interpolating service data from CredHub.",
e);
return serviceData;
}
}
/**
* Convert from the Spring Cloud Connectors service data structure to the Spring Credhub
* data structure.
* Convert from the Spring Cloud Connectors service data structure to the Spring
* Credhub data structure.
*
* @param rawServiceData the Spring Cloud Connectors data structure
* @return the equivalent Spring CredHub data structure
@@ -99,13 +118,14 @@ public class CredHubInterpolationServiceDataPostProcessor implements ServiceData
}
/**
* Convert from the Spring Credhub service data structure to the Spring Cloud Connectors
* data structure.
* 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(ServicesData interpolatedData) {
private CloudFoundryRawServiceData credHubToConnectors(
ServicesData interpolatedData) {
CloudFoundryRawServiceData rawServicesData = new CloudFoundryRawServiceData();
rawServicesData.putAll(interpolatedData);
return rawServicesData;

View File

@@ -0,0 +1,56 @@
/*
* 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.configuration;
import org.springframework.credhub.core.CredHubProperties;
import org.springframework.credhub.core.CredHubTemplate;
import org.springframework.credhub.support.ClientOptions;
import org.springframework.http.client.ClientHttpRequestFactory;
/**
* Factory for {@link CredHubTemplate} used to communicate with CredHub.
*
* @author Scott Frederick
* @author Daniel Lavoie
*/
public class CredHubTemplateFactory {
public CredHubTemplate credHubTemplate(CredHubProperties credHubProperties,
ClientHttpRequestFactory clientHttpRequestFactory) {
return new CredHubTemplate(credHubProperties.getUrl(), clientHttpRequestFactory);
}
/**
* Create a {@link ClientHttpRequestFactory}.
*
* @return the {@link ClientHttpRequestFactory} instance.
*
* @see #clientOptions()
*/
public ClientHttpRequestFactory clientHttpRequestFactoryWrapper() {
return ClientHttpRequestFactoryFactory.create(clientOptions());
}
/**
* Create the default {@link ClientOptions} to configure communication parameters.
*
* @return the default {@link ClientOptions}
*/
private ClientOptions clientOptions() {
return new ClientOptions();
}
}

View File

@@ -18,43 +18,49 @@
package org.springframework.credhub.core;
import org.springframework.beans.factory.annotation.Value;
/**
* Properties containing information about a CredHub server.
*
* @author Scott Frederick
* @author Daniel Lavoie
*/
public class CredHubProperties {
@Value("${CREDHUB_API}")
private String apiUriBase;
private String url;
/**
* Create a new instance without initializing properties.
*/
public CredHubProperties() {
if (apiUriBase == null) {
apiUriBase = System.getenv("CREDHUB_API");
}
}
/**
* Create a new instance with the provided properties. Intended to be used
* internally for testing.
* Create a new instance with the provided properties. Intended to be used internally
* for testing.
*
* @param apiUriBase the base URI for the CredHub server
* @param url the base URI for the CredHub server
*/
CredHubProperties(String apiUriBase) {
this.apiUriBase = apiUriBase;
CredHubProperties(String url) {
this.url = url;
}
/**
* Get the base URI for the CredHub server (scheme, host, and port). This value
* will be prepended to all requests to CredHub.
* Get the base URI for the CredHub server (scheme, host, and port). This value will
* be prepended to all requests to CredHub.
*
* @return the base URI
*/
public String getApiUriBase() {
return apiUriBase;
public String getUrl() {
return url;
}
/**
* Set the base URI for the CredHub server (scheme, host, and port). This value will
* be prepended to all requests to CredHub.
*
* @param url the base URI for the CredHub server
*/
public void setUrl(String url) {
this.url = url;
}
}

View File

@@ -97,7 +97,6 @@ public class CredHubTemplate implements CredHubOperations {
}
@Override
@SuppressWarnings("unchecked")
public <T> CredentialDetails<T> write(final CredentialRequest<T> credentialRequest) {
Assert.notNull(credentialRequest, "credentialRequest must not be null");
@@ -119,7 +118,6 @@ public class CredHubTemplate implements CredHubOperations {
}
@Override
@SuppressWarnings("unchecked")
public <T, P> CredentialDetails<T> generate(final ParametersRequest<P> parametersRequest) {
Assert.notNull(parametersRequest, "parametersRequest must not be null");

View File

@@ -44,7 +44,7 @@ apply plugin: 'propdeps-eclipse'
apply plugin: 'org.springframework.boot'
dependencies {
compile group: 'org.springframework.credhub', name: 'spring-credhub-core', version: '1.0.0.BUILD-SNAPSHOT'
compile group: 'org.springframework.credhub', name: 'spring-credhub-starter', version: '1.0.0.BUILD-SNAPSHOT'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'

View File

@@ -0,0 +1,31 @@
/*
* 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.
*/
description = 'Spring CredHub Starter'
dependencies {
compile project(':spring-credhub-core')
compile group: 'org.springframework.boot', name: 'spring-boot-starter', version: "${springBootVersion}"
optional(group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3') {
exclude(module: 'commons-logging')
}
optional group: 'com.squareup.okhttp', name: 'okhttp', version: '2.7.5'
optional group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
optional group: 'io.netty', name: 'netty-all', version: '4.1.8.Final'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: "${springBootVersion}"
}

View File

@@ -14,56 +14,53 @@
* limitations under the License.
*/
package org.springframework.credhub.configuration;
package org.springframework.credhub.autoconfig;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.credhub.configuration.CredHubTemplateFactory;
import org.springframework.credhub.core.CredHubProperties;
import org.springframework.credhub.core.CredHubTemplate;
import org.springframework.credhub.support.ClientOptions;
import org.springframework.http.client.ClientHttpRequestFactory;
/**
* Configuration for the {@link CredHubTemplate} used to communicate with CredHub. This
* class is typically imported into Java-based Spring application configuration as in
* this example:
*
* <pre>
* {@code
* &#64;Configuration
* &#64;Import(CredHubConfiguration.class)
* public class MyConfiguration {
* }
* }
* </pre>
*
* @author Scott Frederick
* {@link EnableAutoConfiguration Auto-configuration} for {@link CredHubTemplate}.
*
* @author Scott Frederick
* @author Daniel Lavoie
*/
@Configuration
public class CredHubConfiguration {
@ConditionalOnProperty(value = "spring.credhub.url")
public class CredHubAutoConfiguration {
private final CredHubTemplateFactory credHubTemplateFactory = new CredHubTemplateFactory();
/**
* Create the {@link CredHubProperties} that contains information about the
* CredHub server.
*
* @return the {@link CredHubProperties} bean
* Configuration properties for CredHub
*
* @return a {@link CredHubProperties} bean
*/
@Bean
@ConfigurationProperties(prefix = "spring.credhub")
public CredHubProperties credHubProperties() {
return new CredHubProperties();
}
/**
* Create the {@link CredHubTemplate} that the application will use to interact
* with CredHub.
* Create the {@link CredHubTemplate} that the application will use to interact with
* CredHub.
*
* @return the {@link CredHubTemplate} bean
*/
@Bean
public CredHubTemplate credHubTemplate() {
return new CredHubTemplate(credHubProperties().getApiUriBase(),
return credHubTemplateFactory.credHubTemplate(credHubProperties(),
clientHttpRequestFactoryWrapper().getClientHttpRequestFactory());
}
@@ -71,8 +68,8 @@ public class CredHubConfiguration {
* Create a {@link ClientFactoryWrapper} containing a
* {@link ClientHttpRequestFactory}. {@link ClientHttpRequestFactory} is not exposed
* as root bean because {@link ClientHttpRequestFactory} is configured with
* {@link ClientOptions} which are not necessarily
* applicable for the whole application.
* {@link ClientOptions} which are not necessarily applicable for the whole
* application.
*
* @return the {@link ClientFactoryWrapper} to wrap a {@link ClientHttpRequestFactory}
* instance.
@@ -80,18 +77,8 @@ public class CredHubConfiguration {
*/
@Bean
public ClientFactoryWrapper clientHttpRequestFactoryWrapper() {
ClientHttpRequestFactory clientHttpRequestFactory =
ClientHttpRequestFactoryFactory.create(clientOptions());
return new ClientFactoryWrapper(clientHttpRequestFactory);
}
/**
* Create the default {@link ClientOptions} to configure communication parameters.
*
* @return the default {@link ClientOptions}
*/
private ClientOptions clientOptions() {
return new ClientOptions();
return new ClientFactoryWrapper(
credHubTemplateFactory.clientHttpRequestFactoryWrapper());
}
/**

View File

@@ -14,13 +14,7 @@
* limitations under the License.
*/
package org.springframework.credhub.demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.credhub.configuration.CredHubConfiguration;
@Configuration
@Import(CredHubConfiguration.class)
public class CredHubDemoConfiguration {
}
/**
* Spring auto configuration support for Spring CredHub.
*/
package org.springframework.credhub.autoconfig;

View File

@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.credhub.autoconfig.CredHubAutoConfiguration

View File

@@ -0,0 +1,28 @@
package org.springframework.credhub.configuration;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.credhub.configuration.CredHubAutoConfigurationTest.TestConfig;
import org.springframework.credhub.core.CredHubTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfig.class, value = "spring.credhub.url=http://localhost")
public class CredHubAutoConfigurationTest {
@Autowired
private CredHubTemplate credHubTemplate;
@Test
public void contextLoads() {
Assert.assertNotNull(credHubTemplate);
}
@SpringBootApplication
public static class TestConfig {
}
}