Polish
This commit is contained in:
parent
c136054e69
commit
7446235ff4
|
|
@ -30,6 +30,7 @@ import org.springframework.core.ResolvableType;
|
|||
*
|
||||
* @param <H> The health indicator type
|
||||
* @param <S> T he bean source type
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndicator, S> {
|
||||
|
|
@ -61,8 +62,8 @@ public abstract class CompositeHealthIndicatorConfiguration<H extends HealthIndi
|
|||
return indicatorClass.getConstructor(sourceClass).newInstance(source);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Unable to create indicator "
|
||||
+ indicatorClass + " for source " + sourceClass, ex);
|
||||
throw new IllegalStateException("Unable to create indicator " + indicatorClass
|
||||
+ " for source " + sourceClass, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,14 +43,14 @@ class ElasticsearchHealthIndicatorConfiguration {
|
|||
@ConditionalOnBean(Client.class)
|
||||
@ConditionalOnEnabledHealthIndicator("elasticsearch")
|
||||
@EnableConfigurationProperties(ElasticsearchHealthIndicatorProperties.class)
|
||||
static class SpringData extends
|
||||
static class ElasticsearchSpringDataHealthIndicatorConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> {
|
||||
|
||||
private final Map<String, Client> clients;
|
||||
|
||||
private final ElasticsearchHealthIndicatorProperties properties;
|
||||
|
||||
SpringData(Map<String, Client> clients,
|
||||
ElasticsearchSpringDataHealthIndicatorConfiguration(Map<String, Client> clients,
|
||||
ElasticsearchHealthIndicatorProperties properties) {
|
||||
this.clients = clients;
|
||||
this.properties = properties;
|
||||
|
|
@ -72,12 +72,12 @@ class ElasticsearchHealthIndicatorConfiguration {
|
|||
@Configuration
|
||||
@ConditionalOnBean(JestClient.class)
|
||||
@ConditionalOnEnabledHealthIndicator("elasticsearch")
|
||||
static class Jest extends
|
||||
static class ElasticsearchJestHealthIndicatorConfiguration extends
|
||||
CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
|
||||
|
||||
private final Map<String, JestClient> clients;
|
||||
|
||||
Jest(Map<String, JestClient> clients) {
|
||||
ElasticsearchJestHealthIndicatorConfiguration(Map<String, JestClient> clients) {
|
||||
this.clients = clients;
|
||||
}
|
||||
|
||||
|
|
@ -88,9 +88,11 @@ class ElasticsearchHealthIndicatorConfiguration {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ElasticsearchJestHealthIndicator createHealthIndicator(JestClient client) {
|
||||
protected ElasticsearchJestHealthIndicator createHealthIndicator(
|
||||
JestClient client) {
|
||||
return new ElasticsearchJestHealthIndicator(client);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
|
|||
MongoDataAutoConfiguration.class, RabbitAutoConfiguration.class,
|
||||
RedisAutoConfiguration.class, SolrAutoConfiguration.class })
|
||||
@EnableConfigurationProperties({ HealthIndicatorProperties.class })
|
||||
@Import({ ElasticsearchHealthIndicatorConfiguration.SpringData.class,
|
||||
ElasticsearchHealthIndicatorConfiguration.Jest.class })
|
||||
@Import({ ElasticsearchHealthIndicatorConfiguration.ElasticsearchSpringDataHealthIndicatorConfiguration.class,
|
||||
ElasticsearchHealthIndicatorConfiguration.ElasticsearchJestHealthIndicatorConfiguration.class })
|
||||
public class HealthIndicatorAutoConfiguration {
|
||||
|
||||
private final HealthIndicatorProperties properties;
|
||||
|
|
|
|||
|
|
@ -70,4 +70,5 @@ public class ElasticsearchHealthIndicator extends AbstractHealthIndicator {
|
|||
builder.withDetail("initializingShards", response.getInitializingShards());
|
||||
builder.withDetail("unassignedShards", response.getUnassignedShards());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ public class ElasticsearchJestHealthIndicatorTests {
|
|||
public void elasticSearchIsDown() throws IOException {
|
||||
given(this.jestClient.execute(any(Action.class))).willThrow(
|
||||
new CouldNotConnectException("http://localhost:9200", new IOException()));
|
||||
|
||||
Health health = this.healthIndicator.health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
|
||||
}
|
||||
|
|
@ -69,7 +68,6 @@ public class ElasticsearchJestHealthIndicatorTests {
|
|||
public void elasticSearchIsOutOfService() throws IOException {
|
||||
given(this.jestClient.execute(any(Action.class)))
|
||||
.willReturn(createJestResult(4, 1));
|
||||
|
||||
Health health = this.healthIndicator.health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
|
||||
}
|
||||
|
|
@ -77,7 +75,6 @@ public class ElasticsearchJestHealthIndicatorTests {
|
|||
private static JestResult createJestResult(int shards, int failedShards) {
|
||||
String json = String.format("{_shards: {\n" + "total: %s,\n" + "successful: %s,\n"
|
||||
+ "failed: %s\n" + "}}", shards, shards - failedShards, failedShards);
|
||||
|
||||
SearchResult searchResult = new SearchResult(new Gson());
|
||||
searchResult.setJsonString(json);
|
||||
searchResult.setJsonObject(new JsonParser().parse(json).getAsJsonObject());
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ public class JestAutoConfiguration {
|
|||
|
||||
private final ObjectProvider<Gson> gsonProvider;
|
||||
|
||||
public JestAutoConfiguration(JestProperties properties, ObjectProvider<Gson> gsonProvider) {
|
||||
public JestAutoConfiguration(JestProperties properties,
|
||||
ObjectProvider<Gson> gsonProvider) {
|
||||
this.properties = properties;
|
||||
this.gsonProvider = gsonProvider;
|
||||
}
|
||||
|
|
@ -62,8 +63,8 @@ public class JestAutoConfiguration {
|
|||
}
|
||||
|
||||
protected HttpClientConfig createHttpClientConfig() {
|
||||
HttpClientConfig.Builder builder = new HttpClientConfig
|
||||
.Builder(this.properties.getUris());
|
||||
HttpClientConfig.Builder builder = new HttpClientConfig.Builder(
|
||||
this.properties.getUris());
|
||||
if (StringUtils.hasText(this.properties.getUsername())) {
|
||||
builder.defaultCredentials(this.properties.getUsername(),
|
||||
this.properties.getPassword());
|
||||
|
|
@ -73,8 +74,7 @@ public class JestAutoConfiguration {
|
|||
builder.gson(gson);
|
||||
}
|
||||
return builder.connTimeout(this.properties.getConnectionTimeout())
|
||||
.readTimeout(this.properties.getReadTimeout())
|
||||
.build();
|
||||
.readTimeout(this.properties.getReadTimeout()).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ class ArtemisConnectionFactoryFactory {
|
|||
Constructor<T> constructor = factoryClass.getConstructor(boolean.class,
|
||||
TransportConfiguration[].class);
|
||||
T connectionFactory = constructor.newInstance(false,
|
||||
new TransportConfiguration[] {transportConfiguration});
|
||||
new TransportConfiguration[] { transportConfiguration });
|
||||
String user = this.properties.getUser();
|
||||
if (StringUtils.hasText(user)) {
|
||||
connectionFactory.setUser(user);
|
||||
|
|
|
|||
|
|
@ -112,9 +112,10 @@ class HornetQConnectionFactoryFactory {
|
|||
this.properties.getEmbedded().generateTransportParameters());
|
||||
ServerLocator serviceLocator = HornetQClient
|
||||
.createServerLocatorWithoutHA(transportConfiguration);
|
||||
Constructor<T> constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class,
|
||||
ServerLocator.class);
|
||||
return BeanUtils.instantiateClass(constructor, this.properties, serviceLocator);
|
||||
Constructor<T> constructor = factoryClass
|
||||
.getDeclaredConstructor(HornetQProperties.class, ServerLocator.class);
|
||||
return BeanUtils.instantiateClass(constructor, this.properties,
|
||||
serviceLocator);
|
||||
}
|
||||
catch (NoClassDefFoundError ex) {
|
||||
throw new IllegalStateException("Unable to create InVM "
|
||||
|
|
@ -130,8 +131,8 @@ class HornetQConnectionFactoryFactory {
|
|||
params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort());
|
||||
TransportConfiguration transportConfiguration = new TransportConfiguration(
|
||||
NettyConnectorFactory.class.getName(), params);
|
||||
Constructor<T> constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class,
|
||||
boolean.class, TransportConfiguration[].class);
|
||||
Constructor<T> constructor = factoryClass.getDeclaredConstructor(
|
||||
HornetQProperties.class, boolean.class, TransportConfiguration[].class);
|
||||
return BeanUtils.instantiateClass(constructor, this.properties, false,
|
||||
new TransportConfiguration[] { transportConfiguration });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class HornetQXAConnectionFactoryConfiguration {
|
|||
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
|
||||
public ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory,
|
||||
HornetQProperties properties, XAConnectionFactoryWrapper wrapper)
|
||||
throws Exception {
|
||||
throws Exception {
|
||||
return wrapper.wrapConnectionFactory(
|
||||
new HornetQConnectionFactoryFactory(beanFactory, properties)
|
||||
.createConnectionFactory(
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class SpringBootHornetQConnectionFactory extends HornetQConnectionFactory {
|
|||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection createConnection() throws JMSException {
|
||||
String user = this.properties.getUser();
|
||||
if (StringUtils.hasText(user)) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class SpringBootHornetQXAConnectionFactory extends HornetQXAConnectionFactory {
|
|||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection createConnection() throws JMSException {
|
||||
String user = this.properties.getUser();
|
||||
if (StringUtils.hasText(user)) {
|
||||
|
|
|
|||
|
|
@ -209,7 +209,8 @@ public class MongoProperties {
|
|||
}
|
||||
String host = this.host == null ? "localhost" : this.host;
|
||||
int port = determinePort(environment);
|
||||
return new MongoClient(Collections.singletonList(new ServerAddress(host, port)),
|
||||
return new MongoClient(
|
||||
Collections.singletonList(new ServerAddress(host, port)),
|
||||
credentials, options);
|
||||
}
|
||||
// The options and credentials are in the URI
|
||||
|
|
|
|||
|
|
@ -226,14 +226,13 @@ public class WebMvcAutoConfiguration {
|
|||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
|
||||
public LocaleResolver localeResolver() {
|
||||
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
|
||||
if (this.mvcProperties
|
||||
.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
|
||||
return new FixedLocaleResolver(this.mvcProperties.getLocale());
|
||||
}
|
||||
else {
|
||||
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
|
||||
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
|
||||
return localeResolver;
|
||||
}
|
||||
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
|
||||
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
|
||||
return localeResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ public class WebMvcProperties {
|
|||
private DefaultMessageCodesResolver.Format messageCodesResolverFormat;
|
||||
|
||||
/**
|
||||
* Locale to use. By default, this locale is overridden by the "Accept-Language" header.
|
||||
* Locale to use. By default, this locale is overridden by the "Accept-Language"
|
||||
* header.
|
||||
*/
|
||||
private Locale locale;
|
||||
|
||||
|
|
@ -261,8 +262,8 @@ public class WebMvcProperties {
|
|||
FIXED,
|
||||
|
||||
/**
|
||||
* Use the "Accept-Language" header or the configured locale if the header
|
||||
* is not set.
|
||||
* Use the "Accept-Language" header or the configured locale if the header is not
|
||||
* set.
|
||||
*/
|
||||
ACCEPT_HEADER
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,8 @@ public class MongoAutoConfigurationTests {
|
|||
MongoClient mongo = this.context.getBean(MongoClient.class);
|
||||
MongoClientOptions options = mongo.getMongoClientOptions();
|
||||
assertThat(options.isSslEnabled()).isTrue();
|
||||
assertThat(options.getSocketFactory()).isSameAs(this.context.getBean("mySocketFactory"));
|
||||
assertThat(options.getSocketFactory())
|
||||
.isSameAs(this.context.getBean("mySocketFactory"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
|
@ -110,7 +111,8 @@ public class MongoAutoConfigurationTests {
|
|||
|
||||
@Bean
|
||||
public MongoClientOptions mongoClientOptions() {
|
||||
return MongoClientOptions.builder().sslEnabled(true).socketFactory(mySocketFactory()).build();
|
||||
return MongoClientOptions.builder().sslEnabled(true)
|
||||
.socketFactory(mySocketFactory()).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
|||
|
|
@ -2637,20 +2637,21 @@ and http://hibernate.org/orm/documentation/[Hibernate] reference documentation.
|
|||
[NOTE]
|
||||
====
|
||||
As of Hibernate 5.2, the `hibernate-entitymanager` module has been merged in
|
||||
`hibernate-core`. If you need to downgrade, you'll have to add `hibernate-entitymanager`
|
||||
yourself, something like:
|
||||
`hibernate-core`. If you need to downgrade, you'll need to directly add the
|
||||
dependency yourself, for example:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>${hibernate.version}</version>
|
||||
</dependency>
|
||||
```
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>${hibernate.version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
As Hibernate does not bundle the `hibernate-entitymanager` and `hibernate-java8`
|
||||
artifacts anymore, Spring Boot doesn't provide dependency management for them.
|
||||
|
|
@ -3364,6 +3365,7 @@ configured:
|
|||
To take full control over the registration, define a `JestClient` bean.
|
||||
|
||||
|
||||
|
||||
[[boot-features-connecting-to-elasticsearch]]
|
||||
[[boot-features-connecting-to-elasticsearch-spring-data]]
|
||||
==== Connecting to Elasticsearch using Spring Data
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package sample.jetty.jsp;
|
|||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.web.SpringBootServletInitializer;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SampleJettyJspApplication extends SpringBootServletInitializer {
|
||||
|
|
|
|||
|
|
@ -172,12 +172,15 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
|||
Element returns = this.processingEnv.getTypeUtils()
|
||||
.asElement(element.getReturnType());
|
||||
if (returns instanceof TypeElement) {
|
||||
ItemMetadata group = ItemMetadata.newGroup(prefix, this.typeUtils.getType(returns),
|
||||
ItemMetadata group = ItemMetadata.newGroup(prefix,
|
||||
this.typeUtils.getType(returns),
|
||||
this.typeUtils.getType(element.getEnclosingElement()),
|
||||
element.toString());
|
||||
if (this.metadataCollector.hasSimilarGroup(group)) {
|
||||
this.processingEnv.getMessager().printMessage(Kind.ERROR,
|
||||
"Duplicate `@ConfigurationProperties` definition for prefix '" + prefix + "'", element);
|
||||
"Duplicate `@ConfigurationProperties` definition for prefix '"
|
||||
+ prefix + "'",
|
||||
element);
|
||||
}
|
||||
else {
|
||||
this.metadataCollector.add(group);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ package org.springframework.boot.configurationsample.specific;
|
|||
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Test that the same type can be registered several times if the prefix is
|
||||
* different.
|
||||
* Test that the same type can be registered several times if the prefix is different.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -31,13 +31,19 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
|||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Jetty {@link AbstractLifeCycle} to initialize jasper.
|
||||
* Jetty {@link AbstractLifeCycle} to initialize Jasper.
|
||||
*
|
||||
* @author Vladimir Tsanev
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class JasperInitializer extends AbstractLifeCycle {
|
||||
class JasperInitializer extends AbstractLifeCycle {
|
||||
|
||||
private static final String[] INITIALIZER_CLASSES = {
|
||||
"org.eclipse.jetty.apache.jsp.JettyJasperInitializer",
|
||||
"org.apache.jasper.servlet.JasperInitializer" };
|
||||
|
||||
private final WebAppContext context;
|
||||
|
||||
private final ServletContainerInitializer initializer;
|
||||
|
||||
JasperInitializer(WebAppContext context) {
|
||||
|
|
@ -45,24 +51,17 @@ public class JasperInitializer extends AbstractLifeCycle {
|
|||
this.initializer = newInitializer();
|
||||
}
|
||||
|
||||
private static ServletContainerInitializer newInitializer() {
|
||||
try {
|
||||
private ServletContainerInitializer newInitializer() {
|
||||
for (String className : INITIALIZER_CLASSES) {
|
||||
try {
|
||||
return (ServletContainerInitializer) ClassUtils
|
||||
.forName("org.eclipse.jetty.apache.jsp.JettyJasperInitializer",
|
||||
null)
|
||||
.newInstance();
|
||||
Class<?> initializerClass = ClassUtils.forName(className, null);
|
||||
return (ServletContainerInitializer) initializerClass.newInstance();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// try the original initializer
|
||||
return (ServletContainerInitializer) ClassUtils
|
||||
.forName("org.apache.jasper.servlet.JasperInitializer", null)
|
||||
.newInstance();
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -71,22 +70,14 @@ public class JasperInitializer extends AbstractLifeCycle {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
if ("war".equals(protocol)) {
|
||||
return new WarUrlStreamHandler();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
URL.setURLStreamHandlerFactory(new WarUrlStreamHandlerFactory());
|
||||
}
|
||||
catch (Error ex) {
|
||||
// Ignore
|
||||
}
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(this.context.getClassLoader());
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(this.context.getClassLoader());
|
||||
try {
|
||||
setExtendedListenerTypes(true);
|
||||
this.initializer.onStartup(null, this.context.getServletContext());
|
||||
|
|
@ -109,23 +100,36 @@ public class JasperInitializer extends AbstractLifeCycle {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link URLStreamHandlerFactory} to support {@literal war} protocol.
|
||||
*/
|
||||
private static class WarUrlStreamHandlerFactory implements URLStreamHandlerFactory {
|
||||
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
if ("war".equals(protocol)) {
|
||||
return new WarUrlStreamHandler();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link URLStreamHandler} for {@literal war} protocol compatible with jasper's
|
||||
* {@link URL urls} produced by
|
||||
* {@link org.apache.tomcat.util.scan.JarFactory#getJarEntryURL(URL, String)}.
|
||||
*/
|
||||
static class WarUrlStreamHandler extends URLStreamHandler {
|
||||
private static class WarUrlStreamHandler extends URLStreamHandler {
|
||||
|
||||
@Override
|
||||
protected void parseURL(URL u, String spec, int start, int limit) {
|
||||
String path = "jar:" + spec.substring("war:".length());
|
||||
|
||||
int separator = path.indexOf("*/");
|
||||
if (separator >= 0) {
|
||||
path = path.substring(0, separator) + "!/"
|
||||
+ path.substring(separator + 2);
|
||||
}
|
||||
|
||||
setURL(u, u.getProtocol(), "", -1, null, null, path, null, null);
|
||||
}
|
||||
|
||||
|
|
@ -133,12 +137,13 @@ public class JasperInitializer extends AbstractLifeCycle {
|
|||
protected URLConnection openConnection(URL u) throws IOException {
|
||||
return new WarURLConnection(u);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link URLConnection} to support {@literal war} protocol.
|
||||
*/
|
||||
static class WarURLConnection extends URLConnection {
|
||||
private static class WarURLConnection extends URLConnection {
|
||||
|
||||
private final URLConnection connection;
|
||||
|
||||
|
|
@ -160,6 +165,7 @@ public class JasperInitializer extends AbstractLifeCycle {
|
|||
connect();
|
||||
return this.connection.getInputStream();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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.boot.context.embedded.tomcat;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.URLStreamHandlerFactory;
|
||||
import java.security.KeyStore;
|
||||
|
||||
import org.springframework.boot.context.embedded.SslStoreProvider;
|
||||
|
||||
/**
|
||||
* A {@link URLStreamHandlerFactory} that provides a {@link URLStreamHandler} for
|
||||
* accessing an {@link SslStoreProvider}'s key store and trust store from a URL.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class SslStoreProviderUrlStreamHandlerFactory implements URLStreamHandlerFactory {
|
||||
|
||||
private static final String PROTOCOL = "springbootssl";
|
||||
|
||||
private static final String KEY_STORE_PATH = "keyStore";
|
||||
|
||||
static final String KEY_STORE_URL = PROTOCOL + ":" + KEY_STORE_PATH;
|
||||
|
||||
private static final String TRUST_STORE_PATH = "trustStore";
|
||||
|
||||
static final String TRUST_STORE_URL = PROTOCOL + ":" + TRUST_STORE_PATH;
|
||||
|
||||
private final SslStoreProvider sslStoreProvider;
|
||||
|
||||
SslStoreProviderUrlStreamHandlerFactory(SslStoreProvider sslStoreProvider) {
|
||||
this.sslStoreProvider = sslStoreProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
if (PROTOCOL.equals(protocol)) {
|
||||
return new URLStreamHandler() {
|
||||
|
||||
@Override
|
||||
protected URLConnection openConnection(URL url) throws IOException {
|
||||
try {
|
||||
if (KEY_STORE_PATH.equals(url.getPath())) {
|
||||
return new KeyStoreUrlConnection(url,
|
||||
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
|
||||
.getKeyStore());
|
||||
}
|
||||
if (TRUST_STORE_PATH.equals(url.getPath())) {
|
||||
return new KeyStoreUrlConnection(url,
|
||||
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
|
||||
.getTrustStore());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
throw new IOException("Invalid path: " + url.getPath());
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final class KeyStoreUrlConnection extends URLConnection {
|
||||
|
||||
private final KeyStore keyStore;
|
||||
|
||||
private KeyStoreUrlConnection(URL url, KeyStore keyStore) {
|
||||
super(url);
|
||||
this.keyStore = keyStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
this.keyStore.store(stream, new char[0]);
|
||||
return new ByteArrayInputStream(stream.toByteArray());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,19 +16,11 @@
|
|||
|
||||
package org.springframework.boot.context.embedded.tomcat;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.URLStreamHandlerFactory;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.KeyStore;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
|
@ -63,7 +55,6 @@ import org.apache.coyote.http11.AbstractHttp11Protocol;
|
|||
import org.apache.coyote.http11.Http11NioProtocol;
|
||||
import org.apache.tomcat.util.net.SSLHostConfig;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.Compression;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
|
||||
|
|
@ -79,7 +70,6 @@ import org.springframework.context.ResourceLoaderAware;
|
|||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
|
@ -702,158 +692,6 @@ public class TomcatEmbeddedServletContainerFactory
|
|||
return this.uriEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link URLStreamHandlerFactory} that provides a {@link URLStreamHandler} for
|
||||
* accessing an {@link SslStoreProvider}'s key store and trust store from a URL.
|
||||
*/
|
||||
private static final class SslStoreProviderUrlStreamHandlerFactory
|
||||
implements URLStreamHandlerFactory {
|
||||
|
||||
private static final String PROTOCOL = "springbootssl";
|
||||
|
||||
private static final String KEY_STORE_PATH = "keyStore";
|
||||
|
||||
private static final String KEY_STORE_URL = PROTOCOL + ":" + KEY_STORE_PATH;
|
||||
|
||||
private static final String TRUST_STORE_PATH = "trustStore";
|
||||
|
||||
private static final String TRUST_STORE_URL = PROTOCOL + ":" + TRUST_STORE_PATH;
|
||||
|
||||
private final SslStoreProvider sslStoreProvider;
|
||||
|
||||
private SslStoreProviderUrlStreamHandlerFactory(
|
||||
SslStoreProvider sslStoreProvider) {
|
||||
this.sslStoreProvider = sslStoreProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
if (PROTOCOL.equals(protocol)) {
|
||||
return new URLStreamHandler() {
|
||||
|
||||
@Override
|
||||
protected URLConnection openConnection(URL url) throws IOException {
|
||||
try {
|
||||
if (KEY_STORE_PATH.equals(url.getPath())) {
|
||||
return new KeyStoreUrlConnection(url,
|
||||
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
|
||||
.getKeyStore());
|
||||
}
|
||||
if (TRUST_STORE_PATH.equals(url.getPath())) {
|
||||
return new KeyStoreUrlConnection(url,
|
||||
SslStoreProviderUrlStreamHandlerFactory.this.sslStoreProvider
|
||||
.getTrustStore());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
throw new IOException("Invalid path: " + url.getPath());
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final class KeyStoreUrlConnection extends URLConnection {
|
||||
|
||||
private final KeyStore keyStore;
|
||||
|
||||
private KeyStoreUrlConnection(URL url, KeyStore keyStore) {
|
||||
super(url);
|
||||
this.keyStore = keyStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
this.keyStore.store(stream, new char[0]);
|
||||
return new ByteArrayInputStream(stream.toByteArray());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static class TomcatErrorPage {
|
||||
|
||||
private static final String ERROR_PAGE_CLASS = "org.apache.tomcat.util.descriptor.web.ErrorPage";
|
||||
|
||||
private static final String LEGACY_ERROR_PAGE_CLASS = "org.apache.catalina.deploy.ErrorPage";
|
||||
|
||||
private final String location;
|
||||
|
||||
private final String exceptionType;
|
||||
|
||||
private final int errorCode;
|
||||
|
||||
private final Object nativePage;
|
||||
|
||||
TomcatErrorPage(ErrorPage errorPage) {
|
||||
this.location = errorPage.getPath();
|
||||
this.exceptionType = errorPage.getExceptionName();
|
||||
this.errorCode = errorPage.getStatusCode();
|
||||
this.nativePage = createNativePage(errorPage);
|
||||
}
|
||||
|
||||
private Object createNativePage(ErrorPage errorPage) {
|
||||
Object nativePage = null;
|
||||
try {
|
||||
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
|
||||
nativePage = BeanUtils
|
||||
.instantiate(ClassUtils.forName(ERROR_PAGE_CLASS, null));
|
||||
}
|
||||
else if (ClassUtils.isPresent(LEGACY_ERROR_PAGE_CLASS, null)) {
|
||||
nativePage = BeanUtils.instantiate(
|
||||
ClassUtils.forName(LEGACY_ERROR_PAGE_CLASS, null));
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Swallow and continue
|
||||
}
|
||||
catch (LinkageError ex) {
|
||||
// Swallow and continue
|
||||
}
|
||||
return nativePage;
|
||||
}
|
||||
|
||||
public void addToContext(Context context) {
|
||||
Assert.state(this.nativePage != null,
|
||||
"Neither Tomcat 7 nor 8 detected so no native error page exists");
|
||||
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
|
||||
org.apache.tomcat.util.descriptor.web.ErrorPage errorPage = (org.apache.tomcat.util.descriptor.web.ErrorPage) this.nativePage;
|
||||
errorPage.setLocation(this.location);
|
||||
errorPage.setErrorCode(this.errorCode);
|
||||
errorPage.setExceptionType(this.exceptionType);
|
||||
context.addErrorPage(errorPage);
|
||||
}
|
||||
else {
|
||||
callMethod(this.nativePage, "setLocation", this.location, String.class);
|
||||
callMethod(this.nativePage, "setErrorCode", this.errorCode, int.class);
|
||||
callMethod(this.nativePage, "setExceptionType", this.exceptionType,
|
||||
String.class);
|
||||
callMethod(context, "addErrorPage", this.nativePage,
|
||||
this.nativePage.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private void callMethod(Object target, String name, Object value, Class<?> type) {
|
||||
Method method = ReflectionUtils.findMethod(target.getClass(), name, type);
|
||||
ReflectionUtils.invokeMethod(method, target, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link LifecycleListener} that stores an empty merged web.xml. This is critical for
|
||||
* Jasper to prevent warnings about missing web.xml files and to enable EL.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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.boot.context.embedded.tomcat;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.boot.web.servlet.ErrorPage;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Tomcat specific management for an {@link ErrorPage}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class TomcatErrorPage {
|
||||
|
||||
private static final String ERROR_PAGE_CLASS = "org.apache.tomcat.util.descriptor.web.ErrorPage";
|
||||
|
||||
private static final String LEGACY_ERROR_PAGE_CLASS = "org.apache.catalina.deploy.ErrorPage";
|
||||
|
||||
private final String location;
|
||||
|
||||
private final String exceptionType;
|
||||
|
||||
private final int errorCode;
|
||||
|
||||
private final Object nativePage;
|
||||
|
||||
TomcatErrorPage(ErrorPage errorPage) {
|
||||
this.location = errorPage.getPath();
|
||||
this.exceptionType = errorPage.getExceptionName();
|
||||
this.errorCode = errorPage.getStatusCode();
|
||||
this.nativePage = createNativePage(errorPage);
|
||||
}
|
||||
|
||||
private Object createNativePage(ErrorPage errorPage) {
|
||||
Object nativePage = null;
|
||||
try {
|
||||
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
|
||||
nativePage = BeanUtils
|
||||
.instantiate(ClassUtils.forName(ERROR_PAGE_CLASS, null));
|
||||
}
|
||||
else if (ClassUtils.isPresent(LEGACY_ERROR_PAGE_CLASS, null)) {
|
||||
nativePage = BeanUtils
|
||||
.instantiate(ClassUtils.forName(LEGACY_ERROR_PAGE_CLASS, null));
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Swallow and continue
|
||||
}
|
||||
catch (LinkageError ex) {
|
||||
// Swallow and continue
|
||||
}
|
||||
return nativePage;
|
||||
}
|
||||
|
||||
public void addToContext(Context context) {
|
||||
Assert.state(this.nativePage != null,
|
||||
"Neither Tomcat 7 nor 8 detected so no native error page exists");
|
||||
if (ClassUtils.isPresent(ERROR_PAGE_CLASS, null)) {
|
||||
org.apache.tomcat.util.descriptor.web.ErrorPage errorPage = (org.apache.tomcat.util.descriptor.web.ErrorPage) this.nativePage;
|
||||
errorPage.setLocation(this.location);
|
||||
errorPage.setErrorCode(this.errorCode);
|
||||
errorPage.setExceptionType(this.exceptionType);
|
||||
context.addErrorPage(errorPage);
|
||||
}
|
||||
else {
|
||||
callMethod(this.nativePage, "setLocation", this.location, String.class);
|
||||
callMethod(this.nativePage, "setErrorCode", this.errorCode, int.class);
|
||||
callMethod(this.nativePage, "setExceptionType", this.exceptionType,
|
||||
String.class);
|
||||
callMethod(context, "addErrorPage", this.nativePage,
|
||||
this.nativePage.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private void callMethod(Object target, String name, Object value, Class<?> type) {
|
||||
Method method = ReflectionUtils.findMethod(target.getClass(), name, type);
|
||||
ReflectionUtils.invokeMethod(method, target, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -33,10 +33,9 @@ import com.google.gson.reflect.TypeToken;
|
|||
*/
|
||||
public class GsonJsonParser implements JsonParser {
|
||||
|
||||
private static final TypeToken<List<Object>> LIST_TYPE = new TypeToken<List<Object>>() {
|
||||
};
|
||||
private static final TypeToken<Map<String, Object>> MAP_TYPE = new TypeToken<Map<String, Object>>() {
|
||||
};
|
||||
private static final TypeToken<?> MAP_TYPE = new MapTypeToken();
|
||||
|
||||
private static final TypeToken<?> LIST_TYPE = new ListTypeToken();
|
||||
|
||||
private Gson gson = new GsonBuilder().create();
|
||||
|
||||
|
|
@ -62,4 +61,12 @@ public class GsonJsonParser implements JsonParser {
|
|||
throw new IllegalArgumentException("Cannot parse JSON");
|
||||
}
|
||||
|
||||
private static final class MapTypeToken extends TypeToken<Map<String, Object>> {
|
||||
|
||||
}
|
||||
|
||||
private static final class ListTypeToken extends TypeToken<List<Object>> {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
*/
|
||||
public class JacksonJsonParser implements JsonParser {
|
||||
|
||||
private static final TypeReference<List<Object>> LIST_TYPE = new TypeReference<List<Object>>() {
|
||||
};
|
||||
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<Map<String, Object>>() {
|
||||
};
|
||||
private static final TypeReference<?> MAP_TYPE = new MapTypeReference();
|
||||
|
||||
private static final TypeReference<?> LIST_TYPE = new ListTypeReference();
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
|
|
@ -57,4 +56,12 @@ public class JacksonJsonParser implements JsonParser {
|
|||
}
|
||||
}
|
||||
|
||||
private static class MapTypeReference extends TypeReference<Map<String, Object>> {
|
||||
|
||||
};
|
||||
|
||||
private static class ListTypeReference extends TypeReference<List<Object>> {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,12 +79,10 @@ public class TestEntityScanTests {
|
|||
@Test
|
||||
public void valueAndBasePackagesThrows() throws Exception {
|
||||
this.thrown.expect(AnnotationConfigurationException.class);
|
||||
this.thrown.expectMessage(allOf(
|
||||
containsString("'value'"),
|
||||
containsString("'basePackages'"),
|
||||
containsString("com.mycorp.entity"),
|
||||
this.thrown.expectMessage(allOf(containsString("'value'"),
|
||||
containsString("'basePackages'"), containsString("com.mycorp.entity"),
|
||||
containsString("com.mycorp")));
|
||||
new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
|
||||
this.context = new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -78,12 +78,10 @@ public class ServletComponentScanRegistrarTests {
|
|||
@Test
|
||||
public void packagesConfiguredWithBothValueAndBasePackages() {
|
||||
this.thrown.expect(AnnotationConfigurationException.class);
|
||||
this.thrown.expectMessage(allOf(
|
||||
containsString("'value'"),
|
||||
containsString("'basePackages'"),
|
||||
containsString("com.example.foo"),
|
||||
this.thrown.expectMessage(allOf(containsString("'value'"),
|
||||
containsString("'basePackages'"), containsString("com.example.foo"),
|
||||
containsString("com.example.bar")));
|
||||
new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
|
||||
this.context = new AnnotationConfigApplicationContext(ValueAndBasePackages.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue