pull/653/head
Phillip Webb 11 years ago
parent 8295e82ea0
commit 2bb0f744e0

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2014 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.
@ -119,36 +119,13 @@ public enum EmbeddedDatabaseConnection {
* @return true if the data sourceis one of the embedded types
*/
public static boolean isEmbedded(DataSource dataSource) {
boolean embedded = false;
try {
embedded = new JdbcTemplate(dataSource)
.execute(new ConnectionCallback<Boolean>() {
@Override
public Boolean doInConnection(Connection con)
throws SQLException, DataAccessException {
String productName = con.getMetaData()
.getDatabaseProductName();
if (productName == null) {
return false;
}
productName = productName.toUpperCase();
if (productName.contains(H2.name())) {
return true;
}
if (productName.contains(HSQL.name())) {
return true;
}
if (productName.contains(DERBY.name())) {
return true;
}
return false;
}
});
return new JdbcTemplate(dataSource).execute(new IsEmbedded());
}
catch (DataAccessException e) {
catch (DataAccessException ex) {
// Could not connect, which means it's not embedded
return false;
}
return embedded;
}
/**
@ -170,4 +147,27 @@ public enum EmbeddedDatabaseConnection {
return NONE;
}
/**
* {@link ConnectionCallback} to determine if a connection is embedded.
*/
private static class IsEmbedded implements ConnectionCallback<Boolean> {
@Override
public Boolean doInConnection(Connection connection) throws SQLException,
DataAccessException {
String productName = connection.getMetaData().getDatabaseProductName();
if (productName == null) {
return false;
}
productName = productName.toUpperCase();
EmbeddedDatabaseConnection[] candidates = EmbeddedDatabaseConnection.values();
for (EmbeddedDatabaseConnection candidate : candidates) {
if (candidate != NONE && productName.contains(candidate.name())) {
return true;
}
}
return false;
}
}
}

@ -28,6 +28,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.util.StringUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link JmsTemplate}.
@ -64,25 +65,22 @@ public class JmsTemplateAutoConfiguration {
@Bean
public ConnectionFactory jmsConnectionFactory() {
ConnectionFactory connectionFactory;
if (this.config.getUser() != null && !"".equals(this.config.getUser())
&& this.config.getPassword() != null
&& !"".equals(this.config.getPassword())) {
connectionFactory = new ActiveMQConnectionFactory(this.config.getUser(),
this.config.getPassword(), this.config.getBrokerUrl());
}
else {
connectionFactory = new ActiveMQConnectionFactory(
this.config.getBrokerUrl());
}
ConnectionFactory connectionFactory = getActiveMQConnectionFactory();
if (this.config.isPooled()) {
PooledConnectionFactory pool = new PooledConnectionFactory();
pool.setConnectionFactory(connectionFactory);
return pool;
}
else {
return connectionFactory;
return connectionFactory;
}
private ConnectionFactory getActiveMQConnectionFactory() {
if (StringUtils.hasLength(this.config.getUser())
&& StringUtils.hasLength(this.config.getPassword())) {
return new ActiveMQConnectionFactory(this.config.getUser(),
this.config.getPassword(), this.config.getBrokerUrl());
}
return new ActiveMQConnectionFactory(this.config.getBrokerUrl());
}
}

@ -935,14 +935,14 @@ and {sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[`JpaBas
for more details.
[[howto-use-custom-entity-manager]]
=== Use a custom EntityManagerFactory
To take full control of the configuration of the
`EntityManagerFactory`, you need to add a `@Bean` named
"entityManagerFactory". To avoid eager initialization of JPA
infrastructure Spring Boot autoconfiguration does not switch on its
entity manager based on the presence of a bean of that type. Instead
it has to do it by name.
To take full control of the configuration of the `EntityManagerFactory`, you need to add
a `@Bean` named "entityManagerFactory". To avoid eager initialization of JPA
infrastructure, Spring Boot auto-configuration does not switch on its entity manager
based on the presence of a bean of that type. Instead it has to do it by name.
[[howto-use-traditional-persistence-xml]]
@ -1140,9 +1140,12 @@ use this in a webapp is to inject it into a void method in a
}
----
You will get the best results if you put this in a nested class, or a standalone class (i.e.
not mixed in with a lot of other `@Beans` that might be allowed to influence the order of
instantiation). The https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-secure[secure web sample] is a useful template to follow.
You will get the best results if you put this in a nested class, or a standalone class
(i.e. not mixed in with a lot of other `@Beans` that might be allowed to influence the
order of instantiation). The {github-code}/spring-boot-samples/spring-boot-sample-web-secure[secure web sample]
is a useful template to follow.
[[howto-enable-https]]
=== Enable HTTPS

@ -251,8 +251,8 @@ all non-sensitive endpoints to be exposed over HTTP. The default convention is t
[[production-ready-sensitive-endpoints]]
=== Exposing sensitive endpoints
If you use ``Spring Security'' sensitive endpoints will be exposed over HTTP, but also
protected. By default ``basic'' authentication will be used with the username `user`
If you use ``Spring Security'' sensitive endpoints will be exposed over HTTP, but also
protected. By default ``basic'' authentication will be used with the username `user`
and a generated password (which is printed on the console when the application starts).
TIP: Generated passwords are logged as the application starts. Search for ``Using default
@ -300,11 +300,10 @@ The `management.port` property can be used to change the HTTP port.
management.port=8081
----
Since your management
port is often protected by a firewall, and not exposed to the public you might not need
security on the management endpoints, even if your main application is secure. In that
case you will have Spring
Security on the classpath, and you can disable management security like this:
Since your management port is often protected by a firewall, and not exposed to the public
you might not need security on the management endpoints, even if your main application is
secure. In that case you will have Spring Security on the classpath, and you can disable
management security like this:
[source,properties,indent=0]
----
@ -314,6 +313,8 @@ Security on the classpath, and you can disable management security like this:
(If you don't have Spring Security on the classpath then there is no need to explicitly
disable the management security in this way, and it might even break the application.)
[[production-ready-customizing-management-server-address]]
=== Customizing the management server address
You can customize the address that the management endpoints are available on by

@ -993,6 +993,8 @@ packaged as an executable archive), there are some limitations in the JSP suppor
There is a {github-code}/spring-boot-samples/spring-boot-sample-web-jsp[JSP sample] so
you can see how to set things up.
[[boot-features-security]]
== Security
If Spring Security is on the classpath then web applications will be secure by default
@ -1001,58 +1003,47 @@ application you can also add `@EnableGlobalMethodSecurity` with your desired set
Additional information can be found in the {spring-security-reference}#jc-method[Spring
Security Reference].
The default `AuthenticationManager` has a single user (username
``user'' and password random, printed at INFO level when the
application starts up). You can change the password by providing a
`security.user.password`. This and other useful properties are
externalized via
{sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`]
The default `AuthenticationManager` has a single user (username ``user'' and password
random, printed at INFO level when the application starts up). You can change the
password by providing a `security.user.password`. This and other useful properties are
externalized via {sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`]
(properties prefix "security").
The default security configuration is implemented in
`SecurityAutoConfiguration` and in the classes imported from there
(`SpringBootWebSecurityConfiguration` for web security and
`AuthenticationManagerConfiguration` for authentication configuration
which is also relevant in non-web applications). To switch off the
Boot default configuration completely in a web application you can add
a bean with `@EnableWebSecurity`. To customize it you normally use
external properties and beans of type `WebConfigurerAdapter` (e.g. to
The default security configuration is implemented in `SecurityAutoConfiguration` and in
the classes imported from there (`SpringBootWebSecurityConfiguration` for web security
and `AuthenticationManagerConfiguration` for authentication configuration which is also
relevant in non-web applications). To switch off the Boot default configuration
completely in a web application you can add a bean with `@EnableWebSecurity`. To customize
it you normally use external properties and beans of type `WebConfigurerAdapter` (e.g. to
add form-based login). There are several secure applications in the
{github-code}/spring-boot-samples/[Spring Boot samples] to get you
started with common use cases.
The basic features you get out of the box in a web application are
* An `AuthenticationManager` bean with in-memory store and a single
user (see `SecurityProperties.User` for the properties of the user).
{github-code}/spring-boot-samples/[Spring Boot samples] to get you started with common
use cases.
* Ignored (unsecure) paths for common static resource locations
(`/css/**`, `/js/**`, `/images/**` and `**/favicon.ico`).
The basic features you get out of the box in a web application are:
* An `AuthenticationManager` bean with in-memory store and a single user (see
`SecurityProperties.User` for the properties of the user).
* Ignored (unsecure) paths for common static resource locations (`/css/**`, `/js/**`,
`/images/**` and `**/favicon.ico`).
* HTTP Basic security for all other endpoints.
* Security events published to Spring's `ApplicationEventPublisher` (successful and
unsuccessful authentication and access denied).
* Common low-level features (HSTS, XSS, CSRF, caching) provided by Spring Security are
on by default.
* Security events published to Spring's `ApplicationEventPublisher`
(successful and unsuccessful authentication and access denied).
* Common low-level features (HSTS, XSS, CSRF, caching) provided by Spring
Security are on by default.
All of the above can be switched on and off or modified using external
properties (`security.*`).
All of the above can be switched on and off or modified using external properties
(`security.*`).
If the Actuator is also in use, you will find:
* The management endpoints are secure even if the application
endpoints are unsecure.
* The management endpoints are secure even if the application endpoints are unsecure.
* Security events are transformed into `AuditEvents` and published to the `AuditService`.
* The default user will have the "ADMIN" role as well as the "USER" role.
* Security events are transformed into `AuditEvents` and published to
the `AuditService`.
The Actuator security features can be modified using external properties
(`management.security.*`).
* The default user will have the "ADMIN" role as well as the "USER"
role.
The Actuator security features can be modified using external
properties (`management.security.*`).
[[boot-features-sql]]
== Working with SQL databases
@ -1299,12 +1290,12 @@ following to your `application.properties`.
spring.jpa.hibernate.ddl-auto=create-drop
----
Note that Hibernate's own internal property name for this (if you
happen to remember it better) is `hibernate.hbm2ddl.auto`. You can set
it, along with other Hibernate native properties, using
`spring.jpa.properties.*` (the prefix is stripped before adding them
to the entity manager). Also relevant:
`spring.jpa.generate-ddl=false` switches off all DDL generation.
NOTE: Hibernate's own internal property name for this (if you happen to remember it
better) is `hibernate.hbm2ddl.auto`. You can set it, along with other Hibernate native
properties, using `spring.jpa.properties.*` (the prefix is stripped before adding them
to the entity manager). Alternatively, `spring.jpa.generate-ddl=false` switches off all
DDL generation.
[[boot-features-nosql]]

@ -35,7 +35,7 @@ import org.springframework.boot.loader.tools.MainClassFinder;
/**
* Run the project from Gradle.
*
*
* @author Dave Syer
*/
public class RunApp extends DefaultTask {
@ -75,7 +75,7 @@ public class RunApp extends DefaultTask {
}
if (outputDir != null) {
for (File directory : allResources) {
FileUtils.removeDuplicatesFromCopy(outputDir, directory);
FileUtils.removeDuplicatesFromOutputDirectory(outputDir, directory);
}
}
exec.exec();

@ -1,9 +1,9 @@
/*
* originright 2012-2013 the copyal author or authors.
* Copyright 2012-2014 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 origin of the License at
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
@ -26,24 +26,24 @@ import java.io.File;
public class FileUtils {
/**
* Utility to remove duplicate files from a "copy" directory if they already exist in
* an "origin". Recursively scans the origin directory looking for files (not
* Utility to remove duplicate files from an "output" directory if they already exist
* in an "origin". Recursively scans the origin directory looking for files (not
* directories) that exist in both places and deleting the copy.
*
* @param copy the copy directory
* @param origin the origin directory
* @param outputDirectory the output directory
* @param originDirectory the origin directory
*/
public static void removeDuplicatesFromCopy(File copy, File origin) {
if (origin.isDirectory()) {
for (String name : origin.list()) {
File targetFile = new File(copy, name);
public static void removeDuplicatesFromOutputDirectory(File outputDirectory,
File originDirectory) {
if (originDirectory.isDirectory()) {
for (String name : originDirectory.list()) {
File targetFile = new File(outputDirectory, name);
if (targetFile.exists() && targetFile.canWrite()) {
if (!targetFile.isDirectory()) {
targetFile.delete();
}
else {
FileUtils.removeDuplicatesFromCopy(targetFile, new File(origin,
name));
FileUtils.removeDuplicatesFromOutputDirectory(targetFile,
new File(originDirectory, name));
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2014 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.
@ -27,60 +27,67 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Tests fir {@link FileUtils}.
*
* @author Dave Syer
*/
public class FileUtilsTests {
private File origin;
private File target;
private File outputDirectory;
private File originDirectory;
@Before
public void init() {
this.origin = new File("target/test/remove");
this.target = new File("target/test/keep");
FileSystemUtils.deleteRecursively(this.origin);
FileSystemUtils.deleteRecursively(this.target);
this.origin.mkdirs();
this.target.mkdirs();
this.outputDirectory = new File("target/test/remove");
this.originDirectory = new File("target/test/keep");
FileSystemUtils.deleteRecursively(this.outputDirectory);
FileSystemUtils.deleteRecursively(this.originDirectory);
this.outputDirectory.mkdirs();
this.originDirectory.mkdirs();
}
@Test
public void simpleDuplicateFile() throws IOException {
File file = new File(this.origin, "logback.xml");
File file = new File(this.outputDirectory, "logback.xml");
file.createNewFile();
new File(this.target, "logback.xml").createNewFile();
FileUtils.removeDuplicatesFromCopy(this.origin, this.target);
new File(this.originDirectory, "logback.xml").createNewFile();
FileUtils.removeDuplicatesFromOutputDirectory(this.outputDirectory,
this.originDirectory);
assertFalse(file.exists());
}
@Test
public void nestedDuplicateFile() throws IOException {
assertTrue(new File(this.origin, "sub").mkdirs());
assertTrue(new File(this.target, "sub").mkdirs());
File file = new File(this.origin, "sub/logback.xml");
assertTrue(new File(this.outputDirectory, "sub").mkdirs());
assertTrue(new File(this.originDirectory, "sub").mkdirs());
File file = new File(this.outputDirectory, "sub/logback.xml");
file.createNewFile();
new File(this.target, "sub/logback.xml").createNewFile();
FileUtils.removeDuplicatesFromCopy(this.origin, this.target);
new File(this.originDirectory, "sub/logback.xml").createNewFile();
FileUtils.removeDuplicatesFromOutputDirectory(this.outputDirectory,
this.originDirectory);
assertFalse(file.exists());
}
@Test
public void nestedNonDuplicateFile() throws IOException {
assertTrue(new File(this.origin, "sub").mkdirs());
assertTrue(new File(this.target, "sub").mkdirs());
File file = new File(this.origin, "sub/logback.xml");
assertTrue(new File(this.outputDirectory, "sub").mkdirs());
assertTrue(new File(this.originDirectory, "sub").mkdirs());
File file = new File(this.outputDirectory, "sub/logback.xml");
file.createNewFile();
new File(this.target, "sub/different.xml").createNewFile();
FileUtils.removeDuplicatesFromCopy(this.origin, this.target);
new File(this.originDirectory, "sub/different.xml").createNewFile();
FileUtils.removeDuplicatesFromOutputDirectory(this.outputDirectory,
this.originDirectory);
assertTrue(file.exists());
}
@Test
public void nonDuplicateFile() throws IOException {
File file = new File(this.origin, "logback.xml");
File file = new File(this.outputDirectory, "logback.xml");
file.createNewFile();
new File(this.target, "different.xml").createNewFile();
FileUtils.removeDuplicatesFromCopy(this.origin, this.target);
new File(this.originDirectory, "different.xml").createNewFile();
FileUtils.removeDuplicatesFromOutputDirectory(this.outputDirectory,
this.originDirectory);
assertTrue(file.exists());
}

@ -198,7 +198,7 @@ public class RunMojo extends AbstractMojo {
for (Resource resource : this.project.getResources()) {
File directory = new File(resource.getDirectory());
urls.add(directory.toURI().toURL());
FileUtils.removeDuplicatesFromCopy(this.classesDirectory, directory);
FileUtils.removeDuplicatesFromOutputDirectory(this.classesDirectory, directory);
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2014 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.

Loading…
Cancel
Save