parent
1fa541d4de
commit
de3b9a4910
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.batch;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.autoconfigure.batch.BatchProperties.Jdbc;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Initialize the Spring Batch schema (ignoring errors, so it should be idempotent).
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Vedran Pavic
|
||||
* @since 1.0.0
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0 in favor of
|
||||
* {@link BatchDataSourceScriptDatabaseInitializer}
|
||||
*/
|
||||
@Deprecated
|
||||
public class BatchDataSourceInitializer extends org.springframework.boot.jdbc.AbstractDataSourceInitializer {
|
||||
|
||||
private final Jdbc jdbcProperties;
|
||||
|
||||
public BatchDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader,
|
||||
BatchProperties properties) {
|
||||
super(dataSource, resourceLoader);
|
||||
Assert.notNull(properties, "BatchProperties must not be null");
|
||||
this.jdbcProperties = properties.getJdbc();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected org.springframework.boot.jdbc.DataSourceInitializationMode getMode() {
|
||||
DatabaseInitializationMode mode = this.jdbcProperties.getInitializeSchema();
|
||||
switch (mode) {
|
||||
case ALWAYS:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.ALWAYS;
|
||||
case EMBEDDED:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.EMBEDDED;
|
||||
case NEVER:
|
||||
default:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSchemaLocation() {
|
||||
return this.jdbcProperties.getSchema();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
String platform = this.jdbcProperties.getPlatform();
|
||||
if (StringUtils.hasText(platform)) {
|
||||
return platform;
|
||||
}
|
||||
String databaseName = super.getDatabaseName();
|
||||
if ("oracle".equals(databaseName)) {
|
||||
return "oracle10g";
|
||||
}
|
||||
if ("mariadb".equals(databaseName)) {
|
||||
return "mysql";
|
||||
}
|
||||
return databaseName;
|
||||
}
|
||||
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.data.elasticsearch;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
/**
|
||||
* Deprecated configuration properties for Elasticsearch Reactive REST clients.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0
|
||||
*/
|
||||
@Deprecated
|
||||
@ConfigurationProperties(prefix = "spring.data.elasticsearch.client.reactive")
|
||||
class DeprecatedReactiveElasticsearchRestClientProperties {
|
||||
|
||||
/**
|
||||
* Comma-separated list of the Elasticsearch endpoints to connect to.
|
||||
*/
|
||||
private List<String> endpoints = new ArrayList<>(Collections.singletonList("localhost:9200"));
|
||||
|
||||
/**
|
||||
* Whether the client should use SSL to connect to the endpoints.
|
||||
*/
|
||||
private boolean useSsl = false;
|
||||
|
||||
/**
|
||||
* Credentials username.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Credentials password.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Connection timeout.
|
||||
*/
|
||||
private Duration connectionTimeout;
|
||||
|
||||
/**
|
||||
* Read and Write Socket timeout.
|
||||
*/
|
||||
private Duration socketTimeout;
|
||||
|
||||
/**
|
||||
* Limit on the number of bytes that can be buffered whenever the input stream needs
|
||||
* to be aggregated.
|
||||
*/
|
||||
private DataSize maxInMemorySize;
|
||||
|
||||
private boolean customized = false;
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.uris")
|
||||
public List<String> getEndpoints() {
|
||||
return this.endpoints;
|
||||
}
|
||||
|
||||
public void setEndpoints(List<String> endpoints) {
|
||||
this.customized = true;
|
||||
this.endpoints = endpoints;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(reason = "Use of SSL should be indicated through an https URI scheme")
|
||||
public boolean isUseSsl() {
|
||||
return this.useSsl;
|
||||
}
|
||||
|
||||
public void setUseSsl(boolean useSsl) {
|
||||
this.customized = true;
|
||||
this.useSsl = useSsl;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.username")
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.customized = true;
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.password")
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.customized = true;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.connection-timeout")
|
||||
public Duration getConnectionTimeout() {
|
||||
return this.connectionTimeout;
|
||||
}
|
||||
|
||||
public void setConnectionTimeout(Duration connectionTimeout) {
|
||||
this.customized = true;
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.socket-timeout")
|
||||
public Duration getSocketTimeout() {
|
||||
return this.socketTimeout;
|
||||
}
|
||||
|
||||
public void setSocketTimeout(Duration socketTimeout) {
|
||||
this.customized = true;
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.webclient.max-in-memory-size")
|
||||
public DataSize getMaxInMemorySize() {
|
||||
return this.maxInMemorySize;
|
||||
}
|
||||
|
||||
public void setMaxInMemorySize(DataSize maxInMemorySize) {
|
||||
this.customized = true;
|
||||
this.maxInMemorySize = maxInMemorySize;
|
||||
}
|
||||
|
||||
boolean isCustomized() {
|
||||
return this.customized;
|
||||
}
|
||||
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.elasticsearch;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
|
||||
|
||||
/**
|
||||
* Deprecated configuration properties for Elasticsearch REST clients.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0.
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.elasticsearch.rest")
|
||||
@Deprecated
|
||||
class DeprecatedElasticsearchRestClientProperties {
|
||||
|
||||
/**
|
||||
* Comma-separated list of the Elasticsearch instances to use.
|
||||
*/
|
||||
private List<String> uris = new ArrayList<>(Collections.singletonList("http://localhost:9200"));
|
||||
|
||||
/**
|
||||
* Credentials username.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Credentials password.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Connection timeout.
|
||||
*/
|
||||
private Duration connectionTimeout = Duration.ofSeconds(1);
|
||||
|
||||
/**
|
||||
* Read timeout.
|
||||
*/
|
||||
private Duration readTimeout = Duration.ofSeconds(30);
|
||||
|
||||
private final Sniffer sniffer = new Sniffer();
|
||||
|
||||
private boolean customized = false;
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.uris")
|
||||
public List<String> getUris() {
|
||||
return this.uris;
|
||||
}
|
||||
|
||||
public void setUris(List<String> uris) {
|
||||
this.customized = true;
|
||||
this.uris = uris;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.username")
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.customized = true;
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.password")
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.customized = true;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.connection-timeout")
|
||||
public Duration getConnectionTimeout() {
|
||||
return this.connectionTimeout;
|
||||
}
|
||||
|
||||
public void setConnectionTimeout(Duration connectionTimeout) {
|
||||
this.customized = true;
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.socket-timeout")
|
||||
public Duration getReadTimeout() {
|
||||
return this.readTimeout;
|
||||
}
|
||||
|
||||
public void setReadTimeout(Duration readTimeout) {
|
||||
this.customized = true;
|
||||
this.readTimeout = readTimeout;
|
||||
}
|
||||
|
||||
boolean isCustomized() {
|
||||
return this.customized;
|
||||
}
|
||||
|
||||
public Sniffer getSniffer() {
|
||||
return this.sniffer;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
class Sniffer {
|
||||
|
||||
/**
|
||||
* Interval between consecutive ordinary sniff executions.
|
||||
*/
|
||||
private Duration interval = Duration.ofMinutes(5);
|
||||
|
||||
/**
|
||||
* Delay of a sniff execution scheduled after a failure.
|
||||
*/
|
||||
private Duration delayAfterFailure = Duration.ofMinutes(1);
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.restclient.sniffer.interval")
|
||||
public Duration getInterval() {
|
||||
return this.interval;
|
||||
}
|
||||
|
||||
public void setInterval(Duration interval) {
|
||||
DeprecatedElasticsearchRestClientProperties.this.customized = true;
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(replacement = "spring.elasticsearch.restclient.sniffer.delay-after-failure")
|
||||
public Duration getDelayAfterFailure() {
|
||||
return this.delayAfterFailure;
|
||||
}
|
||||
|
||||
public void setDelayAfterFailure(Duration delayAfterFailure) {
|
||||
DeprecatedElasticsearchRestClientProperties.this.customized = true;
|
||||
this.delayAfterFailure = delayAfterFailure;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.integration;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Initializer for Spring Integration schema.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0 in favor of
|
||||
* {@link IntegrationDataSourceScriptDatabaseInitializer}
|
||||
*/
|
||||
@Deprecated
|
||||
public class IntegrationDataSourceInitializer extends org.springframework.boot.jdbc.AbstractDataSourceInitializer {
|
||||
|
||||
private final IntegrationProperties.Jdbc properties;
|
||||
|
||||
public IntegrationDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader,
|
||||
IntegrationProperties properties) {
|
||||
super(dataSource, resourceLoader);
|
||||
Assert.notNull(properties, "IntegrationProperties must not be null");
|
||||
this.properties = properties.getJdbc();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected org.springframework.boot.jdbc.DataSourceInitializationMode getMode() {
|
||||
DatabaseInitializationMode mode = this.properties.getInitializeSchema();
|
||||
switch (mode) {
|
||||
case ALWAYS:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.ALWAYS;
|
||||
case EMBEDDED:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.EMBEDDED;
|
||||
case NEVER:
|
||||
default:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSchemaLocation() {
|
||||
return this.properties.getSchema();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
String platform = this.properties.getPlatform();
|
||||
if (StringUtils.hasText(platform)) {
|
||||
return platform;
|
||||
}
|
||||
return super.getDatabaseName();
|
||||
}
|
||||
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.jdbc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceInitializationConfiguration.InitializationSpecificCredentialsDataSourceInitializationConfiguration.DifferentCredentialsCondition;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceInitializationConfiguration.SharedCredentialsDataSourceInitializationConfiguration.DataSourceInitializationCondition;
|
||||
import org.springframework.boot.autoconfigure.sql.init.SqlDataSourceScriptDatabaseInitializer;
|
||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Configuration for {@link DataSource} initialization using a
|
||||
* {@link DataSourceScriptDatabaseInitializer} with DDL and DML scripts.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Deprecated
|
||||
class DataSourceInitializationConfiguration {
|
||||
|
||||
private static DataSource determineDataSource(Supplier<DataSource> dataSource, String username, String password) {
|
||||
if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
|
||||
return DataSourceBuilder.derivedFrom(dataSource.get()).type(SimpleDriverDataSource.class).username(username)
|
||||
.password(password).build();
|
||||
}
|
||||
return dataSource.get();
|
||||
}
|
||||
|
||||
private static List<String> scriptLocations(List<String> locations, String fallback, String platform) {
|
||||
if (locations != null) {
|
||||
return locations;
|
||||
}
|
||||
List<String> fallbackLocations = new ArrayList<>();
|
||||
fallbackLocations.add("optional:classpath*:" + fallback + "-" + platform + ".sql");
|
||||
fallbackLocations.add("optional:classpath*:" + fallback + ".sql");
|
||||
return fallbackLocations;
|
||||
}
|
||||
|
||||
private static DatabaseInitializationMode mapMode(org.springframework.boot.jdbc.DataSourceInitializationMode mode) {
|
||||
switch (mode) {
|
||||
case ALWAYS:
|
||||
return DatabaseInitializationMode.ALWAYS;
|
||||
case EMBEDDED:
|
||||
return DatabaseInitializationMode.EMBEDDED;
|
||||
case NEVER:
|
||||
return DatabaseInitializationMode.NEVER;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected initialization mode '" + mode + "'");
|
||||
}
|
||||
}
|
||||
|
||||
// Fully-qualified to work around javac bug in JDK 1.8
|
||||
@org.springframework.context.annotation.Configuration(proxyBeanMethods = false)
|
||||
@org.springframework.context.annotation.Conditional(DifferentCredentialsCondition.class)
|
||||
@org.springframework.context.annotation.Import(DatabaseInitializationDependencyConfigurer.class)
|
||||
@ConditionalOnSingleCandidate(DataSource.class)
|
||||
@ConditionalOnMissingBean(DataSourceScriptDatabaseInitializer.class)
|
||||
static class InitializationSpecificCredentialsDataSourceInitializationConfiguration {
|
||||
|
||||
@Bean
|
||||
SqlDataSourceScriptDatabaseInitializer ddlOnlyScriptDataSourceInitializer(ObjectProvider<DataSource> dataSource,
|
||||
DataSourceProperties properties) {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(scriptLocations(properties.getSchema(), "schema", properties.getPlatform()));
|
||||
settings.setContinueOnError(properties.isContinueOnError());
|
||||
settings.setSeparator(properties.getSeparator());
|
||||
settings.setEncoding(properties.getSqlScriptEncoding());
|
||||
settings.setMode(mapMode(properties.getInitializationMode()));
|
||||
DataSource initializationDataSource = determineDataSource(dataSource::getObject,
|
||||
properties.getSchemaUsername(), properties.getSchemaPassword());
|
||||
return new SqlDataSourceScriptDatabaseInitializer(initializationDataSource, settings);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn("ddlOnlyScriptDataSourceInitializer")
|
||||
SqlDataSourceScriptDatabaseInitializer dmlOnlyScriptDataSourceInitializer(ObjectProvider<DataSource> dataSource,
|
||||
DataSourceProperties properties) {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setDataLocations(scriptLocations(properties.getData(), "data", properties.getPlatform()));
|
||||
settings.setContinueOnError(properties.isContinueOnError());
|
||||
settings.setSeparator(properties.getSeparator());
|
||||
settings.setEncoding(properties.getSqlScriptEncoding());
|
||||
settings.setMode(mapMode(properties.getInitializationMode()));
|
||||
DataSource initializationDataSource = determineDataSource(dataSource::getObject,
|
||||
properties.getDataUsername(), properties.getDataPassword());
|
||||
return new SqlDataSourceScriptDatabaseInitializer(initializationDataSource, settings);
|
||||
}
|
||||
|
||||
static class DifferentCredentialsCondition extends AnyNestedCondition {
|
||||
|
||||
DifferentCredentialsCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "spring.datasource", name = "schema-username")
|
||||
static class SchemaCredentials {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "spring.datasource", name = "data-username")
|
||||
static class DataCredentials {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Fully-qualified to work around javac bug in JDK 1.8
|
||||
@org.springframework.context.annotation.Configuration(proxyBeanMethods = false)
|
||||
@org.springframework.context.annotation.Import(DatabaseInitializationDependencyConfigurer.class)
|
||||
@org.springframework.context.annotation.Conditional(DataSourceInitializationCondition.class)
|
||||
@ConditionalOnSingleCandidate(DataSource.class)
|
||||
@ConditionalOnMissingBean(DataSourceScriptDatabaseInitializer.class)
|
||||
static class SharedCredentialsDataSourceInitializationConfiguration {
|
||||
|
||||
@Bean
|
||||
SqlDataSourceScriptDatabaseInitializer scriptDataSourceInitializer(DataSource dataSource,
|
||||
DataSourceProperties properties) {
|
||||
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
|
||||
settings.setSchemaLocations(scriptLocations(properties.getSchema(), "schema", properties.getPlatform()));
|
||||
settings.setDataLocations(scriptLocations(properties.getData(), "data", properties.getPlatform()));
|
||||
settings.setContinueOnError(properties.isContinueOnError());
|
||||
settings.setSeparator(properties.getSeparator());
|
||||
settings.setEncoding(properties.getSqlScriptEncoding());
|
||||
settings.setMode(mapMode(properties.getInitializationMode()));
|
||||
return new SqlDataSourceScriptDatabaseInitializer(dataSource, settings);
|
||||
}
|
||||
|
||||
static class DataSourceInitializationCondition extends SpringBootCondition {
|
||||
|
||||
private static final Set<String> INITIALIZATION_PROPERTIES = Collections
|
||||
.unmodifiableSet(new HashSet<>(Arrays.asList("spring.datasource.initialization-mode",
|
||||
"spring.datasource.platform", "spring.datasource.schema", "spring.datasource.schema[0]",
|
||||
"spring.datasource.schema-username", "spring.datasource.schema-password",
|
||||
"spring.datasource.data", "spring.datasource.data[0]", "spring.datasource.data-username",
|
||||
"spring.datasource.data-password", "spring.datasource.continue-on-error",
|
||||
"spring.datasource.separator", "spring.datasource.sql-script-encoding")));
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
ConditionMessage.Builder message = ConditionMessage.forCondition("DataSource Initialization");
|
||||
Environment environment = context.getEnvironment();
|
||||
Set<String> configuredProperties = INITIALIZATION_PROPERTIES.stream()
|
||||
.filter(environment::containsProperty).collect(Collectors.toSet());
|
||||
if (configuredProperties.isEmpty()) {
|
||||
return ConditionOutcome
|
||||
.noMatch(message.didNotFind("configured properties").items(INITIALIZATION_PROPERTIES));
|
||||
}
|
||||
return ConditionOutcome.match(
|
||||
message.found("configured property", "configured properties").items(configuredProperties));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.quartz;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Initialize the Quartz Scheduler schema.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0 in favor of
|
||||
* {@link QuartzDataSourceScriptDatabaseInitializer}
|
||||
*/
|
||||
@Deprecated
|
||||
public class QuartzDataSourceInitializer extends org.springframework.boot.jdbc.AbstractDataSourceInitializer {
|
||||
|
||||
private final QuartzProperties properties;
|
||||
|
||||
public QuartzDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader,
|
||||
QuartzProperties properties) {
|
||||
super(dataSource, resourceLoader);
|
||||
Assert.notNull(properties, "QuartzProperties must not be null");
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void customize(ResourceDatabasePopulator populator) {
|
||||
populator.setCommentPrefixes(this.properties.getJdbc().getCommentPrefix().toArray(new String[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected org.springframework.boot.jdbc.DataSourceInitializationMode getMode() {
|
||||
DatabaseInitializationMode mode = this.properties.getJdbc().getInitializeSchema();
|
||||
switch (mode) {
|
||||
case ALWAYS:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.ALWAYS;
|
||||
case EMBEDDED:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.EMBEDDED;
|
||||
case NEVER:
|
||||
default:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSchemaLocation() {
|
||||
return this.properties.getJdbc().getSchema();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
String platform = this.properties.getJdbc().getPlatform();
|
||||
if (StringUtils.hasText(platform)) {
|
||||
return platform;
|
||||
}
|
||||
String databaseName = super.getDatabaseName();
|
||||
if ("db2".equals(databaseName)) {
|
||||
return "db2_v95";
|
||||
}
|
||||
if ("mysql".equals(databaseName) || "mariadb".equals(databaseName)) {
|
||||
return "mysql_innodb";
|
||||
}
|
||||
if ("postgresql".equals(databaseName)) {
|
||||
return "postgres";
|
||||
}
|
||||
if ("sqlserver".equals(databaseName)) {
|
||||
return "sqlServer";
|
||||
}
|
||||
return databaseName;
|
||||
}
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.session;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Initializer for Spring Session schema.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 1.4.0
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0 in favor of
|
||||
* {@link JdbcSessionDataSourceScriptDatabaseInitializer}
|
||||
*/
|
||||
@Deprecated
|
||||
public class JdbcSessionDataSourceInitializer extends org.springframework.boot.jdbc.AbstractDataSourceInitializer {
|
||||
|
||||
private final JdbcSessionProperties properties;
|
||||
|
||||
public JdbcSessionDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader,
|
||||
JdbcSessionProperties properties) {
|
||||
super(dataSource, resourceLoader);
|
||||
Assert.notNull(properties, "JdbcSessionProperties must not be null");
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected org.springframework.boot.jdbc.DataSourceInitializationMode getMode() {
|
||||
DatabaseInitializationMode mode = this.properties.getInitializeSchema();
|
||||
switch (mode) {
|
||||
case ALWAYS:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.ALWAYS;
|
||||
case EMBEDDED:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.EMBEDDED;
|
||||
case NEVER:
|
||||
default:
|
||||
return org.springframework.boot.jdbc.DataSourceInitializationMode.NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSchemaLocation() {
|
||||
return this.properties.getSchema();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
String platform = this.properties.getPlatform();
|
||||
if (StringUtils.hasText(platform)) {
|
||||
return platform;
|
||||
}
|
||||
return super.getDatabaseName();
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.batch;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link BatchDataSourceInitializer}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Deprecated
|
||||
class BatchDataSourceInitializerTests {
|
||||
|
||||
@Test
|
||||
void getDatabaseNameWithPlatformDoesNotTouchDataSource() {
|
||||
DataSource dataSource = mock(DataSource.class);
|
||||
BatchProperties properties = new BatchProperties();
|
||||
properties.getJdbc().setPlatform("test");
|
||||
BatchDataSourceInitializer initializer = new BatchDataSourceInitializer(dataSource, new DefaultResourceLoader(),
|
||||
properties);
|
||||
assertThat(initializer.getDatabaseName()).isEqualTo("test");
|
||||
verifyNoInteractions(dataSource);
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.integration;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link IntegrationDataSourceInitializer}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Deprecated
|
||||
class IntegrationDataSourceInitializerTests {
|
||||
|
||||
@Test
|
||||
void getDatabaseNameWithPlatformDoesNotTouchDataSource() {
|
||||
DataSource dataSource = mock(DataSource.class);
|
||||
IntegrationProperties properties = new IntegrationProperties();
|
||||
properties.getJdbc().setPlatform("test");
|
||||
IntegrationDataSourceInitializer initializer = new IntegrationDataSourceInitializer(dataSource,
|
||||
new DefaultResourceLoader(), properties);
|
||||
assertThat(initializer.getDatabaseName()).isEqualTo("test");
|
||||
verifyNoInteractions(dataSource);
|
||||
}
|
||||
|
||||
}
|
@ -1,440 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.jdbc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.support.SimpleThreadScope;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Integration tests for DataSource initialization.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Deprecated
|
||||
class DataSourceInitializationIntegrationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withPropertyValues("spring.datasource.initialization-mode=never",
|
||||
"spring.datasource.url:jdbc:hsqldb:mem:init-" + UUID.randomUUID());
|
||||
|
||||
@Test
|
||||
void dataSourceInitialized() {
|
||||
this.contextRunner.withPropertyValues("spring.datasource.initialization-mode:always").run((context) -> {
|
||||
assertThat(context).hasSingleBean(DataSource.class);
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
|
||||
assertDataSourceIsInitialized(dataSource);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializationAppliesToCustomDataSource() {
|
||||
this.contextRunner.withUserConfiguration(OneDataSource.class)
|
||||
.withPropertyValues("spring.datasource.initialization-mode:always").run((context) -> {
|
||||
assertThat(context).hasSingleBean(DataSource.class);
|
||||
assertDataSourceIsInitialized(context.getBean(DataSource.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializationWithUsernameAndPasswordAppliesToCustomDataSource() {
|
||||
this.contextRunner.withUserConfiguration(OneDataSource.class)
|
||||
.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.schema-username=test", "spring.datasource.schema-password=secret")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(DataSource.class);
|
||||
assertDataSourceIsInitialized(context.getBean(DataSource.class));
|
||||
});
|
||||
}
|
||||
|
||||
private void assertDataSourceIsInitialized(DataSource dataSource) {
|
||||
JdbcOperations template = new JdbcTemplate(dataSource);
|
||||
assertThat(template.queryForObject("SELECT COUNT(*) from BAR", Integer.class)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void dataSourceInitializedWithExplicitScript() {
|
||||
this.contextRunner.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.schema:" + getRelativeLocationFor("schema.sql"),
|
||||
"spring.datasource.data:" + getRelativeLocationFor("data.sql")).run((context) -> {
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
|
||||
assertThat(dataSource).isNotNull();
|
||||
JdbcOperations template = new JdbcTemplate(dataSource);
|
||||
assertThat(template.queryForObject("SELECT COUNT(*) from FOO", Integer.class)).isEqualTo(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void dataSourceInitializedWithMultipleScripts() {
|
||||
this.contextRunner.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.schema:" + getRelativeLocationFor("schema.sql") + ","
|
||||
+ getRelativeLocationFor("another.sql"),
|
||||
"spring.datasource.data:" + getRelativeLocationFor("data.sql")).run((context) -> {
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
|
||||
assertThat(dataSource).isNotNull();
|
||||
JdbcOperations template = new JdbcTemplate(dataSource);
|
||||
assertThat(template.queryForObject("SELECT COUNT(*) from FOO", Integer.class)).isEqualTo(1);
|
||||
assertThat(template.queryForObject("SELECT COUNT(*) from SPAM", Integer.class)).isEqualTo(0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void dataSourceInitializedWithExplicitSqlScriptEncoding() {
|
||||
this.contextRunner.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.sqlScriptEncoding:UTF-8",
|
||||
"spring.datasource.schema:" + getRelativeLocationFor("encoding-schema.sql"),
|
||||
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql")).run((context) -> {
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
|
||||
assertThat(dataSource).isNotNull();
|
||||
JdbcOperations template = new JdbcTemplate(dataSource);
|
||||
assertThat(template.queryForObject("SELECT COUNT(*) from BAR", Integer.class)).isEqualTo(2);
|
||||
assertThat(template.queryForObject("SELECT name from BAR WHERE id=1", String.class))
|
||||
.isEqualTo("bar");
|
||||
assertThat(template.queryForObject("SELECT name from BAR WHERE id=2", String.class))
|
||||
.isEqualTo("ばー");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializationDisabled() {
|
||||
this.contextRunner.run(assertInitializationIsDisabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializationDoesNotApplyWithSeveralDataSources() {
|
||||
this.contextRunner.withUserConfiguration(TwoDataSources.class)
|
||||
.withPropertyValues("spring.datasource.initialization-mode:always").run((context) -> {
|
||||
assertThat(context.getBeanNamesForType(DataSource.class)).hasSize(2);
|
||||
assertDataSourceNotInitialized(context.getBean("oneDataSource", DataSource.class));
|
||||
assertDataSourceNotInitialized(context.getBean("twoDataSource", DataSource.class));
|
||||
});
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> assertInitializationIsDisabled() {
|
||||
return (context) -> {
|
||||
assertThat(context).hasSingleBean(DataSource.class);
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertDataSourceNotInitialized(dataSource);
|
||||
};
|
||||
}
|
||||
|
||||
private void assertDataSourceNotInitialized(DataSource dataSource) {
|
||||
JdbcOperations template = new JdbcTemplate(dataSource);
|
||||
assertThatExceptionOfType(BadSqlGrammarException.class)
|
||||
.isThrownBy(() -> template.queryForObject("SELECT COUNT(*) from BAR", Integer.class))
|
||||
.satisfies((ex) -> {
|
||||
SQLException sqlException = ex.getSQLException();
|
||||
int expectedCode = -5501; // user lacks privilege or object not found
|
||||
assertThat(sqlException.getErrorCode()).isEqualTo(expectedCode);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void dataSourceInitializedWithSchemaCredentials() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.sqlScriptEncoding:UTF-8",
|
||||
"spring.datasource.schema:" + getRelativeLocationFor("encoding-schema.sql"),
|
||||
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"),
|
||||
"spring.datasource.schema-username:admin", "spring.datasource.schema-password:admin")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class)
|
||||
.hasMessageContaining("invalid authorization specification");
|
||||
context.getStartupFailure().printStackTrace();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void dataSourceInitializedWithDataCredentials() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.sqlScriptEncoding:UTF-8",
|
||||
"spring.datasource.schema:" + getRelativeLocationFor("encoding-schema.sql"),
|
||||
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"),
|
||||
"spring.datasource.data-username:admin", "spring.datasource.data-password:admin")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class)
|
||||
.hasMessageContaining("invalid authorization specification");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleScriptsAppliedInLexicalOrder() {
|
||||
new ApplicationContextRunner(() -> {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.setResourceLoader(new ReverseOrderResourceLoader(new DefaultResourceLoader()));
|
||||
return context;
|
||||
}).withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withPropertyValues("spring.datasource.initialization-mode=always",
|
||||
"spring.datasource.url:jdbc:hsqldb:mem:testdb-" + new Random().nextInt(),
|
||||
"spring.datasource.schema:classpath*:" + getRelativeLocationFor("lexical-schema-*.sql"),
|
||||
"spring.datasource.data:classpath*:" + getRelativeLocationFor("data.sql"))
|
||||
.run((context) -> {
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
|
||||
assertThat(dataSource).isNotNull();
|
||||
JdbcOperations template = new JdbcTemplate(dataSource);
|
||||
assertThat(template.queryForObject("SELECT COUNT(*) from FOO", Integer.class)).isEqualTo(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDataSourceInitializedWithInvalidSchemaResource() {
|
||||
this.contextRunner.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.schema:classpath:does/not/exist.sql").run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class);
|
||||
assertThat(context.getStartupFailure())
|
||||
.hasMessageContaining("No schema scripts found at location 'classpath:does/not/exist.sql'");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void dataSourceInitializedWithInvalidDataResource() {
|
||||
this.contextRunner.withPropertyValues("spring.datasource.initialization-mode:always",
|
||||
"spring.datasource.schema:" + getRelativeLocationFor("schema.sql"),
|
||||
"spring.datasource.data:classpath:does/not/exist.sql").run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class);
|
||||
assertThat(context.getStartupFailure())
|
||||
.hasMessageContaining("No data scripts found at location 'classpath:does/not/exist.sql'");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenDataSourceIsProxiedByABeanPostProcessorThenDataSourceInitializationUsesTheProxy() {
|
||||
this.contextRunner.withPropertyValues("spring.datasource.initialization-mode:always")
|
||||
.withUserConfiguration(DataSourceProxyConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(DataSource.class);
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertThat(dataSource).isInstanceOf(DataSourceProxy.class);
|
||||
assertThat(((DataSourceProxy) dataSource).connectionsRetrieved).hasPositiveValue();
|
||||
assertDataSourceIsInitialized(dataSource);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
// gh-13042
|
||||
void whenDataSourceIsScopedAndJpaIsInvolvedThenInitializationCompletesSuccessfully() {
|
||||
this.contextRunner.withPropertyValues("spring.datasource.initialization-mode:always")
|
||||
.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class))
|
||||
.withUserConfiguration(ScopedDataSourceConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(DataSource.class);
|
||||
DataSource dataSource = context.getBean(DataSource.class);
|
||||
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
|
||||
assertDataSourceIsInitialized(dataSource);
|
||||
});
|
||||
}
|
||||
|
||||
private String getRelativeLocationFor(String resource) {
|
||||
return ClassUtils.addResourcePathToPackagePath(getClass(), resource);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class OneDataSource {
|
||||
|
||||
@Bean
|
||||
DataSource oneDataSource() {
|
||||
return new TestDataSource(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TwoDataSources extends OneDataSource {
|
||||
|
||||
@Bean
|
||||
DataSource twoDataSource() {
|
||||
return new TestDataSource(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ResourcePatternResolver} used to ensure consistently wrong resource
|
||||
* ordering.
|
||||
*/
|
||||
static class ReverseOrderResourceLoader implements ResourcePatternResolver {
|
||||
|
||||
private final ResourcePatternResolver resolver;
|
||||
|
||||
ReverseOrderResourceLoader(ResourceLoader loader) {
|
||||
this.resolver = ResourcePatternUtils.getResourcePatternResolver(loader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource(String location) {
|
||||
return this.resolver.getResource(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.resolver.getClassLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource[] getResources(String locationPattern) throws IOException {
|
||||
Resource[] resources = this.resolver.getResources(locationPattern);
|
||||
Arrays.sort(resources, Comparator.comparing(Resource::getFilename).reversed());
|
||||
return resources;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = true)
|
||||
static class DataSourceProxyConfiguration {
|
||||
|
||||
@Bean
|
||||
static BeanPostProcessor dataSourceProxy() {
|
||||
return new BeanPostProcessor() {
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
if (bean instanceof DataSource) {
|
||||
return new DataSourceProxy((DataSource) bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class DataSourceProxy implements DataSource {
|
||||
|
||||
private final AtomicInteger connectionsRetrieved = new AtomicInteger();
|
||||
|
||||
private final DataSource delegate;
|
||||
|
||||
DataSourceProxy(DataSource delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintWriter getLogWriter() throws SQLException {
|
||||
return this.delegate.getLogWriter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogWriter(PrintWriter out) throws SQLException {
|
||||
this.delegate.setLogWriter(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return this.delegate.isWrapperFor(iface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return this.delegate.unwrap(iface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
this.connectionsRetrieved.incrementAndGet();
|
||||
return this.delegate.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
this.connectionsRetrieved.incrementAndGet();
|
||||
return this.delegate.getConnection(username, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLoginTimeout() throws SQLException {
|
||||
return this.delegate.getLoginTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoginTimeout(int seconds) throws SQLException {
|
||||
this.delegate.setLoginTimeout(seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
return this.delegate.getParentLogger();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ScopedDataSourceConfiguration {
|
||||
|
||||
@Bean
|
||||
static BeanFactoryPostProcessor fooScope() {
|
||||
return (beanFactory) -> beanFactory.registerScope("test", new SimpleThreadScope());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope("test")
|
||||
HikariDataSource dataSource(DataSourceProperties properties) {
|
||||
return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.quartz;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link QuartzDataSourceInitializer}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Deprecated
|
||||
class QuartzDataSourceInitializerTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class))
|
||||
.withPropertyValues("spring.datasource.url=" + String.format(
|
||||
"jdbc:h2:mem:test-%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", UUID.randomUUID().toString()));
|
||||
|
||||
@Test
|
||||
void getDatabaseNameWithPlatformDoesNotTouchDataSource() {
|
||||
DataSource dataSource = mock(DataSource.class);
|
||||
QuartzProperties properties = new QuartzProperties();
|
||||
properties.getJdbc().setPlatform("test");
|
||||
QuartzDataSourceInitializer initializer = new QuartzDataSourceInitializer(dataSource,
|
||||
new DefaultResourceLoader(), properties);
|
||||
assertThat(initializer.getDatabaseName()).isEqualTo("test");
|
||||
verifyNoInteractions(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
void hashIsUsedAsACommentPrefixByDefault() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class).withPropertyValues(
|
||||
"spring.quartz.jdbc.schema=classpath:org/springframework/boot/autoconfigure/quartz/tables_#_comments.sql")
|
||||
.run(this::assertThatDataSourceHasBeenInitialized);
|
||||
}
|
||||
|
||||
@Test
|
||||
void doubleDashIsUsedAsACommentPrefixByDefault() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class).withPropertyValues(
|
||||
"spring.quartz.jdbc.schema=classpath:org/springframework/boot/autoconfigure/quartz/tables_--_comments.sql")
|
||||
.run(this::assertThatDataSourceHasBeenInitialized);
|
||||
}
|
||||
|
||||
@Test
|
||||
void commentPrefixCanBeCustomized() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class).withPropertyValues(
|
||||
"spring.quartz.jdbc.comment-prefix=**",
|
||||
"spring.quartz.jdbc.schema=classpath:org/springframework/boot/autoconfigure/quartz/tables_custom_comment_prefix.sql")
|
||||
.run(this::assertThatDataSourceHasBeenInitialized);
|
||||
}
|
||||
|
||||
private void assertThatDataSourceHasBeenInitialized(AssertableApplicationContext context) {
|
||||
JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
|
||||
assertThat(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM QRTZ_TEST_TABLE", Integer.class)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(QuartzProperties.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
QuartzDataSourceInitializer initializer(DataSource dataSource, ResourceLoader resourceLoader,
|
||||
QuartzProperties properties) {
|
||||
return new QuartzDataSourceInitializer(dataSource, resourceLoader, properties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.autoconfigure.session;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link JdbcSessionDataSourceInitializer}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Deprecated
|
||||
class JdbcSessionDataSourceInitializerTests {
|
||||
|
||||
@Test
|
||||
void getDatabaseNameWithPlatformDoesNotTouchDataSource() {
|
||||
DataSource dataSource = mock(DataSource.class);
|
||||
JdbcSessionProperties properties = new JdbcSessionProperties();
|
||||
properties.setPlatform("test");
|
||||
JdbcSessionDataSourceInitializer initializer = new JdbcSessionDataSourceInitializer(dataSource,
|
||||
new DefaultResourceLoader(), properties);
|
||||
assertThat(initializer.getDatabaseName()).isEqualTo("test");
|
||||
verifyNoInteractions(dataSource);
|
||||
}
|
||||
|
||||
}
|
@ -1,968 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.DefaultPropertiesPropertySource;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||
import org.springframework.boot.context.event.ApplicationPreparedEvent;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.bind.PropertySourcesPlaceholdersResolver;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.boot.env.PropertySourceLoader;
|
||||
import org.springframework.boot.env.RandomValuePropertySource;
|
||||
import org.springframework.boot.logging.DeferredLog;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
|
||||
import org.springframework.context.event.SmartApplicationListener;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.Profiles;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link EnvironmentPostProcessor} that configures the context environment by loading
|
||||
* properties from well known file locations. By default properties will be loaded from
|
||||
* 'application.properties' and/or 'application.yml' files in the following locations:
|
||||
* <ul>
|
||||
* <li>file:./config/</li>
|
||||
* <li>file:./config/{@literal *}/</li>
|
||||
* <li>file:./</li>
|
||||
* <li>classpath:config/</li>
|
||||
* <li>classpath:</li>
|
||||
* </ul>
|
||||
* The list is ordered by precedence (properties defined in locations higher in the list
|
||||
* override those defined in lower locations).
|
||||
* <p>
|
||||
* Alternative search locations and names can be specified using
|
||||
* {@link #setSearchLocations(String)} and {@link #setSearchNames(String)}.
|
||||
* <p>
|
||||
* Additional files will also be loaded based on active profiles. For example if a 'web'
|
||||
* profile is active 'application-web.properties' and 'application-web.yml' will be
|
||||
* considered.
|
||||
* <p>
|
||||
* The 'spring.config.name' property can be used to specify an alternative name to load
|
||||
* and the 'spring.config.location' property can be used to specify alternative search
|
||||
* locations or specific files.
|
||||
* <p>
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
* @author Eddú Meléndez
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
* @since 1.0.0
|
||||
* @deprecated since 2.4.0 for removal in 3.0.0 in favor of
|
||||
* {@link ConfigDataEnvironmentPostProcessor}
|
||||
*/
|
||||
@Deprecated
|
||||
public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
|
||||
|
||||
// Note the order is from least to most specific (last one wins)
|
||||
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/";
|
||||
|
||||
private static final String DEFAULT_NAMES = "application";
|
||||
|
||||
private static final Set<String> NO_SEARCH_NAMES = Collections.singleton(null);
|
||||
|
||||
private static final Bindable<String[]> STRING_ARRAY = Bindable.of(String[].class);
|
||||
|
||||
private static final Bindable<List<String>> STRING_LIST = Bindable.listOf(String.class);
|
||||
|
||||
private static final Set<String> LOAD_FILTERED_PROPERTY;
|
||||
|
||||
static {
|
||||
Set<String> filteredProperties = new HashSet<>();
|
||||
filteredProperties.add("spring.profiles.active");
|
||||
filteredProperties.add("spring.profiles.include");
|
||||
LOAD_FILTERED_PROPERTY = Collections.unmodifiableSet(filteredProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* The "active profiles" property name.
|
||||
*/
|
||||
public static final String ACTIVE_PROFILES_PROPERTY = "spring.profiles.active";
|
||||
|
||||
/**
|
||||
* The "includes profiles" property name.
|
||||
*/
|
||||
public static final String INCLUDE_PROFILES_PROPERTY = "spring.profiles.include";
|
||||
|
||||
/**
|
||||
* The "config name" property name.
|
||||
*/
|
||||
public static final String CONFIG_NAME_PROPERTY = "spring.config.name";
|
||||
|
||||
/**
|
||||
* The "config location" property name.
|
||||
*/
|
||||
public static final String CONFIG_LOCATION_PROPERTY = "spring.config.location";
|
||||
|
||||
/**
|
||||
* The "config additional location" property name.
|
||||
*/
|
||||
public static final String CONFIG_ADDITIONAL_LOCATION_PROPERTY = "spring.config.additional-location";
|
||||
|
||||
/**
|
||||
* The default order for the processor.
|
||||
*/
|
||||
public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 10;
|
||||
|
||||
private final Log logger;
|
||||
|
||||
private static final Resource[] EMPTY_RESOURCES = {};
|
||||
|
||||
private static final Comparator<File> FILE_COMPARATOR = Comparator.comparing(File::getAbsolutePath);
|
||||
|
||||
private String searchLocations;
|
||||
|
||||
private String names;
|
||||
|
||||
private int order = DEFAULT_ORDER;
|
||||
|
||||
public ConfigFileApplicationListener() {
|
||||
this(new DeferredLog());
|
||||
}
|
||||
|
||||
ConfigFileApplicationListener(Log logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||
return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)
|
||||
|| ApplicationPreparedEvent.class.isAssignableFrom(eventType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
throw new IllegalStateException("ConfigFileApplicationListener [" + getClass().getName()
|
||||
+ "] is deprecated and can only be used as an EnvironmentPostProcessor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
addPropertySources(environment, application.getResourceLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add config file property sources to the specified environment.
|
||||
* @param environment the environment to add source to
|
||||
* @param resourceLoader the resource loader
|
||||
* @see #addPostProcessors(ConfigurableApplicationContext)
|
||||
*/
|
||||
protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
|
||||
RandomValuePropertySource.addToEnvironment(environment);
|
||||
new Loader(environment, resourceLoader).load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add appropriate post-processors to post-configure the property-sources.
|
||||
* @param context the context to configure
|
||||
*/
|
||||
protected void addPostProcessors(ConfigurableApplicationContext context) {
|
||||
context.addBeanFactoryPostProcessor(new PropertySourceOrderingPostProcessor(context));
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the search locations that will be considered as a comma-separated list. Each
|
||||
* search location should be a directory path (ending in "/") and it will be prefixed
|
||||
* by the file names constructed from {@link #setSearchNames(String) search names} and
|
||||
* profiles (if any) plus file extensions supported by the properties loaders.
|
||||
* Locations are considered in the order specified, with later items taking precedence
|
||||
* (like a map merge).
|
||||
* @param locations the search locations
|
||||
*/
|
||||
public void setSearchLocations(String locations) {
|
||||
Assert.hasLength(locations, "Locations must not be empty");
|
||||
this.searchLocations = locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the names of the files that should be loaded (excluding file extension) as a
|
||||
* comma-separated list.
|
||||
* @param names the names to load
|
||||
*/
|
||||
public void setSearchNames(String names) {
|
||||
Assert.hasLength(names, "Names must not be empty");
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanFactoryPostProcessor} to re-order our property sources below any
|
||||
* {@code @PropertySource} items added by the {@link ConfigurationClassPostProcessor}.
|
||||
*/
|
||||
private static class PropertySourceOrderingPostProcessor implements BeanFactoryPostProcessor, Ordered {
|
||||
|
||||
private final ConfigurableApplicationContext context;
|
||||
|
||||
PropertySourceOrderingPostProcessor(ConfigurableApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
reorderSources(this.context.getEnvironment());
|
||||
}
|
||||
|
||||
private void reorderSources(ConfigurableEnvironment environment) {
|
||||
DefaultPropertiesPropertySource.moveToEnd(environment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads candidate property sources and configures the active profiles.
|
||||
*/
|
||||
private class Loader {
|
||||
|
||||
private final Log logger = ConfigFileApplicationListener.this.logger;
|
||||
|
||||
private final ConfigurableEnvironment environment;
|
||||
|
||||
private final PropertySourcesPlaceholdersResolver placeholdersResolver;
|
||||
|
||||
private final ResourceLoader resourceLoader;
|
||||
|
||||
private final List<PropertySourceLoader> propertySourceLoaders;
|
||||
|
||||
private Deque<Profile> profiles;
|
||||
|
||||
private List<Profile> processedProfiles;
|
||||
|
||||
private boolean activatedProfiles;
|
||||
|
||||
private Map<Profile, MutablePropertySources> loaded;
|
||||
|
||||
private Map<DocumentsCacheKey, List<Document>> loadDocumentsCache = new HashMap<>();
|
||||
|
||||
Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
|
||||
this.environment = environment;
|
||||
this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);
|
||||
this.resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader(null);
|
||||
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,
|
||||
this.resourceLoader.getClassLoader());
|
||||
}
|
||||
|
||||
void load() {
|
||||
FilteredPropertySource.apply(this.environment, DefaultPropertiesPropertySource.NAME, LOAD_FILTERED_PROPERTY,
|
||||
this::loadWithFilteredProperties);
|
||||
}
|
||||
|
||||
private void loadWithFilteredProperties(PropertySource<?> defaultProperties) {
|
||||
this.profiles = new LinkedList<>();
|
||||
this.processedProfiles = new LinkedList<>();
|
||||
this.activatedProfiles = false;
|
||||
this.loaded = new LinkedHashMap<>();
|
||||
initializeProfiles();
|
||||
while (!this.profiles.isEmpty()) {
|
||||
Profile profile = this.profiles.poll();
|
||||
if (isDefaultProfile(profile)) {
|
||||
addProfileToEnvironment(profile.getName());
|
||||
}
|
||||
load(profile, this::getPositiveProfileFilter, addToLoaded(MutablePropertySources::addLast, false));
|
||||
this.processedProfiles.add(profile);
|
||||
}
|
||||
load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true));
|
||||
addLoadedPropertySources();
|
||||
applyActiveProfiles(defaultProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize profile information from both the {@link Environment} active
|
||||
* profiles and any {@code spring.profiles.active}/{@code spring.profiles.include}
|
||||
* properties that are already set.
|
||||
*/
|
||||
private void initializeProfiles() {
|
||||
// The default profile for these purposes is represented as null. We add it
|
||||
// first so that it is processed first and has lowest priority.
|
||||
this.profiles.add(null);
|
||||
Binder binder = Binder.get(this.environment);
|
||||
Set<Profile> activatedViaProperty = getProfiles(binder, ACTIVE_PROFILES_PROPERTY);
|
||||
Set<Profile> includedViaProperty = getProfiles(binder, INCLUDE_PROFILES_PROPERTY);
|
||||
List<Profile> otherActiveProfiles = getOtherActiveProfiles(activatedViaProperty, includedViaProperty);
|
||||
this.profiles.addAll(otherActiveProfiles);
|
||||
// Any pre-existing active profiles set via property sources (e.g.
|
||||
// System properties) take precedence over those added in config files.
|
||||
this.profiles.addAll(includedViaProperty);
|
||||
addActiveProfiles(activatedViaProperty);
|
||||
if (this.profiles.size() == 1) { // only has null profile
|
||||
for (String defaultProfileName : getDefaultProfiles(binder)) {
|
||||
Profile defaultProfile = new Profile(defaultProfileName, true);
|
||||
this.profiles.add(defaultProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getDefaultProfiles(Binder binder) {
|
||||
return binder.bind(AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, STRING_ARRAY)
|
||||
.orElseGet(this.environment::getDefaultProfiles);
|
||||
}
|
||||
|
||||
private List<Profile> getOtherActiveProfiles(Set<Profile> activatedViaProperty,
|
||||
Set<Profile> includedViaProperty) {
|
||||
return Arrays.stream(this.environment.getActiveProfiles()).map(Profile::new).filter(
|
||||
(profile) -> !activatedViaProperty.contains(profile) && !includedViaProperty.contains(profile))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
void addActiveProfiles(Set<Profile> profiles) {
|
||||
if (profiles.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (this.activatedProfiles) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Profiles already activated, '" + profiles + "' will not be applied");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.profiles.addAll(profiles);
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Activated activeProfiles " + StringUtils.collectionToCommaDelimitedString(profiles));
|
||||
}
|
||||
this.activatedProfiles = true;
|
||||
removeUnprocessedDefaultProfiles();
|
||||
}
|
||||
|
||||
private void removeUnprocessedDefaultProfiles() {
|
||||
this.profiles.removeIf((profile) -> (profile != null && profile.isDefaultProfile()));
|
||||
}
|
||||
|
||||
private DocumentFilter getPositiveProfileFilter(Profile profile) {
|
||||
return (Document document) -> {
|
||||
if (profile == null) {
|
||||
return ObjectUtils.isEmpty(document.getProfiles());
|
||||
}
|
||||
return ObjectUtils.containsElement(document.getProfiles(), profile.getName())
|
||||
&& this.environment.acceptsProfiles(Profiles.of(document.getProfiles()));
|
||||
};
|
||||
}
|
||||
|
||||
private DocumentFilter getNegativeProfileFilter(Profile profile) {
|
||||
return (Document document) -> (profile == null && !ObjectUtils.isEmpty(document.getProfiles())
|
||||
&& this.environment.acceptsProfiles(Profiles.of(document.getProfiles())));
|
||||
}
|
||||
|
||||
private DocumentConsumer addToLoaded(BiConsumer<MutablePropertySources, PropertySource<?>> addMethod,
|
||||
boolean checkForExisting) {
|
||||
return (profile, document) -> {
|
||||
if (checkForExisting) {
|
||||
for (MutablePropertySources merged : this.loaded.values()) {
|
||||
if (merged.contains(document.getPropertySource().getName())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
MutablePropertySources merged = this.loaded.computeIfAbsent(profile,
|
||||
(k) -> new MutablePropertySources());
|
||||
addMethod.accept(merged, document.getPropertySource());
|
||||
};
|
||||
}
|
||||
|
||||
private void load(Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) {
|
||||
getSearchLocations().forEach((location) -> {
|
||||
String nonOptionalLocation = ConfigDataLocation.of(location).getValue();
|
||||
boolean isDirectory = location.endsWith("/");
|
||||
Set<String> names = isDirectory ? getSearchNames() : NO_SEARCH_NAMES;
|
||||
names.forEach((name) -> load(nonOptionalLocation, name, profile, filterFactory, consumer));
|
||||
});
|
||||
}
|
||||
|
||||
private void load(String location, String name, Profile profile, DocumentFilterFactory filterFactory,
|
||||
DocumentConsumer consumer) {
|
||||
if (!StringUtils.hasText(name)) {
|
||||
for (PropertySourceLoader loader : this.propertySourceLoaders) {
|
||||
if (canLoadFileExtension(loader, location)) {
|
||||
load(loader, location, profile, filterFactory.getDocumentFilter(profile), consumer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("File extension of config file location '" + location
|
||||
+ "' is not known to any PropertySourceLoader. If the location is meant to reference "
|
||||
+ "a directory, it must end in '/'");
|
||||
}
|
||||
Set<String> processed = new HashSet<>();
|
||||
for (PropertySourceLoader loader : this.propertySourceLoaders) {
|
||||
for (String fileExtension : loader.getFileExtensions()) {
|
||||
if (processed.add(fileExtension)) {
|
||||
loadForFileExtension(loader, location + name, "." + fileExtension, profile, filterFactory,
|
||||
consumer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canLoadFileExtension(PropertySourceLoader loader, String name) {
|
||||
return Arrays.stream(loader.getFileExtensions())
|
||||
.anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(name, fileExtension));
|
||||
}
|
||||
|
||||
private void loadForFileExtension(PropertySourceLoader loader, String prefix, String fileExtension,
|
||||
Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) {
|
||||
DocumentFilter defaultFilter = filterFactory.getDocumentFilter(null);
|
||||
DocumentFilter profileFilter = filterFactory.getDocumentFilter(profile);
|
||||
if (profile != null) {
|
||||
// Try profile-specific file & profile section in profile file (gh-340)
|
||||
String profileSpecificFile = prefix + "-" + profile + fileExtension;
|
||||
load(loader, profileSpecificFile, profile, defaultFilter, consumer);
|
||||
load(loader, profileSpecificFile, profile, profileFilter, consumer);
|
||||
// Try profile specific sections in files we've already processed
|
||||
for (Profile processedProfile : this.processedProfiles) {
|
||||
if (processedProfile != null) {
|
||||
String previouslyLoaded = prefix + "-" + processedProfile + fileExtension;
|
||||
load(loader, previouslyLoaded, profile, profileFilter, consumer);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Also try the profile-specific section (if any) of the normal file
|
||||
load(loader, prefix + fileExtension, profile, profileFilter, consumer);
|
||||
}
|
||||
|
||||
private void load(PropertySourceLoader loader, String location, Profile profile, DocumentFilter filter,
|
||||
DocumentConsumer consumer) {
|
||||
Resource[] resources = getResources(location);
|
||||
for (Resource resource : resources) {
|
||||
try {
|
||||
if (resource == null || !resource.exists()) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
StringBuilder description = getDescription("Skipped missing config ", location, resource,
|
||||
profile);
|
||||
this.logger.trace(description);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!StringUtils.hasText(StringUtils.getFilenameExtension(resource.getFilename()))) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
StringBuilder description = getDescription("Skipped empty config extension ", location,
|
||||
resource, profile);
|
||||
this.logger.trace(description);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (resource.isFile() && isPatternLocation(location) && hasHiddenPathElement(resource)) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
StringBuilder description = getDescription("Skipped location with hidden path element ",
|
||||
location, resource, profile);
|
||||
this.logger.trace(description);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
String name = "applicationConfig: [" + getLocationName(location, resource) + "]";
|
||||
List<Document> documents = loadDocuments(loader, name, resource);
|
||||
if (CollectionUtils.isEmpty(documents)) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
StringBuilder description = getDescription("Skipped unloaded config ", location, resource,
|
||||
profile);
|
||||
this.logger.trace(description);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
List<Document> loaded = new ArrayList<>();
|
||||
for (Document document : documents) {
|
||||
if (filter.match(document)) {
|
||||
addActiveProfiles(document.getActiveProfiles());
|
||||
addIncludedProfiles(document.getIncludeProfiles());
|
||||
loaded.add(document);
|
||||
}
|
||||
}
|
||||
Collections.reverse(loaded);
|
||||
if (!loaded.isEmpty()) {
|
||||
loaded.forEach((document) -> consumer.accept(profile, document));
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
StringBuilder description = getDescription("Loaded config file ", location, resource,
|
||||
profile);
|
||||
this.logger.debug(description);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
StringBuilder description = getDescription("Failed to load property source from ", location,
|
||||
resource, profile);
|
||||
throw new IllegalStateException(description.toString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasHiddenPathElement(Resource resource) throws IOException {
|
||||
String cleanPath = StringUtils.cleanPath(resource.getFile().getAbsolutePath());
|
||||
for (Path value : Paths.get(cleanPath)) {
|
||||
if (value.toString().startsWith("..")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getLocationName(String locationReference, Resource resource) {
|
||||
if (!locationReference.contains("*")) {
|
||||
return locationReference;
|
||||
}
|
||||
if (resource instanceof FileSystemResource) {
|
||||
return ((FileSystemResource) resource).getPath();
|
||||
}
|
||||
return resource.getDescription();
|
||||
}
|
||||
|
||||
private Resource[] getResources(String locationReference) {
|
||||
try {
|
||||
if (isPatternLocation(locationReference)) {
|
||||
return getResourcesFromPatternLocationReference(locationReference);
|
||||
}
|
||||
return new Resource[] { this.resourceLoader.getResource(locationReference) };
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return EMPTY_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPatternLocation(String location) {
|
||||
return location.contains("*");
|
||||
}
|
||||
|
||||
private Resource[] getResourcesFromPatternLocationReference(String locationReference) throws IOException {
|
||||
String directoryPath = locationReference.substring(0, locationReference.indexOf("*/"));
|
||||
Resource resource = this.resourceLoader.getResource(directoryPath);
|
||||
File[] files = resource.getFile().listFiles(File::isDirectory);
|
||||
if (files != null) {
|
||||
String fileName = locationReference.substring(locationReference.lastIndexOf("/") + 1);
|
||||
Arrays.sort(files, FILE_COMPARATOR);
|
||||
return Arrays.stream(files).map((file) -> file.listFiles((dir, name) -> name.equals(fileName)))
|
||||
.filter(Objects::nonNull).flatMap((Function<File[], Stream<File>>) Arrays::stream)
|
||||
.map(FileSystemResource::new).toArray(Resource[]::new);
|
||||
}
|
||||
return EMPTY_RESOURCES;
|
||||
}
|
||||
|
||||
private void addIncludedProfiles(Set<Profile> includeProfiles) {
|
||||
LinkedList<Profile> existingProfiles = new LinkedList<>(this.profiles);
|
||||
this.profiles.clear();
|
||||
this.profiles.addAll(includeProfiles);
|
||||
this.profiles.removeAll(this.processedProfiles);
|
||||
this.profiles.addAll(existingProfiles);
|
||||
}
|
||||
|
||||
private List<Document> loadDocuments(PropertySourceLoader loader, String name, Resource resource)
|
||||
throws IOException {
|
||||
DocumentsCacheKey cacheKey = new DocumentsCacheKey(loader, resource);
|
||||
List<Document> documents = this.loadDocumentsCache.get(cacheKey);
|
||||
if (documents == null) {
|
||||
List<PropertySource<?>> loaded = loader.load(name, resource);
|
||||
documents = asDocuments(loaded);
|
||||
this.loadDocumentsCache.put(cacheKey, documents);
|
||||
}
|
||||
return documents;
|
||||
}
|
||||
|
||||
private List<Document> asDocuments(List<PropertySource<?>> loaded) {
|
||||
if (loaded == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return loaded.stream().map((propertySource) -> {
|
||||
Binder binder = new Binder(ConfigurationPropertySources.from(propertySource),
|
||||
this.placeholdersResolver);
|
||||
String[] profiles = binder.bind("spring.profiles", STRING_ARRAY).orElse(null);
|
||||
Set<Profile> activeProfiles = getProfiles(binder, ACTIVE_PROFILES_PROPERTY);
|
||||
Set<Profile> includeProfiles = getProfiles(binder, INCLUDE_PROFILES_PROPERTY);
|
||||
return new Document(propertySource, profiles, activeProfiles, includeProfiles);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private StringBuilder getDescription(String prefix, String locationReference, Resource resource,
|
||||
Profile profile) {
|
||||
StringBuilder result = new StringBuilder(prefix);
|
||||
try {
|
||||
if (resource != null) {
|
||||
String uri = resource.getURI().toASCIIString();
|
||||
result.append("'");
|
||||
result.append(uri);
|
||||
result.append("' (");
|
||||
result.append(locationReference);
|
||||
result.append(")");
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
result.append(locationReference);
|
||||
}
|
||||
if (profile != null) {
|
||||
result.append(" for profile ");
|
||||
result.append(profile);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<Profile> getProfiles(Binder binder, String name) {
|
||||
return binder.bind(name, STRING_ARRAY).map(this::asProfileSet).orElse(Collections.emptySet());
|
||||
}
|
||||
|
||||
private Set<Profile> asProfileSet(String[] profileNames) {
|
||||
List<Profile> profiles = new ArrayList<>();
|
||||
for (String profileName : profileNames) {
|
||||
profiles.add(new Profile(profileName));
|
||||
}
|
||||
return new LinkedHashSet<>(profiles);
|
||||
}
|
||||
|
||||
private void addProfileToEnvironment(String profile) {
|
||||
for (String activeProfile : this.environment.getActiveProfiles()) {
|
||||
if (activeProfile.equals(profile)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.environment.addActiveProfile(profile);
|
||||
}
|
||||
|
||||
private Set<String> getSearchLocations() {
|
||||
Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY);
|
||||
if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) {
|
||||
locations.addAll(getSearchLocations(CONFIG_LOCATION_PROPERTY));
|
||||
}
|
||||
else {
|
||||
locations.addAll(
|
||||
asResolvedSet(ConfigFileApplicationListener.this.searchLocations, DEFAULT_SEARCH_LOCATIONS));
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
private Set<String> getSearchLocations(String propertyName) {
|
||||
Set<String> locations = new LinkedHashSet<>();
|
||||
if (this.environment.containsProperty(propertyName)) {
|
||||
for (String path : asResolvedSet(this.environment.getProperty(propertyName), null)) {
|
||||
if (!path.contains("$")) {
|
||||
path = StringUtils.cleanPath(path);
|
||||
Assert.state(!path.startsWith(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX),
|
||||
"Classpath wildcard patterns cannot be used as a search location");
|
||||
validateWildcardLocation(path);
|
||||
if (!ResourceUtils.isUrl(path)) {
|
||||
path = ResourceUtils.FILE_URL_PREFIX + path;
|
||||
}
|
||||
}
|
||||
locations.add(path);
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
private void validateWildcardLocation(String path) {
|
||||
if (path.contains("*")) {
|
||||
Assert.state(StringUtils.countOccurrencesOf(path, "*") == 1,
|
||||
() -> "Search location '" + path + "' cannot contain multiple wildcards");
|
||||
String directoryPath = path.substring(0, path.lastIndexOf("/") + 1);
|
||||
Assert.state(directoryPath.endsWith("*/"), () -> "Search location '" + path + "' must end with '*/'");
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> getSearchNames() {
|
||||
if (this.environment.containsProperty(CONFIG_NAME_PROPERTY)) {
|
||||
String property = this.environment.getProperty(CONFIG_NAME_PROPERTY);
|
||||
Set<String> names = asResolvedSet(property, null);
|
||||
names.forEach(this::assertValidConfigName);
|
||||
return names;
|
||||
}
|
||||
return asResolvedSet(ConfigFileApplicationListener.this.names, DEFAULT_NAMES);
|
||||
}
|
||||
|
||||
private Set<String> asResolvedSet(String value, String fallback) {
|
||||
List<String> list = Arrays.asList(StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(
|
||||
(value != null) ? this.environment.resolvePlaceholders(value) : fallback)));
|
||||
Collections.reverse(list);
|
||||
return new LinkedHashSet<>(list);
|
||||
}
|
||||
|
||||
private void assertValidConfigName(String name) {
|
||||
Assert.state(!name.contains("*"), () -> "Config name '" + name + "' cannot contain wildcards");
|
||||
}
|
||||
|
||||
private void addLoadedPropertySources() {
|
||||
MutablePropertySources destination = this.environment.getPropertySources();
|
||||
List<MutablePropertySources> loaded = new ArrayList<>(this.loaded.values());
|
||||
Collections.reverse(loaded);
|
||||
String lastAdded = null;
|
||||
Set<String> added = new HashSet<>();
|
||||
for (MutablePropertySources sources : loaded) {
|
||||
for (PropertySource<?> source : sources) {
|
||||
if (added.add(source.getName())) {
|
||||
addLoadedPropertySource(destination, lastAdded, source);
|
||||
lastAdded = source.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addLoadedPropertySource(MutablePropertySources destination, String lastAdded,
|
||||
PropertySource<?> source) {
|
||||
if (lastAdded == null) {
|
||||
if (destination.contains(DefaultPropertiesPropertySource.NAME)) {
|
||||
destination.addBefore(DefaultPropertiesPropertySource.NAME, source);
|
||||
}
|
||||
else {
|
||||
destination.addLast(source);
|
||||
}
|
||||
}
|
||||
else {
|
||||
destination.addAfter(lastAdded, source);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyActiveProfiles(PropertySource<?> defaultProperties) {
|
||||
List<String> activeProfiles = new ArrayList<>();
|
||||
if (defaultProperties != null) {
|
||||
Binder binder = new Binder(ConfigurationPropertySources.from(defaultProperties),
|
||||
new PropertySourcesPlaceholdersResolver(this.environment));
|
||||
activeProfiles.addAll(bindStringList(binder, "spring.profiles.include"));
|
||||
if (!this.activatedProfiles) {
|
||||
activeProfiles.addAll(bindStringList(binder, "spring.profiles.active"));
|
||||
}
|
||||
}
|
||||
this.processedProfiles.stream().filter(this::isDefaultProfile).map(Profile::getName)
|
||||
.forEach(activeProfiles::add);
|
||||
this.environment.setActiveProfiles(activeProfiles.toArray(new String[0]));
|
||||
}
|
||||
|
||||
private boolean isDefaultProfile(Profile profile) {
|
||||
return profile != null && !profile.isDefaultProfile();
|
||||
}
|
||||
|
||||
private List<String> bindStringList(Binder binder, String property) {
|
||||
return binder.bind(property, STRING_LIST).orElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A Spring Profile that can be loaded.
|
||||
*/
|
||||
private static class Profile {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final boolean defaultProfile;
|
||||
|
||||
Profile(String name) {
|
||||
this(name, false);
|
||||
}
|
||||
|
||||
Profile(String name, boolean defaultProfile) {
|
||||
Assert.notNull(name, "Name must not be null");
|
||||
this.name = name;
|
||||
this.defaultProfile = defaultProfile;
|
||||
}
|
||||
|
||||
String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
boolean isDefaultProfile() {
|
||||
return this.defaultProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
return ((Profile) obj).name.equals(this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.name.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache key used to save loading the same document multiple times.
|
||||
*/
|
||||
private static class DocumentsCacheKey {
|
||||
|
||||
private final PropertySourceLoader loader;
|
||||
|
||||
private final Resource resource;
|
||||
|
||||
DocumentsCacheKey(PropertySourceLoader loader, Resource resource) {
|
||||
this.loader = loader;
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DocumentsCacheKey other = (DocumentsCacheKey) obj;
|
||||
return this.loader.equals(other.loader) && this.resource.equals(other.resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.loader.hashCode() * 31 + this.resource.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A single document loaded by a {@link PropertySourceLoader}.
|
||||
*/
|
||||
private static class Document {
|
||||
|
||||
private final PropertySource<?> propertySource;
|
||||
|
||||
private String[] profiles;
|
||||
|
||||
private final Set<Profile> activeProfiles;
|
||||
|
||||
private final Set<Profile> includeProfiles;
|
||||
|
||||
Document(PropertySource<?> propertySource, String[] profiles, Set<Profile> activeProfiles,
|
||||
Set<Profile> includeProfiles) {
|
||||
this.propertySource = propertySource;
|
||||
this.profiles = profiles;
|
||||
this.activeProfiles = activeProfiles;
|
||||
this.includeProfiles = includeProfiles;
|
||||
}
|
||||
|
||||
PropertySource<?> getPropertySource() {
|
||||
return this.propertySource;
|
||||
}
|
||||
|
||||
String[] getProfiles() {
|
||||
return this.profiles;
|
||||
}
|
||||
|
||||
Set<Profile> getActiveProfiles() {
|
||||
return this.activeProfiles;
|
||||
}
|
||||
|
||||
Set<Profile> getIncludeProfiles() {
|
||||
return this.includeProfiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.propertySource.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory used to create a {@link DocumentFilter}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
private interface DocumentFilterFactory {
|
||||
|
||||
/**
|
||||
* Create a filter for the given profile.
|
||||
* @param profile the profile or {@code null}
|
||||
* @return the filter
|
||||
*/
|
||||
DocumentFilter getDocumentFilter(Profile profile);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter used to restrict when a {@link Document} is loaded.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
private interface DocumentFilter {
|
||||
|
||||
boolean match(Document document);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumer used to handle a loaded {@link Document}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
private interface DocumentConsumer {
|
||||
|
||||
void accept(Profile profile, Document document);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.config;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.BindContext;
|
||||
import org.springframework.boot.context.properties.bind.BindException;
|
||||
import org.springframework.boot.context.properties.bind.BindHandler;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationProperty;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||
|
||||
/**
|
||||
* Exception thrown if legacy processing must be used.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
final class UseLegacyConfigProcessingException extends ConfigDataException {
|
||||
|
||||
/**
|
||||
* The property name used to trigger legacy processing.
|
||||
*/
|
||||
static final ConfigurationPropertyName PROPERTY_NAME = ConfigurationPropertyName
|
||||
.of("spring.config.use-legacy-processing");
|
||||
|
||||
private static final Bindable<Boolean> BOOLEAN = Bindable.of(Boolean.class);
|
||||
|
||||
private static final UseLegacyProcessingBindHandler BIND_HANDLER = new UseLegacyProcessingBindHandler();
|
||||
|
||||
private final ConfigurationProperty configurationProperty;
|
||||
|
||||
UseLegacyConfigProcessingException(ConfigurationProperty configurationProperty) {
|
||||
super("Legacy processing requested from " + configurationProperty, null);
|
||||
this.configurationProperty = configurationProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the source configuration property that requested the use of legacy
|
||||
* processing.
|
||||
* @return the configurationProperty the configuration property
|
||||
*/
|
||||
ConfigurationProperty getConfigurationProperty() {
|
||||
return this.configurationProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw a new {@link UseLegacyConfigProcessingException} instance if
|
||||
* {@link #PROPERTY_NAME} binds to {@code true}.
|
||||
* @param binder the binder to use
|
||||
*/
|
||||
static void throwIfRequested(Binder binder) {
|
||||
try {
|
||||
binder.bind(PROPERTY_NAME, BOOLEAN, BIND_HANDLER);
|
||||
}
|
||||
catch (BindException ex) {
|
||||
if (ex.getCause() instanceof UseLegacyConfigProcessingException) {
|
||||
throw (UseLegacyConfigProcessingException) ex.getCause();
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BindHandler} used to check for legacy processing properties.
|
||||
*/
|
||||
private static class UseLegacyProcessingBindHandler implements BindHandler {
|
||||
|
||||
@Override
|
||||
public Object onSuccess(ConfigurationPropertyName name, Bindable<?> target, BindContext context,
|
||||
Object result) {
|
||||
if (Boolean.TRUE.equals(result)) {
|
||||
throw new UseLegacyConfigProcessingException(context.getConfigurationProperty());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.jdbc;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.jdbc.support.JdbcUtils;
|
||||
import org.springframework.jdbc.support.MetaDataAccessException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class used for {@link DataSource} initialization.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.5.0
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0 in favor of
|
||||
* {@link DataSourceScriptDatabaseInitializer}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractDataSourceInitializer implements InitializingBean {
|
||||
|
||||
private static final String PLATFORM_PLACEHOLDER = "@@platform@@";
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
private final ResourceLoader resourceLoader;
|
||||
|
||||
protected AbstractDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader) {
|
||||
Assert.notNull(dataSource, "DataSource must not be null");
|
||||
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
|
||||
this.dataSource = dataSource;
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
||||
String schemaLocation = getSchemaLocation();
|
||||
if (schemaLocation.contains(PLATFORM_PLACEHOLDER)) {
|
||||
String platform = getDatabaseName();
|
||||
schemaLocation = schemaLocation.replace(PLATFORM_PLACEHOLDER, platform);
|
||||
}
|
||||
populator.addScript(this.resourceLoader.getResource(schemaLocation));
|
||||
populator.setContinueOnError(true);
|
||||
customize(populator);
|
||||
DatabasePopulatorUtils.execute(populator, this.dataSource);
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
if (getMode() == DataSourceInitializationMode.NEVER) {
|
||||
return false;
|
||||
}
|
||||
return getMode() != DataSourceInitializationMode.EMBEDDED
|
||||
|| EmbeddedDatabaseConnection.isEmbedded(this.dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the {@link ResourceDatabasePopulator}.
|
||||
* @param populator the configured database populator
|
||||
*/
|
||||
protected void customize(ResourceDatabasePopulator populator) {
|
||||
}
|
||||
|
||||
protected abstract DataSourceInitializationMode getMode();
|
||||
|
||||
protected abstract String getSchemaLocation();
|
||||
|
||||
protected String getDatabaseName() {
|
||||
try {
|
||||
String productName = JdbcUtils.commonDatabaseName(
|
||||
JdbcUtils.extractDatabaseMetaData(this.dataSource, DatabaseMetaData::getDatabaseProductName));
|
||||
DatabaseDriver databaseDriver = DatabaseDriver.fromProductName(productName);
|
||||
if (databaseDriver == DatabaseDriver.UNKNOWN) {
|
||||
throw new IllegalStateException("Unable to detect database type");
|
||||
}
|
||||
return databaseDriver.getId();
|
||||
}
|
||||
catch (MetaDataAccessException ex) {
|
||||
throw new IllegalStateException("Unable to detect database type", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.jdbc;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.sql.init.dependency.AbstractBeansOfTypeDatabaseInitializerDetector;
|
||||
import org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* A {@link DatabaseInitializerDetector} for {@link AbstractDataSourceInitializer}.
|
||||
*
|
||||
* @author Henning Pöttker
|
||||
*/
|
||||
@Deprecated
|
||||
class AbstractDataSourceInitializerDatabaseInitializerDetector extends AbstractBeansOfTypeDatabaseInitializerDetector {
|
||||
|
||||
private static final int PRECEDENCE = Ordered.LOWEST_PRECEDENCE - 100;
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getDatabaseInitializerBeanTypes() {
|
||||
return Collections.singleton(AbstractDataSourceInitializer.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return PRECEDENCE;
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.jdbc;
|
||||
|
||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||
|
||||
/**
|
||||
* Supported {@link javax.sql.DataSource} initialization modes.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
* @see AbstractDataSourceInitializer
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0 in favor of
|
||||
* {@link DatabaseInitializationMode}
|
||||
*/
|
||||
@Deprecated
|
||||
public enum DataSourceInitializationMode {
|
||||
|
||||
/**
|
||||
* Always initialize the datasource.
|
||||
*/
|
||||
ALWAYS,
|
||||
|
||||
/**
|
||||
* Only initialize an embedded datasource.
|
||||
*/
|
||||
EMBEDDED,
|
||||
|
||||
/**
|
||||
* Do not initialize the datasource.
|
||||
*/
|
||||
NEVER
|
||||
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.orm.jpa.hibernate;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy;
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
|
||||
/**
|
||||
* Hibernate {@link PhysicalNamingStrategy} that follows Spring recommended naming
|
||||
* conventions.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Madhura Bhave
|
||||
* @since 1.4.0
|
||||
* @deprecated since 2.6.0 for removal in 2.8.0 in favor of
|
||||
* {@link CamelCaseToUnderscoresNamingStrategy}
|
||||
*/
|
||||
@Deprecated
|
||||
public class SpringPhysicalNamingStrategy implements PhysicalNamingStrategy {
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
|
||||
for (int i = 1; i < builder.length() - 1; i++) {
|
||||
if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i), builder.charAt(i + 1))) {
|
||||
builder.insert(i++, '_');
|
||||
}
|
||||
}
|
||||
return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an identifier for the specified details. By default this method will return an
|
||||
* identifier with the name adapted based on the result of
|
||||
* {@link #isCaseInsensitive(JdbcEnvironment)}
|
||||
* @param name the name of the identifier
|
||||
* @param quoted if the identifier is quoted
|
||||
* @param jdbcEnvironment the JDBC environment
|
||||
* @return an identifier instance
|
||||
*/
|
||||
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
|
||||
if (isCaseInsensitive(jdbcEnvironment)) {
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
return new Identifier(name, quoted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the database is case sensitive.
|
||||
* @param jdbcEnvironment the JDBC environment which can be used to determine case
|
||||
* @return true if the database is case insensitive sensitivity
|
||||
*/
|
||||
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isUnderscoreRequired(char before, char current, char after) {
|
||||
return Character.isLowerCase(before) && Character.isUpperCase(current) && Character.isLowerCase(after);
|
||||
}
|
||||
|
||||
}
|
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.config;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Profiles;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests to reproduce reported issues.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
* @author Nguyen Bao Sach
|
||||
*/
|
||||
@ExtendWith(UseLegacyProcessing.class)
|
||||
class ConfigFileApplicationListenerLegacyReproTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void enableProfileViaApplicationProperties() {
|
||||
// gh-308
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
this.context = application.run("--spring.config.name=enableprofileviaapplicationproperties",
|
||||
"--spring.profiles.active=dev");
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("dev"))).isTrue();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("a"))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeProfilesWithYamlAndCommandLine() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro";
|
||||
this.context = application.run(configName, "--spring.profiles.active=B");
|
||||
assertVersionProperty(this.context, "B", "B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeProfilesWithYamlOnly() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro";
|
||||
this.context = application.run(configName);
|
||||
assertVersionProperty(this.context, "B", "B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void orderActiveProfilesWithYamlOnly() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro-ordered";
|
||||
this.context = application.run(configName);
|
||||
assertVersionProperty(this.context, "B", "A", "B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void commandLineBeatsProfilesWithYaml() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro";
|
||||
this.context = application.run(configName, "--spring.profiles.active=C");
|
||||
assertVersionProperty(this.context, "C", "C");
|
||||
}
|
||||
|
||||
@Test
|
||||
void orderProfilesWithYaml() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro";
|
||||
this.context = application.run(configName, "--spring.profiles.active=A,C");
|
||||
assertVersionProperty(this.context, "C", "A", "C");
|
||||
}
|
||||
|
||||
@Test
|
||||
void reverseOrderOfProfilesWithYaml() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro";
|
||||
this.context = application.run(configName, "--spring.profiles.active=C,A");
|
||||
assertVersionProperty(this.context, "A", "C", "A");
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeProfilesWithYamlAndCommandLineAndNoOverride() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro-without-override";
|
||||
this.context = application.run(configName, "--spring.profiles.active=B");
|
||||
assertVersionProperty(this.context, "B", "B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeProfilesWithYamlOnlyAndNoOverride() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro-without-override";
|
||||
this.context = application.run(configName);
|
||||
assertVersionProperty(this.context, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void commandLineBeatsProfilesWithYamlAndNoOverride() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro-without-override";
|
||||
this.context = application.run(configName, "--spring.profiles.active=C");
|
||||
assertVersionProperty(this.context, "C", "C");
|
||||
}
|
||||
|
||||
@Test
|
||||
void orderProfilesWithYamlAndNoOverride() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro-without-override";
|
||||
this.context = application.run(configName, "--spring.profiles.active=A,C");
|
||||
assertVersionProperty(this.context, "C", "A", "C");
|
||||
}
|
||||
|
||||
@Test
|
||||
void reverseOrderOfProfilesWithYamlAndNoOverride() {
|
||||
// gh-322, gh-342
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=activeprofilerepro-without-override";
|
||||
this.context = application.run(configName, "--spring.profiles.active=C,A");
|
||||
assertVersionProperty(this.context, "A", "C", "A");
|
||||
}
|
||||
|
||||
private void assertVersionProperty(ConfigurableApplicationContext context, String expectedVersion,
|
||||
String... expectedActiveProfiles) {
|
||||
assertThat(context.getEnvironment().getActiveProfiles()).isEqualTo(expectedActiveProfiles);
|
||||
assertThat(context.getEnvironment().getProperty("version")).as("version mismatch").isEqualTo(expectedVersion);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.config;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConfigFileApplicationListener} handling of negated profiles in yaml
|
||||
* configuration files.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@ExtendWith(UseLegacyProcessing.class)
|
||||
class ConfigFileApplicationListenerYamlProfileNegationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileNegationDefaultProfile() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=profilenegation";
|
||||
this.context = application.run(configName);
|
||||
assertVersionProperty(this.context, "NOT A");
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileNegationWithActiveProfile() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=profilenegation";
|
||||
this.context = application.run(configName, "--spring.profiles.active=C,A");
|
||||
assertVersionProperty(this.context, null, "C", "A");
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileNegationLocalActiveProfiles() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=profilenegation-local-active-profiles";
|
||||
this.context = application.run(configName);
|
||||
assertVersionProperty(this.context, "NOT A", "B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileNegationOverrideLocalActiveProfiles() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=profilenegation-local-active-profiles";
|
||||
this.context = application.run(configName, "--spring.profiles.active=C,A");
|
||||
assertVersionProperty(this.context, null, "C", "A");
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileNegationWithProfileSpecificFile() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=profilenegation";
|
||||
this.context = application.run(configName, "--spring.profiles.active=C,B");
|
||||
assertVersionProperty(this.context, "NOT A", "C", "B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileCascading() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=cascadingprofiles";
|
||||
this.context = application.run(configName);
|
||||
assertVersionProperty(this.context, "D", "A", "C", "E", "B", "D");
|
||||
assertThat(this.context.getEnvironment().getProperty("not-a")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-b")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-c")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-d")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-e")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileCascadingOverrideProfilesA() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=cascadingprofiles";
|
||||
this.context = application.run(configName, "--spring.profiles.active=A");
|
||||
assertVersionProperty(this.context, "E", "A", "C", "E");
|
||||
assertThat(this.context.getEnvironment().getProperty("not-a")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-b")).isEqualTo("true");
|
||||
assertThat(this.context.getEnvironment().getProperty("not-c")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-d")).isEqualTo("true");
|
||||
assertThat(this.context.getEnvironment().getProperty("not-e")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileCascadingMultipleActiveProfilesViaPropertiesShouldPreserveOrder() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=cascadingprofiles";
|
||||
this.context = application.run(configName, "--spring.profiles.active=A,B");
|
||||
assertVersionProperty(this.context, "D", "A", "C", "E", "B", "D");
|
||||
assertThat(this.context.getEnvironment().getProperty("not-a")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-b")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-c")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-d")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-e")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void yamlProfileCascadingOverrideProfilesB() {
|
||||
SpringApplication application = new SpringApplication(Config.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
String configName = "--spring.config.name=cascadingprofiles";
|
||||
this.context = application.run(configName, "--spring.profiles.active=B");
|
||||
assertVersionProperty(this.context, "E", "B", "D", "E");
|
||||
assertThat(this.context.getEnvironment().getProperty("not-a")).isEqualTo("true");
|
||||
assertThat(this.context.getEnvironment().getProperty("not-b")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-c")).isEqualTo("true");
|
||||
assertThat(this.context.getEnvironment().getProperty("not-d")).isNull();
|
||||
assertThat(this.context.getEnvironment().getProperty("not-e")).isNull();
|
||||
}
|
||||
|
||||
private void assertVersionProperty(ConfigurableApplicationContext context, String expectedVersion,
|
||||
String... expectedActiveProfiles) {
|
||||
assertThat(context.getEnvironment().getActiveProfiles()).isEqualTo(expectedActiveProfiles);
|
||||
assertThat(context.getEnvironment().getProperty("version")).as("version mismatch").isEqualTo(expectedVersion);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.config;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.MockConfigurationPropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link UseLegacyConfigProcessingException}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class UseLegacyConfigProcessingExceptionTests {
|
||||
|
||||
@Test
|
||||
void throwIfRequestedWhenMissingDoesNothing() {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
Binder binder = new Binder(source);
|
||||
UseLegacyConfigProcessingException.throwIfRequested(binder);
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwIfRequestedWhenFalseDoesNothing() {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
source.put("spring.config.use-legacy-processing", "false");
|
||||
Binder binder = new Binder(source);
|
||||
UseLegacyConfigProcessingException.throwIfRequested(binder);
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwIfRequestedWhenTrueThrowsException() {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
source.put("spring.config.use-legacy-processing", "true");
|
||||
Binder binder = new Binder(source);
|
||||
assertThatExceptionOfType(UseLegacyConfigProcessingException.class)
|
||||
.isThrownBy(() -> UseLegacyConfigProcessingException.throwIfRequested(binder))
|
||||
.satisfies((ex) -> assertThat(ex.getConfigurationProperty().getName())
|
||||
.hasToString("spring.config.use-legacy-processing"));
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.config;
|
||||
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.Extension;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
/**
|
||||
* JUnit {@link Extension @Extension} to switch a test to use legacy processing.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class UseLegacyProcessing implements BeforeAllCallback, AfterAllCallback {
|
||||
|
||||
private static final String PROPERTY_NAME = "spring.config.use-legacy-processing";
|
||||
|
||||
private String propertyValue;
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) throws Exception {
|
||||
this.propertyValue = System.setProperty(PROPERTY_NAME, "true");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) throws Exception {
|
||||
if (this.propertyValue != null) {
|
||||
System.setProperty(PROPERTY_NAME, this.propertyValue);
|
||||
}
|
||||
else {
|
||||
System.clearProperty(PROPERTY_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.jdbc;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
|
||||
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for the configuration of dependencies on {@link AbstractDataSourceInitializer}
|
||||
* beans.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Deprecated
|
||||
class AbstractDataSourceInitializerDependencyConfigurationTests {
|
||||
|
||||
@Test
|
||||
void beansThatDependOnDatabaseInitializationDependOnAbstractDataSourceInitializerBeans() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
TestConfiguration.class)) {
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("factoryMethodDependsOnDatabaseInitialization")
|
||||
.getDependsOn()).contains("initializer");
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("beanClassDependsOnDatabaseInitialization")
|
||||
.getDependsOn()).contains("initializer");
|
||||
}
|
||||
}
|
||||
|
||||
@Import(DatabaseInitializationDependencyConfigurer.class)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
DataSource dataSource() {
|
||||
return DataSourceBuilder.create().build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOnDatabaseInitialization
|
||||
String factoryMethodDependsOnDatabaseInitialization() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Bean
|
||||
DatabaseInitializationDependent beanClassDependsOnDatabaseInitialization() {
|
||||
return new DatabaseInitializationDependent();
|
||||
}
|
||||
|
||||
@Bean
|
||||
AbstractDataSourceInitializer initializer(DataSource dataSource, ResourceLoader resourceLoader) {
|
||||
return new AbstractDataSourceInitializer(dataSource, resourceLoader) {
|
||||
|
||||
@Override
|
||||
protected String getSchemaLocation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSourceInitializationMode getMode() {
|
||||
return DataSourceInitializationMode.NEVER;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@DependsOnDatabaseInitialization
|
||||
static class DatabaseInitializationDependent {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.orm.jpa.hibernate;
|
||||
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringPhysicalNamingStrategy}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Deprecated
|
||||
class SpringPhysicalNamingStrategyTests {
|
||||
|
||||
private Metadata metadata;
|
||||
|
||||
private MetadataSources metadataSources;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.metadataSources = new MetadataSources(createServiceRegistry());
|
||||
this.metadataSources.addAnnotatedClass(TelephoneNumber.class);
|
||||
this.metadata = this.metadataSources.getMetadataBuilder()
|
||||
.applyPhysicalNamingStrategy(new SpringPhysicalNamingStrategy()).build();
|
||||
}
|
||||
|
||||
private StandardServiceRegistry createServiceRegistry() {
|
||||
return new StandardServiceRegistryBuilder().applySetting(AvailableSettings.DIALECT, H2Dialect.class).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void tableNameShouldBeLowercaseUnderscore() {
|
||||
PersistentClass binding = this.metadata.getEntityBinding(TelephoneNumber.class.getName());
|
||||
assertThat(binding.getTable().getQuotedName()).isEqualTo("telephone_number");
|
||||
}
|
||||
|
||||
@Test
|
||||
void tableNameShouldNotBeLowerCaseIfCaseSensitive() {
|
||||
this.metadata = this.metadataSources.getMetadataBuilder()
|
||||
.applyPhysicalNamingStrategy(new TestSpringPhysicalNamingStrategy()).build();
|
||||
PersistentClass binding = this.metadata.getEntityBinding(TelephoneNumber.class.getName());
|
||||
assertThat(binding.getTable().getQuotedName()).isEqualTo("Telephone_Number");
|
||||
}
|
||||
|
||||
private class TestSpringPhysicalNamingStrategy extends SpringPhysicalNamingStrategy {
|
||||
|
||||
@Override
|
||||
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.orm.jpa.hibernate;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
/**
|
||||
* Simple entity used in {@link SpringPhysicalNamingStrategyTests}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Entity
|
||||
public class TelephoneNumber {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
String areaCode;
|
||||
|
||||
String number;
|
||||
|
||||
}
|
Loading…
Reference in New Issue