Merge branch '1.5.x'
This commit is contained in:
commit
eb17aa06f9
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2016 the original author or authors.
|
* Copyright 2012-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -69,8 +69,12 @@ public class HealthEndpoint extends AbstractEndpoint<Health> {
|
||||||
return this.timeToLive;
|
return this.timeToLive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimeToLive(long ttl) {
|
/**
|
||||||
this.timeToLive = ttl;
|
* Set the time to live for cached results.
|
||||||
|
* @param timeToLive the time to live in milliseconds
|
||||||
|
*/
|
||||||
|
public void setTimeToLive(long timeToLive) {
|
||||||
|
this.timeToLive = timeToLive;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -171,20 +171,13 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint
|
||||||
|
|
||||||
private Health getCurrentHealth() {
|
private Health getCurrentHealth() {
|
||||||
long accessTime = System.currentTimeMillis();
|
long accessTime = System.currentTimeMillis();
|
||||||
CachedHealth cachedHealth = this.cachedHealth;
|
CachedHealth cached = this.cachedHealth;
|
||||||
if (isStale(cachedHealth, accessTime)) {
|
if (cached == null || cached.isStale(accessTime, getDelegate().getTimeToLive())) {
|
||||||
Health health = getDelegate().invoke();
|
Health health = getDelegate().invoke();
|
||||||
this.cachedHealth = new CachedHealth(health, accessTime);
|
this.cachedHealth = new CachedHealth(health, accessTime);
|
||||||
return health;
|
return health;
|
||||||
}
|
}
|
||||||
return cachedHealth.health;
|
return cached.getHealth();
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isStale(CachedHealth cachedHealth, long accessTime) {
|
|
||||||
if (cachedHealth == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return (accessTime - cachedHealth.creationTime) >= getDelegate().getTimeToLive();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean exposeHealthDetails(HttpServletRequest request,
|
protected boolean exposeHealthDetails(HttpServletRequest request,
|
||||||
|
@ -234,6 +227,14 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint
|
||||||
this.creationTime = creationTime;
|
this.creationTime = creationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isStale(long accessTime, long timeToLive) {
|
||||||
|
return (accessTime - this.creationTime) >= timeToLive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Health getHealth() {
|
||||||
|
return this.health;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,8 +106,8 @@ public class OAuth2RestOperationsConfiguration {
|
||||||
|
|
||||||
private final AccessTokenRequest accessTokenRequest;
|
private final AccessTokenRequest accessTokenRequest;
|
||||||
|
|
||||||
public ClientContextConfiguration(@Qualifier("accessTokenRequest")
|
public ClientContextConfiguration(
|
||||||
ObjectProvider<AccessTokenRequest> accessTokenRequest) {
|
@Qualifier("accessTokenRequest") ObjectProvider<AccessTokenRequest> accessTokenRequest) {
|
||||||
this.accessTokenRequest = accessTokenRequest.getIfAvailable();
|
this.accessTokenRequest = accessTokenRequest.getIfAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class ResourceProperties implements ResourceLoaderAware {
|
||||||
String[] normalized = new String[staticLocations.length];
|
String[] normalized = new String[staticLocations.length];
|
||||||
for (int i = 0; i < staticLocations.length; i++) {
|
for (int i = 0; i < staticLocations.length; i++) {
|
||||||
String location = staticLocations[i];
|
String location = staticLocations[i];
|
||||||
normalized[i] = location.endsWith("/") ? location : location + "/";
|
normalized[i] = (location.endsWith("/") ? location : location + "/");
|
||||||
}
|
}
|
||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,8 @@ public class Neo4jPropertiesTests {
|
||||||
Neo4jProperties properties = load(true,
|
Neo4jProperties properties = load(true,
|
||||||
"spring.data.neo4j.uri=https://localhost:7474");
|
"spring.data.neo4j.uri=https://localhost:7474");
|
||||||
Configuration configuration = properties.createConfiguration();
|
Configuration configuration = properties.createConfiguration();
|
||||||
assertDriver(configuration, Neo4jProperties.HTTP_DRIVER, "https://localhost:7474");
|
assertDriver(configuration, Neo4jProperties.HTTP_DRIVER,
|
||||||
|
"https://localhost:7474");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -47,13 +47,18 @@ public class OAuth2RestOperationsConfigurationTests {
|
||||||
public void clientIdConditionMatches() throws Exception {
|
public void clientIdConditionMatches() throws Exception {
|
||||||
EnvironmentTestUtils.addEnvironment(this.environment,
|
EnvironmentTestUtils.addEnvironment(this.environment,
|
||||||
"security.oauth2.client.client-id=acme");
|
"security.oauth2.client.client-id=acme");
|
||||||
this.context = new SpringApplicationBuilder(OAuth2RestOperationsConfiguration.class).environment(this.environment).web(false).run();
|
this.context = new SpringApplicationBuilder(
|
||||||
assertThat(this.context.getBean(OAuth2RestOperationsConfiguration.class)).isNotNull();
|
OAuth2RestOperationsConfiguration.class).environment(this.environment)
|
||||||
|
.web(false).run();
|
||||||
|
assertThat(this.context.getBean(OAuth2RestOperationsConfiguration.class))
|
||||||
|
.isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void clientIdConditionDoesNotMatch() throws Exception {
|
public void clientIdConditionDoesNotMatch() throws Exception {
|
||||||
this.context = new SpringApplicationBuilder(OAuth2RestOperationsConfiguration.class).environment(this.environment).web(false).run();
|
this.context = new SpringApplicationBuilder(
|
||||||
|
OAuth2RestOperationsConfiguration.class).environment(this.environment)
|
||||||
|
.web(false).run();
|
||||||
this.thrown.expect(NoSuchBeanDefinitionException.class);
|
this.thrown.expect(NoSuchBeanDefinitionException.class);
|
||||||
this.context.getBean(OAuth2RestOperationsConfiguration.class);
|
this.context.getBean(OAuth2RestOperationsConfiguration.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,8 @@ public class ResourcePropertiesTests {
|
||||||
@Test
|
@Test
|
||||||
public void customStaticLocationsAreNormalizedToEndWithTrailingSlash() {
|
public void customStaticLocationsAreNormalizedToEndWithTrailingSlash() {
|
||||||
this.properties.setStaticLocations(new String[] { "/foo", "/bar", "/baz/" });
|
this.properties.setStaticLocations(new String[] { "/foo", "/bar", "/baz/" });
|
||||||
assertThat(this.properties.getStaticLocations()).containsExactly("/foo/", "/bar/",
|
String[] actual = this.properties.getStaticLocations();
|
||||||
"/baz/");
|
assertThat(actual).containsExactly("/foo/", "/bar/", "/baz/");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.lang.reflect.Field;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
@ -208,21 +207,27 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
|
||||||
|
|
||||||
public ResourcePatternResolver getResourcePatternResolver(
|
public ResourcePatternResolver getResourcePatternResolver(
|
||||||
ApplicationContext applicationContext, ResourceLoader resourceLoader) {
|
ApplicationContext applicationContext, ResourceLoader resourceLoader) {
|
||||||
return new PathMatchingResourcePatternResolver(resourceLoader == null
|
if (resourceLoader == null) {
|
||||||
? createResourceLoader(applicationContext) : resourceLoader);
|
resourceLoader = new DefaultResourceLoader();
|
||||||
|
copyProtocolResolvers(applicationContext, resourceLoader);
|
||||||
|
}
|
||||||
|
return new PathMatchingResourcePatternResolver(resourceLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourceLoader createResourceLoader(
|
protected final void copyProtocolResolvers(ApplicationContext applicationContext,
|
||||||
ApplicationContext applicationContext) {
|
ResourceLoader resourceLoader) {
|
||||||
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
|
if (applicationContext instanceof DefaultResourceLoader
|
||||||
if (applicationContext instanceof DefaultResourceLoader) {
|
&& resourceLoader instanceof DefaultResourceLoader) {
|
||||||
Collection<ProtocolResolver> protocolResolvers = ((DefaultResourceLoader) applicationContext)
|
copyProtocolResolvers((DefaultResourceLoader) applicationContext,
|
||||||
.getProtocolResolvers();
|
(DefaultResourceLoader) resourceLoader);
|
||||||
for (ProtocolResolver protocolResolver : protocolResolvers) {
|
}
|
||||||
resourceLoader.addProtocolResolver(protocolResolver);
|
}
|
||||||
}
|
|
||||||
|
protected final void copyProtocolResolvers(DefaultResourceLoader source,
|
||||||
|
DefaultResourceLoader destination) {
|
||||||
|
for (ProtocolResolver resolver : source.getProtocolResolvers()) {
|
||||||
|
destination.addProtocolResolver(resolver);
|
||||||
}
|
}
|
||||||
return resourceLoader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -238,25 +243,21 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
|
||||||
public ResourcePatternResolver getResourcePatternResolver(
|
public ResourcePatternResolver getResourcePatternResolver(
|
||||||
ApplicationContext applicationContext, ResourceLoader resourceLoader) {
|
ApplicationContext applicationContext, ResourceLoader resourceLoader) {
|
||||||
if (applicationContext instanceof WebApplicationContext) {
|
if (applicationContext instanceof WebApplicationContext) {
|
||||||
return new ServletContextResourcePatternResolver(resourceLoader == null
|
return getResourcePatternResolver(
|
||||||
? createResourceLoader((WebApplicationContext) applicationContext)
|
(WebApplicationContext) applicationContext, resourceLoader);
|
||||||
: resourceLoader);
|
|
||||||
}
|
}
|
||||||
return super.getResourcePatternResolver(applicationContext, resourceLoader);
|
return super.getResourcePatternResolver(applicationContext, resourceLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourceLoader createResourceLoader(
|
private ResourcePatternResolver getResourcePatternResolver(
|
||||||
WebApplicationContext applicationContext) {
|
WebApplicationContext applicationContext, ResourceLoader resourceLoader) {
|
||||||
WebApplicationContextResourceLoader resourceLoader = new WebApplicationContextResourceLoader(
|
if (resourceLoader == null) {
|
||||||
applicationContext);
|
resourceLoader = new WebApplicationContextResourceLoader(
|
||||||
if (applicationContext instanceof DefaultResourceLoader) {
|
applicationContext);
|
||||||
Collection<ProtocolResolver> protocolResolvers = ((DefaultResourceLoader) applicationContext)
|
copyProtocolResolvers(applicationContext, resourceLoader);
|
||||||
.getProtocolResolvers();
|
|
||||||
for (ProtocolResolver protocolResolver : protocolResolvers) {
|
|
||||||
resourceLoader.addProtocolResolver(protocolResolver);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return resourceLoader;
|
return new ServletContextResourcePatternResolver(resourceLoader);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,65 +433,64 @@ Maven build to run the app.
|
||||||
|
|
||||||
[[cloud-deployment-gae]]
|
[[cloud-deployment-gae]]
|
||||||
=== Google Cloud
|
=== Google Cloud
|
||||||
|
Google Cloud has several options that could be used to launch Spring Boot applications.
|
||||||
|
The easiest to get started with is probably App Engine, but you could also find ways to
|
||||||
|
run Spring Boot in a container with Container Engine, or on a virtual machine using
|
||||||
|
Compute Engine.
|
||||||
|
|
||||||
Google Cloud has several options that could be used to launch Spring Boot applications. The
|
To run in App Engine you can create a project in the UI first, which sets up a unique
|
||||||
easiest to get started with is probably App Engine, but you could also find ways to run
|
identifier for you and also HTTP routes. Add a Java app to the project and leave it empty,
|
||||||
Spring Boot in a container with Container Engine, or on a virtual machine using Compute Engine.
|
then use the https://cloud.google.com/sdk/downloads[Google Cloud SDK] to push your
|
||||||
|
|
||||||
To run in App Engine you can create a project in the UI first, which
|
|
||||||
sets up a unique identifier for you and also HTTP routes. Add a Java
|
|
||||||
app to the project and leave it empty, then use the
|
|
||||||
https://cloud.google.com/sdk/downloads[Google Cloud SDK] to push your
|
|
||||||
Spring Boot app into that slot from the command line or CI build.
|
Spring Boot app into that slot from the command line or CI build.
|
||||||
|
|
||||||
App Engine needs you to create an `app.yaml` file to describe the
|
App Engine needs you to create an `app.yaml` file to describe the resources your app
|
||||||
resources your app requires. Normally you put this in
|
requires. Normally you put this in `src/min/appengine`, and it looks something like this:
|
||||||
`src/min/appengine`, and it looks something like this:
|
|
||||||
|
|
||||||
[source,yaml,indent=0]
|
[source,yaml,indent=0]
|
||||||
----
|
----
|
||||||
service: default
|
service: default
|
||||||
|
|
||||||
runtime: java
|
runtime: java
|
||||||
env: flex
|
env: flex
|
||||||
|
|
||||||
runtime_config:
|
runtime_config:
|
||||||
jdk: openjdk8
|
jdk: openjdk8
|
||||||
|
|
||||||
handlers:
|
handlers:
|
||||||
- url: /.*
|
- url: /.*
|
||||||
script: this field is required, but ignored
|
script: this field is required, but ignored
|
||||||
|
|
||||||
manual_scaling:
|
manual_scaling:
|
||||||
instances: 1
|
instances: 1
|
||||||
|
|
||||||
health_check:
|
health_check:
|
||||||
enable_health_check: False
|
enable_health_check: False
|
||||||
|
|
||||||
env_variables:
|
env_variables:
|
||||||
ENCRYPT_KEY: your_encryption_key_here
|
ENCRYPT_KEY: your_encryption_key_here
|
||||||
----
|
----
|
||||||
|
|
||||||
You can deploy the app, for example, with a Maven plugin by simply
|
You can deploy the app, for example, with a Maven plugin by simply adding the project ID
|
||||||
adding the project ID to the build configuration:
|
to the build configuration:
|
||||||
|
|
||||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||||
----
|
----
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.google.cloud.tools</groupId>
|
<groupId>com.google.cloud.tools</groupId>
|
||||||
<artifactId>appengine-maven-plugin</artifactId>
|
<artifactId>appengine-maven-plugin</artifactId>
|
||||||
<version>1.3.0</version>
|
<version>1.3.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<project>myproject</project>
|
<project>myproject</project>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
----
|
----
|
||||||
|
|
||||||
Then deploy with `mvn appengine:deploy` (if you need to authenticate first the build will fail).
|
Then deploy with `mvn appengine:deploy` (if you need to authenticate first the build will
|
||||||
|
fail).
|
||||||
|
|
||||||
NOTE: Google App Engine Classic is tied to the Servlet 2.5 API, so you can't deploy a Spring Application
|
NOTE: Google App Engine Classic is tied to the Servlet 2.5 API, so you can't deploy a
|
||||||
there without some modifications. See the <<howto.adoc#howto-servlet-2-5, Servlet 2.5 section>>
|
Spring Application there without some modifications. See the
|
||||||
of this guide.
|
<<howto.adoc#howto-servlet-2-5, Servlet 2.5 section>> of this guide.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,7 @@ key defined via `@PropertySource` will be loaded too late to have any effect on
|
||||||
auto-configuration.
|
auto-configuration.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[howto-build-an-application-context-hierarchy]]
|
[[howto-build-an-application-context-hierarchy]]
|
||||||
=== Build an ApplicationContext hierarchy (adding a parent or root context)
|
=== Build an ApplicationContext hierarchy (adding a parent or root context)
|
||||||
You can use the `ApplicationBuilder` class to create parent/child `ApplicationContext`
|
You can use the `ApplicationBuilder` class to create parent/child `ApplicationContext`
|
||||||
|
|
|
@ -284,10 +284,12 @@ returned, and for an authenticated connection additional details are also displa
|
||||||
Health information is collected from all
|
Health information is collected from all
|
||||||
{sc-spring-boot-actuator}/health/HealthIndicator.{sc-ext}[`HealthIndicator`] beans defined
|
{sc-spring-boot-actuator}/health/HealthIndicator.{sc-ext}[`HealthIndicator`] beans defined
|
||||||
in your `ApplicationContext`. Spring Boot includes a number of auto-configured
|
in your `ApplicationContext`. Spring Boot includes a number of auto-configured
|
||||||
`HealthIndicators` and you can also write your own. By default, the final system state is derived
|
`HealthIndicators` and you can also write your own. By default, the final system state is
|
||||||
by the `HealthAggregator` which sorts the statuses from each `HealthIndicator` based on an ordered list of statuses.
|
derived by the `HealthAggregator` which sorts the statuses from each `HealthIndicator`
|
||||||
The first status in the sorted list is used as the overall health status.
|
based on an ordered list of statuses. The first status in the sorted list is used as the
|
||||||
If no `HealthIndicator` returns a status that is known to the `HealthAggregator`, an `UNKNOWN` status is used.
|
overall health status. If no `HealthIndicator` returns a status that is known to the
|
||||||
|
`HealthAggregator`, an `UNKNOWN` status is used.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=== Security with HealthIndicators
|
=== Security with HealthIndicators
|
||||||
|
|
|
@ -2475,8 +2475,8 @@ and `AuthenticationManagerConfiguration` for authentication configuration which
|
||||||
relevant in non-web applications). To switch off the default web application security
|
relevant in non-web applications). To switch off the default web application security
|
||||||
configuration completely you can add a bean with `@EnableWebSecurity` (this does not
|
configuration completely you can add a bean with `@EnableWebSecurity` (this does not
|
||||||
disable the authentication manager configuration or Actuator's security).
|
disable the authentication manager configuration or Actuator's security).
|
||||||
To customize it you normally use external properties and beans of type `WebSecurityConfigurerAdapter`
|
To customize it you normally use external properties and beans of type
|
||||||
(e.g. to add form-based login).
|
`WebSecurityConfigurerAdapter` (e.g. to add form-based login).
|
||||||
|
|
||||||
NOTE: If you add `@EnableWebSecurity` and also disable Actuator security, you will get
|
NOTE: If you add `@EnableWebSecurity` and also disable Actuator security, you will get
|
||||||
the default form-based login for the entire application unless you add a custom
|
the default form-based login for the entire application unless you add a custom
|
||||||
|
@ -6261,7 +6261,7 @@ where one will be auto-configured for you.
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
EnvironmentTestUtils.addEnvironment(env, "org=Spring", "name=Boot");
|
EnvironmentTestUtils.addEnvironment(env, "org=Spring", "name=Boot");
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
|
@ -6274,25 +6274,25 @@ for assertions:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.boot.test.rule.OutputCapture;
|
import org.springframework.boot.test.rule.OutputCapture;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class MyTest {
|
public class MyTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public OutputCapture capture = new OutputCapture();
|
public OutputCapture capture = new OutputCapture();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testName() throws Exception {
|
||||||
|
System.out.println("Hello World!");
|
||||||
|
assertThat(capture.toString(), containsString("World"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testName() throws Exception {
|
|
||||||
System.out.println("Hello World!");
|
|
||||||
assertThat(capture.toString(), containsString("World"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
----
|
----
|
||||||
|
|
||||||
[[boot-features-rest-templates-test-utility]]
|
[[boot-features-rest-templates-test-utility]]
|
||||||
|
@ -6313,17 +6313,17 @@ features will be enabled:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
public class MyTest {
|
public class MyTest {
|
||||||
|
|
||||||
private TestRestTemplate template = new TestRestTemplate();
|
private TestRestTemplate template = new TestRestTemplate();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequest() throws Exception {
|
||||||
|
HttpHeaders headers = template.getForEntity("http://myhost.com/example", String.class).getHeaders();
|
||||||
|
assertThat(headers.getLocation().toString(), containsString("myotherhost"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRequest() throws Exception {
|
|
||||||
HttpHeaders headers = template.getForEntity("http://myhost.com/example", String.class).getHeaders();
|
|
||||||
assertThat(headers.getLocation().toString(), containsString("myotherhost"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Alternatively, if you are using the `@SpringBootTest` annotation with
|
Alternatively, if you are using the `@SpringBootTest` annotation with
|
||||||
|
@ -6334,32 +6334,32 @@ specify a host and port will automatically connect to the embedded server:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class MyTest {
|
public class MyTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TestRestTemplate template;
|
private TestRestTemplate template;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequest() throws Exception {
|
public void testRequest() throws Exception {
|
||||||
HttpHeaders headers = template.getForEntity("/example", String.class).getHeaders();
|
HttpHeaders headers = template.getForEntity("/example", String.class).getHeaders();
|
||||||
assertThat(headers.getLocation().toString(), containsString("myotherhost"));
|
assertThat(headers.getLocation().toString(), containsString("myotherhost"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestConfiguration
|
@TestConfiguration
|
||||||
static class Config {
|
static class Config {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestTemplateBuilder restTemplateBuilder() {
|
||||||
|
return new RestTemplateBuilder()
|
||||||
|
.additionalMessageConverters(...)
|
||||||
|
.customizers(...);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public RestTemplateBuilder restTemplateBuilder() {
|
|
||||||
return new RestTemplateBuilder()
|
|
||||||
.additionalMessageConverters(...)
|
|
||||||
.customizers(...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,9 @@ import org.springframework.core.io.Resource;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
*/
|
*/
|
||||||
// tag::example[]
|
// tag::example[]
|
||||||
public class EnvironmentPostProcessorExample
|
public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
|
||||||
implements EnvironmentPostProcessor {
|
|
||||||
|
|
||||||
private final YamlPropertySourceLoader loader
|
private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
|
||||||
= new YamlPropertySourceLoader();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postProcessEnvironment(ConfigurableEnvironment environment,
|
public void postProcessEnvironment(ConfigurableEnvironment environment,
|
||||||
|
@ -48,15 +46,14 @@ public class EnvironmentPostProcessorExample
|
||||||
|
|
||||||
private PropertySource<?> loadYaml(Resource path) {
|
private PropertySource<?> loadYaml(Resource path) {
|
||||||
if (!path.exists()) {
|
if (!path.exists()) {
|
||||||
throw new IllegalArgumentException("Resource " + path
|
throw new IllegalArgumentException("Resource " + path + " does not exist");
|
||||||
+ " does not exist");
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return this.loader.load("custom-resource", path, null);
|
return this.loader.load("custom-resource", path, null);
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new IllegalStateException("Failed to load yaml configuration "
|
throw new IllegalStateException(
|
||||||
+ "from " + path, ex);
|
"Failed to load yaml configuration from " + path, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ public class EnvironmentPostProcessorExampleTests {
|
||||||
@Test
|
@Test
|
||||||
public void applyEnvironmentPostProcessor() {
|
public void applyEnvironmentPostProcessor() {
|
||||||
assertThat(this.environment.containsProperty("test.foo.bar")).isFalse();
|
assertThat(this.environment.containsProperty("test.foo.bar")).isFalse();
|
||||||
new EnvironmentPostProcessorExample().postProcessEnvironment(
|
new EnvironmentPostProcessorExample().postProcessEnvironment(this.environment,
|
||||||
this.environment, new SpringApplication());
|
new SpringApplication());
|
||||||
assertThat(this.environment.containsProperty("test.foo.bar")).isTrue();
|
assertThat(this.environment.containsProperty("test.foo.bar")).isTrue();
|
||||||
assertThat(this.environment.getProperty("test.foo.bar")).isEqualTo("value");
|
assertThat(this.environment.getProperty("test.foo.bar")).isEqualTo("value");
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ import org.springframework.boot.test.json.JacksonTester;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests for {@link SpringBootTest} with {@link AutoConfigureJsonTesters}.
|
* Integration tests for {@link SpringBootTest} with {@link AutoConfigureJsonTesters}.
|
||||||
*
|
*
|
||||||
|
@ -41,17 +43,19 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||||
public class SpringBootTestWithAutoConfigureJsonTestersTests {
|
public class SpringBootTestWithAutoConfigureJsonTestersTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
BasicJsonTester basicJson;
|
private BasicJsonTester basicJson;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
JacksonTester<ExampleBasicObject> jacksonTester;
|
private JacksonTester<ExampleBasicObject> jacksonTester;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
GsonTester<ExampleBasicObject> gsonTester;
|
private GsonTester<ExampleBasicObject> gsonTester;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextLoads() {
|
public void contextLoads() {
|
||||||
|
assertThat(this.basicJson).isNotNull();
|
||||||
|
assertThat(this.jacksonTester).isNotNull();
|
||||||
|
assertThat(this.gsonTester).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,11 +187,11 @@ final class JarURLConnection extends java.net.JarURLConnection {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getContentLength() {
|
public int getContentLength() {
|
||||||
long longContentLength = getContentLengthLong();
|
long length = getContentLengthLong();
|
||||||
if (longContentLength > Integer.MAX_VALUE) {
|
if (length > Integer.MAX_VALUE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (int) longContentLength;
|
return (int) length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -151,8 +151,7 @@ public class RepackageMojo extends AbstractDependencyFilterMojo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a fully executable jar for *nix machines by prepending a launch script to the
|
* Make a fully executable jar for *nix machines by prepending a launch script to the
|
||||||
* jar.
|
* jar. <br/>
|
||||||
* <br/>
|
|
||||||
* Currently, some tools do not accept this format so you may not always be able to
|
* Currently, some tools do not accept this format so you may not always be able to
|
||||||
* use this technique. For example, <code>jar -xf</code> may silently fail to extract
|
* use this technique. For example, <code>jar -xf</code> may silently fail to extract
|
||||||
* a jar or war that has been made fully-executable. It is recommended that you only
|
* a jar or war that has been made fully-executable. It is recommended that you only
|
||||||
|
|
|
@ -65,7 +65,6 @@ final class EnvironmentConverter {
|
||||||
* environment is already a {@code StandardEnvironment} and is not a
|
* environment is already a {@code StandardEnvironment} and is not a
|
||||||
* {@link ConfigurableWebEnvironment} no conversion is performed and it is returned
|
* {@link ConfigurableWebEnvironment} no conversion is performed and it is returned
|
||||||
* unchanged.
|
* unchanged.
|
||||||
*
|
|
||||||
* @param environment The Environment to convert
|
* @param environment The Environment to convert
|
||||||
* @return The converted Environment
|
* @return The converted Environment
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -92,8 +92,8 @@ import org.springframework.util.StringUtils;
|
||||||
* @author Eddú Meléndez
|
* @author Eddú Meléndez
|
||||||
* @author Madhura Bhave
|
* @author Madhura Bhave
|
||||||
*/
|
*/
|
||||||
public class ConfigFileApplicationListener implements EnvironmentPostProcessor,
|
public class ConfigFileApplicationListener
|
||||||
SmartApplicationListener, Ordered {
|
implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
|
||||||
|
|
||||||
private static final String DEFAULT_PROPERTIES = "defaultProperties";
|
private static final String DEFAULT_PROPERTIES = "defaultProperties";
|
||||||
|
|
||||||
|
@ -142,8 +142,8 @@ public class ConfigFileApplicationListener implements EnvironmentPostProcessor,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||||
return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType) ||
|
return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)
|
||||||
ApplicationPreparedEvent.class.isAssignableFrom(eventType);
|
|| ApplicationPreparedEvent.class.isAssignableFrom(eventType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -307,8 +307,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
||||||
.forEach((name, level) -> setLogLevel(system, name, level));
|
.forEach((name, level) -> setLogLevel(system, name, level));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setLogLevel(LoggingSystem system, String name,
|
private void setLogLevel(LoggingSystem system, String name, String level) {
|
||||||
String level) {
|
|
||||||
try {
|
try {
|
||||||
name = (name.equalsIgnoreCase(LoggingSystem.ROOT_LOGGER_NAME) ? null : name);
|
name = (name.equalsIgnoreCase(LoggingSystem.ROOT_LOGGER_NAME) ? null : name);
|
||||||
system.setLogLevel(name, coerceLogLevel(level));
|
system.setLogLevel(name, coerceLogLevel(level));
|
||||||
|
|
|
@ -452,8 +452,8 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc
|
||||||
if (AnnotatedElementUtils.hasAnnotation(type, Validated.class)) {
|
if (AnnotatedElementUtils.hasAnnotation(type, Validated.class)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (type.getPackage() != null &&
|
if (type.getPackage() != null && type.getPackage().getName()
|
||||||
type.getPackage().getName().startsWith("org.springframework.boot")) {
|
.startsWith("org.springframework.boot")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getConstraintsForClass(type).isBeanConstrained()) {
|
if (getConstraintsForClass(type).isBeanConstrained()) {
|
||||||
|
|
|
@ -321,7 +321,6 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
|
||||||
keyManagerFactory.getKeyManagers());
|
keyManagerFactory.getKeyManagers());
|
||||||
}
|
}
|
||||||
return keyManagerFactory.getKeyManagers();
|
return keyManagerFactory.getKeyManagers();
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException(ex);
|
throw new IllegalStateException(ex);
|
||||||
|
|
|
@ -526,10 +526,14 @@ public class LoggingApplicationListenerTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void lowPriorityPropertySourceShouldNotOverrideRootLoggerConfig() throws Exception {
|
public void lowPriorityPropertySourceShouldNotOverrideRootLoggerConfig()
|
||||||
MutablePropertySources propertySources = this.context.getEnvironment().getPropertySources();
|
throws Exception {
|
||||||
propertySources.addFirst(new MapPropertySource("test1", Collections.singletonMap("logging.level.ROOT", "DEBUG")));
|
MutablePropertySources propertySources = this.context.getEnvironment()
|
||||||
propertySources.addLast(new MapPropertySource("test2", Collections.singletonMap("logging.level.root", "WARN")));
|
.getPropertySources();
|
||||||
|
propertySources.addFirst(new MapPropertySource("test1",
|
||||||
|
Collections.singletonMap("logging.level.ROOT", "DEBUG")));
|
||||||
|
propertySources.addLast(new MapPropertySource("test2",
|
||||||
|
Collections.singletonMap("logging.level.root", "WARN")));
|
||||||
this.initializer.initialize(this.context.getEnvironment(),
|
this.initializer.initialize(this.context.getEnvironment(),
|
||||||
this.context.getClassLoader());
|
this.context.getClassLoader());
|
||||||
this.logger.debug("testatdebug");
|
this.logger.debug("testatdebug");
|
||||||
|
|
|
@ -255,8 +255,10 @@ public class UndertowServletWebServerFactoryTests
|
||||||
UndertowServletWebServerFactory factory = getFactory();
|
UndertowServletWebServerFactory factory = getFactory();
|
||||||
Ssl ssl = getSsl(null, "password", "src/test/resources/test.jks");
|
Ssl ssl = getSsl(null, "password", "src/test/resources/test.jks");
|
||||||
factory.setSsl(ssl);
|
factory.setSsl(ssl);
|
||||||
KeyManager[] keyManagers = ReflectionTestUtils.invokeMethod(factory, "getKeyManagers");
|
KeyManager[] keyManagers = ReflectionTestUtils.invokeMethod(factory,
|
||||||
Class<?> name = Class.forName("org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory$ConfigurableAliasKeyManager");
|
"getKeyManagers");
|
||||||
|
Class<?> name = Class.forName("org.springframework.boot.web.embedded.undertow"
|
||||||
|
+ ".UndertowServletWebServerFactory$ConfigurableAliasKeyManager");
|
||||||
assertThat(keyManagers[0]).isNotInstanceOf(name);
|
assertThat(keyManagers[0]).isNotInstanceOf(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue