Browse Source

Log URLs for all DataSources

This commit logs the path of the H2 console, followed by the
comma-separated ordered URLs of each data source that offers a
connection.

See gh-28204
pull/28344/head
StitzL 4 years ago committed by Stephane Nicoll
parent
commit
f31b8ec226
  1. 35
      spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.java
  2. 51
      spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfigurationTests.java

35
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.java

@ -17,6 +17,9 @@
package org.springframework.boot.autoconfigure.h2; package org.springframework.boot.autoconfigure.h2;
import java.sql.Connection; import java.sql.Connection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.sql.DataSource; import javax.sql.DataSource;
@ -63,18 +66,32 @@ public class H2ConsoleAutoConfiguration {
String urlMapping = path + (path.endsWith("/") ? "*" : "/*"); String urlMapping = path + (path.endsWith("/") ? "*" : "/*");
ServletRegistrationBean<WebServlet> registration = new ServletRegistrationBean<>(new WebServlet(), urlMapping); ServletRegistrationBean<WebServlet> registration = new ServletRegistrationBean<>(new WebServlet(), urlMapping);
configureH2ConsoleSettings(registration, properties.getSettings()); configureH2ConsoleSettings(registration, properties.getSettings());
dataSource.ifAvailable((available) -> { if (logger.isInfoEnabled()) {
try (Connection connection = available.getConnection()) { logDataSources(dataSource, path);
logger.info("H2 console available at '" + path + "'. Database available at '" }
+ connection.getMetaData().getURL() + "'");
}
catch (Exception ex) {
// Continue
}
});
return registration; return registration;
} }
private void logDataSources(ObjectProvider<DataSource> dataSource, String path) {
List<String> urls = dataSource.orderedStream()
.map((available) -> {
String url = null;
try (Connection connection = available.getConnection()) {
url = connection.getMetaData().getURL();
} catch (Exception ex) {
}
return url;
}).filter(Objects::nonNull)
.collect(Collectors.toList());
if (!urls.isEmpty()) {
String log = urls.stream().collect(Collectors.joining("', '",
"H2 console available at '" + path + "'. Database(s) available at '", "'."));
logger.info(log);
}
}
private void configureH2ConsoleSettings(ServletRegistrationBean<WebServlet> registration, Settings settings) { private void configureH2ConsoleSettings(ServletRegistrationBean<WebServlet> registration, Settings settings) {
if (settings.isTrace()) { if (settings.isTrace()) {
registration.addInitParameter("trace", ""); registration.addInitParameter("trace", "");

51
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfigurationTests.java

@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.h2; package org.springframework.boot.autoconfigure.h2;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import javax.sql.DataSource; import javax.sql.DataSource;
@ -33,6 +34,7 @@ import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
@ -114,25 +116,42 @@ class H2ConsoleAutoConfigurationTests {
@Test @Test
@ExtendWith(OutputCaptureExtension.class) @ExtendWith(OutputCaptureExtension.class)
void dataSourceUrlIsLoggedWhenAvailable(CapturedOutput output) { void singleDataSourceUrlIsLoggedWhenOnlyOneAvailable(CapturedOutput output) {
this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
.withPropertyValues("spring.h2.console.enabled=true").run((context) -> { .withPropertyValues("spring.h2.console.enabled=true").run((context) -> {
try (Connection connection = context.getBean(DataSource.class).getConnection()) { try (Connection connection = context.getBean(DataSource.class).getConnection()) {
assertThat(output) assertThat(output)
.contains("Database available at '" + connection.getMetaData().getURL() + "'"); .contains("H2 console available at '/h2-console'. Database(s) available at '" + connection.getMetaData().getURL() + "'");
} }
}); });
} }
@Test @Test
@ExtendWith(OutputCaptureExtension.class)
void allDataSourceUrlsAreLoggedWhenMultipleAvailable(CapturedOutput output) {
this.contextRunner.withUserConfiguration(MultiDataSourceConfiguration.class)
.withPropertyValues("spring.h2.console.enabled=true").run((context) ->
assertThat(output).contains("H2 console available at '/h2-console'. Database(s) available at 'primaryUrl', 'secondaryUrl'"));
}
@Test
@ExtendWith(OutputCaptureExtension.class)
void noDataSourceIsLoggedWhenNoneAvailable(CapturedOutput output) {
this.contextRunner.withUserConfiguration(FailingDataSourceConfiguration.class)
.withPropertyValues("spring.h2.console.enabled=true")
.run((context) -> assertThat(output).isEmpty());
}
@Test
void h2ConsoleShouldNotFailIfDatabaseConnectionFails() { void h2ConsoleShouldNotFailIfDatabaseConnectionFails() {
this.contextRunner.withUserConfiguration(CustomDataSourceConfiguration.class) this.contextRunner.withUserConfiguration(FailingDataSourceConfiguration.class)
.withPropertyValues("spring.h2.console.enabled=true") .withPropertyValues("spring.h2.console.enabled=true")
.run((context) -> assertThat(context.isRunning()).isTrue()); .run((context) -> assertThat(context.isRunning()).isTrue());
} }
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
static class CustomDataSourceConfiguration { static class FailingDataSourceConfiguration {
@Bean @Bean
DataSource dataSource() throws SQLException { DataSource dataSource() throws SQLException {
@ -143,4 +162,28 @@ class H2ConsoleAutoConfigurationTests {
} }
@Configuration(proxyBeanMethods = false)
static class MultiDataSourceConfiguration extends FailingDataSourceConfiguration {
@Bean
@Primary
DataSource primaryDataSource() throws SQLException {
return getDataSource("primaryUrl");
}
@Bean
DataSource anotherDataSource() throws SQLException {
return getDataSource("secondaryUrl");
}
private DataSource getDataSource(String url) throws SQLException {
DataSource dataSource = mock(DataSource.class);
given(dataSource.getConnection()).willReturn(mock(Connection.class));
given(dataSource.getConnection().getMetaData()).willReturn(mock(DatabaseMetaData.class));
given(dataSource.getConnection().getMetaData().getURL()).willReturn(url);
return dataSource;
}
}
} }

Loading…
Cancel
Save