[bs-35] Add @ConfigurationProperties EndpointsProperties and bind to application.yml

[Fixes #48245695]
This commit is contained in:
Dave Syer 2013-05-01 09:14:01 +01:00
parent ce2a2beab4
commit 5501adc862
3 changed files with 230 additions and 0 deletions

View File

@ -0,0 +1,138 @@
package org.springframework.bootstrap.sample.service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Test;
import org.springframework.bootstrap.SpringApplication;
import org.springframework.bootstrap.service.properties.EndpointsProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
/**
* Integration tests for endpoints configuration.
*
* @author Dave Syer
*
*/
public class EndpointsPropertiesServiceBootstrapApplicationTests {
private ConfigurableApplicationContext context;
private void start(final Class<?> configuration, final String... args)
throws Exception {
Future<ConfigurableApplicationContext> future = Executors
.newSingleThreadExecutor().submit(
new Callable<ConfigurableApplicationContext>() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(configuration, args);
}
});
this.context = future.get(10, TimeUnit.SECONDS);
}
@After
public void stop() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void testCustomErrorPath() throws Exception {
start(ServiceBootstrapApplication.class, "--endpoints.error.path=/oops");
testError();
}
@Test
public void testCustomEndpointsProperties() throws Exception {
start(CustomServiceBootstrapApplication.class, "--endpoints.error.path=/oops");
testError();
}
private void testError() {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = getRestTemplate("user", "password").getForEntity(
"http://localhost:8080/oops", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("None", body.get("error"));
assertEquals(999, body.get("status"));
}
@Configuration
@Import(ServiceBootstrapApplication.class)
public static class CustomServiceBootstrapApplication {
@Bean
CustomEndpointsProperties endpointsProperties() {
return new CustomEndpointsProperties();
}
}
public static class CustomEndpointsProperties extends EndpointsProperties {
@Override
public Endpoint getError() {
return new Endpoint("/oops");
}
}
private RestTemplate getRestTemplate(final String username, final String password) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
if (username != null) {
interceptors.add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().add(
"Authorization",
"Basic "
+ new String(Base64
.encode((username + ":" + password)
.getBytes())));
return execution.execute(request, body);
}
});
}
RestTemplate restTemplate = new RestTemplate(
new InterceptingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory(), interceptors));
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
return restTemplate;
}
}

View File

@ -18,10 +18,13 @@ package org.springframework.bootstrap.autoconfigure.service;
import java.util.List;
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
import org.springframework.bootstrap.service.annotation.EnableConfigurationProperties;
import org.springframework.bootstrap.service.properties.EndpointsProperties;
import org.springframework.bootstrap.service.properties.ManagementServerProperties;
import org.springframework.bootstrap.service.properties.ServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.converter.HttpMessageConverter;
@ -62,6 +65,12 @@ public class ServiceAutoConfiguration extends WebMvcConfigurationSupport {
@EnableConfigurationProperties({ ServerProperties.class,
ManagementServerProperties.class })
public static class ServerPropertiesConfiguration {
@Bean
@ConditionalOnMissingBean(EndpointsProperties.class)
public EndpointsProperties endpointsProperties() {
return new EndpointsProperties();
}
}
}

View File

@ -0,0 +1,83 @@
/*
* 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.service.properties;
import javax.validation.constraints.NotNull;
import org.springframework.bootstrap.context.annotation.ConfigurationProperties;
/**
* Externalized configuration for endpoints (e.g. paths)
*
* @author Dave Syer
*
*/
@ConfigurationProperties(name = "endpoints", ignoreUnknownFields = false)
public class EndpointsProperties {
private Endpoint varz = new Endpoint("/varz");
private Endpoint healthz = new Endpoint("/healthz");
private Endpoint error = new Endpoint("/error");
private Endpoint shutdown = new Endpoint("/shutdown");
private Endpoint trace = new Endpoint("/trace");
public Endpoint getVarz() {
return this.varz;
}
public Endpoint getHealthz() {
return this.healthz;
}
public Endpoint getError() {
return this.error;
}
public Endpoint getShutdown() {
return this.shutdown;
}
public Endpoint getTrace() {
return this.trace;
}
public static class Endpoint {
@NotNull
private String path;
public Endpoint() {
}
public Endpoint(String path) {
super();
this.path = path;
}
public String getPath() {
return this.path;
}
public void setPath(String path) {
this.path = path;
}
}
}