JDBC tracing context not leaking

without this change there were cases (that we didn't test) where the tracing context would leak and pollute other parts of the code (including tests)
with this change we ensure that in case of errors we don't allow any dangling tracing context
This commit is contained in:
Marcin Grzejszczak
2021-05-26 18:05:43 +02:00
parent feeb251f09
commit 12737adb67
11 changed files with 1088 additions and 929 deletions

View File

@@ -1,277 +1,281 @@
/*
* Copyright 2013-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.cloud.sleuth.autoconfig.instrument.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import javax.sql.DataSource;
import com.p6spy.engine.common.ConnectionInformation;
import com.p6spy.engine.common.P6LogQuery;
import com.p6spy.engine.event.CompoundJdbcEventListener;
import com.p6spy.engine.event.JdbcEventListener;
import com.p6spy.engine.logging.Category;
import com.p6spy.engine.logging.LoggingEventListener;
import com.p6spy.engine.spy.JdbcEventListenerFactory;
import com.p6spy.engine.spy.P6DataSource;
import com.p6spy.engine.spy.appender.CustomLineFormat;
import com.p6spy.engine.spy.appender.FormattedLogger;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.jdbc.DataSourceWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
class P6SpyConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TraceDataSourceDecoratorAutoConfiguration.class, BraveAutoConfiguration.class,
TestSpanHandlerConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialization-mode=never",
"spring.datasource.url:jdbc:h2:mem:testdb-" + ThreadLocalRandom.current().nextInt())
.withClassLoader(new FilteredClassLoader("net.ttddyy.dsproxy"));
@BeforeEach
@AfterEach
void resetLogAccumulator() {
LogAccumulator.reset();
}
@Test
void testCustomListeners() {
ApplicationContextRunner contextRunner = this.contextRunner
.withUserConfiguration(CustomListenerConfiguration.class);
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
JdbcEventListenerFactory jdbcEventListenerFactory = context.getBean(JdbcEventListenerFactory.class);
GetCountingListener getCountingListener = context.getBean(GetCountingListener.class);
ClosingCountingListener closingCountingListener = context.getBean(ClosingCountingListener.class);
P6DataSource p6DataSource = (P6DataSource) ((DataSourceWrapper) dataSource).getDecoratedDataSource();
assertThat(p6DataSource).extracting("jdbcEventListenerFactory").isEqualTo(jdbcEventListenerFactory);
CompoundJdbcEventListener jdbcEventListener = (CompoundJdbcEventListener) jdbcEventListenerFactory
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).contains(getCountingListener, closingCountingListener);
assertThat(getCountingListener.connectionCount).isEqualTo(0);
Connection connection1 = p6DataSource.getConnection();
assertThat(getCountingListener.connectionCount).isEqualTo(1);
assertThat(closingCountingListener.connectionCount).isEqualTo(0);
Connection connection2 = p6DataSource.getConnection();
assertThat(getCountingListener.connectionCount).isEqualTo(2);
connection1.close();
assertThat(closingCountingListener.connectionCount).isEqualTo(1);
connection2.close();
assertThat(closingCountingListener.connectionCount).isEqualTo(2);
});
}
@Test
void testDoesNotRegisterLoggingListenerIfDisabled() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.p6spy.enable-logging:false");
contextRunner.run(context -> {
JdbcEventListenerFactory jdbcEventListenerFactory = context.getBean(JdbcEventListenerFactory.class);
CompoundJdbcEventListener jdbcEventListener = (CompoundJdbcEventListener) jdbcEventListenerFactory
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).extracting("class")
.doesNotContain(LoggingEventListener.class);
});
}
@Test
void testCanSetCustomLoggingFormat() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.p6spy.log-format:test %{connectionId}");
contextRunner.run(context -> {
JdbcEventListenerFactory jdbcEventListenerFactory = context.getBean(JdbcEventListenerFactory.class);
CompoundJdbcEventListener jdbcEventListener = (CompoundJdbcEventListener) jdbcEventListenerFactory
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).extracting("class").contains(LoggingEventListener.class);
assertThat(P6LogQuery.getLogger()).extracting("strategy").extracting("class")
.isEqualTo(CustomLineFormat.class);
});
}
@Test
void testMultilineShouldNotOverrideCustomProperties() {
System.setProperty("p6spy.config.logMessageFormat", "com.p6spy.engine.spy.appender.CustomLineFormat");
System.setProperty("p6spy.config.excludecategories", "debug");
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.p6spy.multiline:true");
contextRunner.run(context -> {
JdbcEventListenerFactory jdbcEventListenerFactory = context.getBean(JdbcEventListenerFactory.class);
CompoundJdbcEventListener jdbcEventListener = (CompoundJdbcEventListener) jdbcEventListenerFactory
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).extracting("class").contains(LoggingEventListener.class);
assertThat(P6LogQuery.getLogger()).extracting("strategy").extracting("class")
.isEqualTo(CustomLineFormat.class);
});
}
@Test
void testUseCustomLogger() {
ApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues(
"spring.sleuth.jdbc.decorator.datasource.p6spy.logging:custom",
"spring.sleuth.jdbc.decorator.datasource.p6spy.custom-appender-class:"
+ LogAccumulator.class.getName());
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
dataSource.getConnection().close();
assertThat(P6LogQuery.getLogger()).isInstanceOf(LogAccumulator.class);
});
}
@Test
void testLogFilterPattern() {
ApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues(
"spring.sleuth.jdbc.decorator.datasource.p6spy.logging:custom",
"spring.sleuth.jdbc.decorator.datasource.p6spy.custom-appender-class:" + LogAccumulator.class.getName(),
"spring.sleuth.jdbc.decorator.datasource.p6spy.log-filter.pattern:.*table1.*");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
try (Connection connection = dataSource.getConnection();
PreparedStatement ps1 = connection.prepareStatement("select 1 /* from table1 */");
PreparedStatement ps2 = connection.prepareStatement("select 1 /* from table2 */")) {
ps1.execute();
ps2.execute();
}
assertThat(LogAccumulator.MESSAGES).hasSize(1);
assertThat(LogAccumulator.MESSAGES).allMatch(message -> message.contains("table1"));
});
}
@Test
void testLogFilterPatternMatchAll() {
ApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues(
"spring.sleuth.jdbc.decorator.datasource.p6spy.logging:custom",
"spring.sleuth.jdbc.decorator.datasource.p6spy.custom-appender-class:" + LogAccumulator.class.getName(),
"spring.sleuth.jdbc.decorator.datasource.p6spy.log-filter.pattern:.*");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
try (Connection connection = dataSource.getConnection();
PreparedStatement ps1 = connection.prepareStatement("select 1 /* from table1 */");
PreparedStatement ps2 = connection.prepareStatement("select 1 /* from table2 */")) {
ps1.execute();
ps2.execute();
}
assertThat(LogAccumulator.MESSAGES).hasSize(2);
});
}
@Configuration
static class CustomListenerConfiguration {
@Bean
public GetCountingListener wrappingCountingListener() {
return new GetCountingListener();
}
@Bean
public ClosingCountingListener closingCountingListener() {
return new ClosingCountingListener();
}
}
static class GetCountingListener extends JdbcEventListener {
int connectionCount = 0;
@Override
public void onAfterGetConnection(ConnectionInformation connectionInformation, SQLException e) {
connectionCount++;
}
}
static class ClosingCountingListener extends JdbcEventListener {
int connectionCount = 0;
@Override
public void onAfterConnectionClose(ConnectionInformation connectionInformation, SQLException e) {
connectionCount++;
}
}
public static class LogAccumulator extends FormattedLogger {
static final List<String> MESSAGES = new ArrayList<>();
static final List<Exception> EXCEPTIONS = new ArrayList<>();
public static void reset() {
MESSAGES.clear();
EXCEPTIONS.clear();
}
@Override
public void logException(Exception e) {
EXCEPTIONS.add(e);
}
@Override
public void logText(String text) {
MESSAGES.add(text);
}
@Override
public boolean isCategoryEnabled(Category category) {
return true;
}
}
}
/*
* Copyright 2013-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.cloud.sleuth.autoconfig.instrument.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import javax.sql.DataSource;
import com.p6spy.engine.common.ConnectionInformation;
import com.p6spy.engine.common.P6LogQuery;
import com.p6spy.engine.event.CompoundJdbcEventListener;
import com.p6spy.engine.event.JdbcEventListener;
import com.p6spy.engine.logging.Category;
import com.p6spy.engine.logging.LoggingEventListener;
import com.p6spy.engine.spy.JdbcEventListenerFactory;
import com.p6spy.engine.spy.P6DataSource;
import com.p6spy.engine.spy.appender.CustomLineFormat;
import com.p6spy.engine.spy.appender.FormattedLogger;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.jdbc.DataSourceWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
class P6SpyConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TraceDataSourceDecoratorAutoConfiguration.class, BraveAutoConfiguration.class,
TestSpanHandlerConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialization-mode=never",
"spring.datasource.url:jdbc:h2:mem:testdb-" + ThreadLocalRandom.current().nextInt())
.withClassLoader(new FilteredClassLoader("net.ttddyy.dsproxy"));
@BeforeEach
@AfterEach
void resetLogAccumulator() {
LogAccumulator.reset();
}
@Test
void testCustomListeners() {
ApplicationContextRunner contextRunner = this.contextRunner
.withUserConfiguration(CustomListenerConfiguration.class);
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
JdbcEventListenerFactory jdbcEventListenerFactory = context.getBean(JdbcEventListenerFactory.class);
GetCountingListener getCountingListener = context.getBean(GetCountingListener.class);
ClosingCountingListener closingCountingListener = context.getBean(ClosingCountingListener.class);
P6DataSource p6DataSource = (P6DataSource) ((DataSourceWrapper) dataSource).getDecoratedDataSource();
assertThat(p6DataSource).extracting("jdbcEventListenerFactory").isEqualTo(jdbcEventListenerFactory);
CompoundJdbcEventListener jdbcEventListener = (CompoundJdbcEventListener) jdbcEventListenerFactory
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).contains(getCountingListener, closingCountingListener);
assertThat(getCountingListener.connectionCount).isEqualTo(0);
Connection connection1 = p6DataSource.getConnection();
assertThat(getCountingListener.connectionCount).isEqualTo(1);
assertThat(closingCountingListener.connectionCount).isEqualTo(0);
Connection connection2 = p6DataSource.getConnection();
assertThat(getCountingListener.connectionCount).isEqualTo(2);
// order matters!
connection2.close();
assertThat(closingCountingListener.connectionCount).isEqualTo(1);
// order matters!
connection1.close();
assertThat(closingCountingListener.connectionCount).isEqualTo(2);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@Test
void testDoesNotRegisterLoggingListenerIfDisabled() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.p6spy.enable-logging:false");
contextRunner.run(context -> {
JdbcEventListenerFactory jdbcEventListenerFactory = context.getBean(JdbcEventListenerFactory.class);
CompoundJdbcEventListener jdbcEventListener = (CompoundJdbcEventListener) jdbcEventListenerFactory
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).extracting("class")
.doesNotContain(LoggingEventListener.class);
});
}
@Test
void testCanSetCustomLoggingFormat() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.p6spy.log-format:test %{connectionId}");
contextRunner.run(context -> {
JdbcEventListenerFactory jdbcEventListenerFactory = context.getBean(JdbcEventListenerFactory.class);
CompoundJdbcEventListener jdbcEventListener = (CompoundJdbcEventListener) jdbcEventListenerFactory
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).extracting("class").contains(LoggingEventListener.class);
assertThat(P6LogQuery.getLogger()).extracting("strategy").extracting("class")
.isEqualTo(CustomLineFormat.class);
});
}
@Test
void testMultilineShouldNotOverrideCustomProperties() {
System.setProperty("p6spy.config.logMessageFormat", "com.p6spy.engine.spy.appender.CustomLineFormat");
System.setProperty("p6spy.config.excludecategories", "debug");
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.p6spy.multiline:true");
contextRunner.run(context -> {
JdbcEventListenerFactory jdbcEventListenerFactory = context.getBean(JdbcEventListenerFactory.class);
CompoundJdbcEventListener jdbcEventListener = (CompoundJdbcEventListener) jdbcEventListenerFactory
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).extracting("class").contains(LoggingEventListener.class);
assertThat(P6LogQuery.getLogger()).extracting("strategy").extracting("class")
.isEqualTo(CustomLineFormat.class);
});
}
@Test
void testUseCustomLogger() {
ApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues(
"spring.sleuth.jdbc.decorator.datasource.p6spy.logging:custom",
"spring.sleuth.jdbc.decorator.datasource.p6spy.custom-appender-class:"
+ LogAccumulator.class.getName());
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
dataSource.getConnection().close();
assertThat(P6LogQuery.getLogger()).isInstanceOf(LogAccumulator.class);
});
}
@Test
void testLogFilterPattern() {
ApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues(
"spring.sleuth.jdbc.decorator.datasource.p6spy.logging:custom",
"spring.sleuth.jdbc.decorator.datasource.p6spy.custom-appender-class:" + LogAccumulator.class.getName(),
"spring.sleuth.jdbc.decorator.datasource.p6spy.log-filter.pattern:.*table1.*");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
try (Connection connection = dataSource.getConnection();
PreparedStatement ps1 = connection.prepareStatement("select 1 /* from table1 */");
PreparedStatement ps2 = connection.prepareStatement("select 1 /* from table2 */")) {
ps1.execute();
ps2.execute();
}
assertThat(LogAccumulator.MESSAGES).hasSize(1);
assertThat(LogAccumulator.MESSAGES).allMatch(message -> message.contains("table1"));
});
}
@Test
void testLogFilterPatternMatchAll() {
ApplicationContextRunner contextRunner = this.contextRunner.withPropertyValues(
"spring.sleuth.jdbc.decorator.datasource.p6spy.logging:custom",
"spring.sleuth.jdbc.decorator.datasource.p6spy.custom-appender-class:" + LogAccumulator.class.getName(),
"spring.sleuth.jdbc.decorator.datasource.p6spy.log-filter.pattern:.*");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
try (Connection connection = dataSource.getConnection();
PreparedStatement ps1 = connection.prepareStatement("select 1 /* from table1 */");
PreparedStatement ps2 = connection.prepareStatement("select 1 /* from table2 */")) {
ps1.execute();
ps2.execute();
}
assertThat(LogAccumulator.MESSAGES).hasSize(2);
});
}
@Configuration
static class CustomListenerConfiguration {
@Bean
public GetCountingListener wrappingCountingListener() {
return new GetCountingListener();
}
@Bean
public ClosingCountingListener closingCountingListener() {
return new ClosingCountingListener();
}
}
static class GetCountingListener extends JdbcEventListener {
int connectionCount = 0;
@Override
public void onAfterGetConnection(ConnectionInformation connectionInformation, SQLException e) {
connectionCount++;
}
}
static class ClosingCountingListener extends JdbcEventListener {
int connectionCount = 0;
@Override
public void onAfterConnectionClose(ConnectionInformation connectionInformation, SQLException e) {
connectionCount++;
}
}
public static class LogAccumulator extends FormattedLogger {
static final List<String> MESSAGES = new ArrayList<>();
static final List<Exception> EXCEPTIONS = new ArrayList<>();
public static void reset() {
MESSAGES.clear();
EXCEPTIONS.clear();
}
@Override
public void logException(Exception e) {
EXCEPTIONS.add(e);
}
@Override
public void logText(String text) {
MESSAGES.add(text);
}
@Override
public boolean isCategoryEnabled(Category category) {
return true;
}
}
}

View File

@@ -1,238 +1,246 @@
/*
* Copyright 2013-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.cloud.sleuth.autoconfig.instrument.jdbc;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import javax.sql.DataSource;
import net.ttddyy.dsproxy.ExecutionInfo;
import net.ttddyy.dsproxy.QueryInfo;
import net.ttddyy.dsproxy.listener.ChainListener;
import net.ttddyy.dsproxy.listener.QueryExecutionListener;
import net.ttddyy.dsproxy.listener.logging.CommonsQueryLoggingListener;
import net.ttddyy.dsproxy.listener.logging.CommonsSlowQueryListener;
import net.ttddyy.dsproxy.listener.logging.JULQueryLoggingListener;
import net.ttddyy.dsproxy.listener.logging.JULSlowQueryListener;
import net.ttddyy.dsproxy.listener.logging.SLF4JQueryLoggingListener;
import net.ttddyy.dsproxy.listener.logging.SLF4JSlowQueryListener;
import net.ttddyy.dsproxy.listener.logging.SystemOutQueryLoggingListener;
import net.ttddyy.dsproxy.listener.logging.SystemOutSlowQueryListener;
import net.ttddyy.dsproxy.proxy.DefaultConnectionIdManager;
import net.ttddyy.dsproxy.proxy.GlobalConnectionIdManager;
import net.ttddyy.dsproxy.support.ProxyDataSource;
import net.ttddyy.dsproxy.transform.ParameterTransformer;
import net.ttddyy.dsproxy.transform.QueryTransformer;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.jdbc.DataSourceProxyConnectionIdManagerProvider;
import org.springframework.cloud.sleuth.instrument.jdbc.DataSourceWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import static org.assertj.core.api.Assertions.assertThat;
class ProxyDataSourceConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TraceDataSourceDecoratorAutoConfiguration.class, BraveAutoConfiguration.class,
TestSpanHandlerConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialization-mode=never",
"spring.datasource.url:jdbc:h2:mem:testdb-" + ThreadLocalRandom.current().nextInt())
.withClassLoader(new FilteredClassLoader("com.p6spy"));
@Test
void testRegisterLogAndSlowQueryLogByDefaultToSlf4j() {
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(SLF4JSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(SLF4JQueryLoggingListener.class);
});
}
@Test
void testRegisterLogAndSlowQueryLogByUsingSlf4j() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.datasource-proxy.logging:slf4j");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(SLF4JSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(SLF4JQueryLoggingListener.class);
});
}
@Test
void testRegisterLogAndSlowQueryLogUsingSystemOut() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.datasource-proxy.logging:sysout");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(SystemOutSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(SystemOutQueryLoggingListener.class);
});
}
@Test
void testRegisterLogAndSlowQueryLogUsingJUL() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.datasourceProxy.logging:jul");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(JULSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(JULQueryLoggingListener.class);
});
}
@Test
void testRegisterLogAndSlowQueryLogUsingApacheCommons() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.datasourceProxy.logging:commons");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(CommonsSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(CommonsQueryLoggingListener.class);
});
}
@Test
void testCustomParameterAndQueryTransformer() {
ApplicationContextRunner contextRunner = this.contextRunner
.withUserConfiguration(CustomDataSourceProxyConfiguration.class);
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ParameterTransformer parameterTransformer = context.getBean(ParameterTransformer.class);
QueryTransformer queryTransformer = context.getBean(QueryTransformer.class);
assertThat(proxyDataSource.getProxyConfig().getParameterTransformer()).isSameAs(parameterTransformer);
assertThat(proxyDataSource.getProxyConfig().getQueryTransformer()).isSameAs(queryTransformer);
});
}
@Test
void testCustomListeners() {
ApplicationContextRunner contextRunner = this.contextRunner
.withUserConfiguration(CustomListenerConfiguration.class);
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
QueryExecutionListener queryExecutionListener = context.getBean(QueryExecutionListener.class);
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).contains(queryExecutionListener);
});
}
@Test
void testGlobalConnectionIdManagerByDefault() {
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
assertThat(proxyDataSource.getConnectionIdManager()).isInstanceOf(GlobalConnectionIdManager.class);
});
}
@Test
void testCustomConnectionIdManager() {
ApplicationContextRunner contextRunner = this.contextRunner
.withUserConfiguration(CustomDataSourceProxyConfiguration.class);
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
assertThat(proxyDataSource.getConnectionIdManager()).isInstanceOf(DefaultConnectionIdManager.class);
});
}
@Configuration
static class CustomDataSourceProxyConfiguration {
@Bean
public ParameterTransformer parameterTransformer() {
return (replacer, transformInfo) -> {
};
}
@Bean
public QueryTransformer queryTransformer() {
return (transformInfo) -> "TestQuery";
}
@Bean
public DataSourceProxyConnectionIdManagerProvider connectionIdManagerProvider() {
return DefaultConnectionIdManager::new;
}
}
@Configuration
static class CustomListenerConfiguration {
@Bean
@Primary
public QueryExecutionListener queryExecutionListener() {
return new QueryExecutionListener() {
@Override
public void beforeQuery(ExecutionInfo execInfo, List<QueryInfo> queryInfoList) {
System.out.println("beforeQuery");
}
@Override
public void afterQuery(ExecutionInfo execInfo, List<QueryInfo> queryInfoList) {
System.out.println("afterQuery");
}
};
}
}
}
/*
* Copyright 2013-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.cloud.sleuth.autoconfig.instrument.jdbc;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import javax.sql.DataSource;
import net.ttddyy.dsproxy.ExecutionInfo;
import net.ttddyy.dsproxy.QueryInfo;
import net.ttddyy.dsproxy.listener.ChainListener;
import net.ttddyy.dsproxy.listener.QueryExecutionListener;
import net.ttddyy.dsproxy.listener.logging.CommonsQueryLoggingListener;
import net.ttddyy.dsproxy.listener.logging.CommonsSlowQueryListener;
import net.ttddyy.dsproxy.listener.logging.JULQueryLoggingListener;
import net.ttddyy.dsproxy.listener.logging.JULSlowQueryListener;
import net.ttddyy.dsproxy.listener.logging.SLF4JQueryLoggingListener;
import net.ttddyy.dsproxy.listener.logging.SLF4JSlowQueryListener;
import net.ttddyy.dsproxy.listener.logging.SystemOutQueryLoggingListener;
import net.ttddyy.dsproxy.listener.logging.SystemOutSlowQueryListener;
import net.ttddyy.dsproxy.proxy.DefaultConnectionIdManager;
import net.ttddyy.dsproxy.proxy.GlobalConnectionIdManager;
import net.ttddyy.dsproxy.support.ProxyDataSource;
import net.ttddyy.dsproxy.transform.ParameterTransformer;
import net.ttddyy.dsproxy.transform.QueryTransformer;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.jdbc.DataSourceProxyConnectionIdManagerProvider;
import org.springframework.cloud.sleuth.instrument.jdbc.DataSourceWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import static org.assertj.core.api.Assertions.assertThat;
class ProxyDataSourceConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TraceDataSourceDecoratorAutoConfiguration.class, BraveAutoConfiguration.class,
TestSpanHandlerConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialization-mode=never",
"spring.datasource.url:jdbc:h2:mem:testdb-" + ThreadLocalRandom.current().nextInt())
.withClassLoader(new FilteredClassLoader("com.p6spy"));
@Test
void testRegisterLogAndSlowQueryLogByDefaultToSlf4j() {
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(SLF4JSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(SLF4JQueryLoggingListener.class);
});
}
@Test
void testRegisterLogAndSlowQueryLogByUsingSlf4j() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.datasource-proxy.logging:slf4j");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(SLF4JSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(SLF4JQueryLoggingListener.class);
});
}
@Test
void testRegisterLogAndSlowQueryLogUsingSystemOut() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.datasource-proxy.logging:sysout");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(SystemOutSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(SystemOutQueryLoggingListener.class);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@Test
void testRegisterLogAndSlowQueryLogUsingJUL() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.datasourceProxy.logging:jul");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(JULSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(JULQueryLoggingListener.class);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@Test
void testRegisterLogAndSlowQueryLogUsingApacheCommons() {
ApplicationContextRunner contextRunner = this.contextRunner
.withPropertyValues("spring.sleuth.jdbc.decorator.datasource.datasourceProxy.logging:commons");
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(CommonsSlowQueryListener.class);
assertThat(chainListener.getListeners()).extracting("class").contains(CommonsQueryLoggingListener.class);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@Test
void testCustomParameterAndQueryTransformer() {
ApplicationContextRunner contextRunner = this.contextRunner
.withUserConfiguration(CustomDataSourceProxyConfiguration.class);
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
ParameterTransformer parameterTransformer = context.getBean(ParameterTransformer.class);
QueryTransformer queryTransformer = context.getBean(QueryTransformer.class);
assertThat(proxyDataSource.getProxyConfig().getParameterTransformer()).isSameAs(parameterTransformer);
assertThat(proxyDataSource.getProxyConfig().getQueryTransformer()).isSameAs(queryTransformer);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@Test
void testCustomListeners() {
ApplicationContextRunner contextRunner = this.contextRunner
.withUserConfiguration(CustomListenerConfiguration.class);
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
QueryExecutionListener queryExecutionListener = context.getBean(QueryExecutionListener.class);
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).contains(queryExecutionListener);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@Test
void testGlobalConnectionIdManagerByDefault() {
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
assertThat(proxyDataSource.getConnectionIdManager()).isInstanceOf(GlobalConnectionIdManager.class);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@Test
void testCustomConnectionIdManager() {
ApplicationContextRunner contextRunner = this.contextRunner
.withUserConfiguration(CustomDataSourceProxyConfiguration.class);
contextRunner.run(context -> {
DataSource dataSource = context.getBean(DataSource.class);
ProxyDataSource proxyDataSource = (ProxyDataSource) ((DataSourceWrapper) dataSource)
.getDecoratedDataSource();
assertThat(proxyDataSource.getConnectionIdManager()).isInstanceOf(DefaultConnectionIdManager.class);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@Configuration
static class CustomDataSourceProxyConfiguration {
@Bean
public ParameterTransformer parameterTransformer() {
return (replacer, transformInfo) -> {
};
}
@Bean
public QueryTransformer queryTransformer() {
return (transformInfo) -> "TestQuery";
}
@Bean
public DataSourceProxyConnectionIdManagerProvider connectionIdManagerProvider() {
return DefaultConnectionIdManager::new;
}
}
@Configuration
static class CustomListenerConfiguration {
@Bean
@Primary
public QueryExecutionListener queryExecutionListener() {
return new QueryExecutionListener() {
@Override
public void beforeQuery(ExecutionInfo execInfo, List<QueryInfo> queryInfoList) {
System.out.println("beforeQuery");
}
@Override
public void afterQuery(ExecutionInfo execInfo, List<QueryInfo> queryInfoList) {
System.out.println("afterQuery");
}
};
}
}
}

View File

@@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.jdbc.TraceJdbcEventListener;
@@ -50,6 +51,7 @@ class SleuthP6SpyListenerAutoConfigurationTests {
.createJdbcEventListener();
assertThat(jdbcEventListener.getEventListeners()).extracting("class")
.contains(TraceJdbcEventListener.class);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}

View File

@@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.jdbc.DataSourceWrapper;
import org.springframework.cloud.sleuth.instrument.jdbc.TraceQueryExecutionListener;
@@ -53,6 +54,7 @@ class SleuthProxyDataSourceListenerAutoConfigurationTests {
.getDecoratedDataSource();
ChainListener chainListener = proxyDataSource.getProxyConfig().getQueryListener();
assertThat(chainListener.getListeners()).extracting("class").contains(TraceQueryExecutionListener.class);
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}

View File

@@ -36,22 +36,16 @@ import static org.assertj.core.api.Assertions.assertThat;
class TracingJdbcEventListenerTests extends TracingListenerStrategyTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
private static final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TraceDataSourceDecoratorAutoConfiguration.class, BraveAutoConfiguration.class,
TestSpanHandlerConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialization-mode=never",
"spring.datasource.url:jdbc:h2:mem:testdb-baz", "spring.datasource.hikari.pool-name=test")
"spring.datasource.url=jdbc:h2:mem:testdb-baz", "spring.datasource.hikari.pool-name=test")
.withClassLoader(new FilteredClassLoader("net.ttddyy.dsproxy"));
protected TracingJdbcEventListenerTests() {
super(new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
TraceDataSourceDecoratorAutoConfiguration.class, BraveAutoConfiguration.class,
TestSpanHandlerConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialization-mode=never",
"spring.datasource.url:jdbc:h2:mem:testdb-baz", "spring.datasource.hikari.pool-name=test")
.withClassLoader(new FilteredClassLoader("net.ttddyy.dsproxy")));
super(contextRunner);
}
@Test

View File

@@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.instrument.jdbc.TraceJdbcEventListener;
import org.springframework.cloud.sleuth.instrument.jdbc.TraceQueryExecutionListener;
import org.springframework.context.annotation.Bean;
@@ -71,6 +72,7 @@ abstract class TracingListenerStrategyTests {
assertThat(connectionSpan.remoteServiceName()).isEqualTo("TESTDB-BAZ");
assertThat(connectionSpan.annotations()).extracting("value").contains("jdbc.commit");
assertThat(connectionSpan.annotations()).extracting("value").contains("jdbc.rollback");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -92,6 +94,7 @@ abstract class TracingListenerStrategyTests {
assertThat(connectionSpan.remoteServiceName()).isEqualTo("aaaabbbb");
assertThat(connectionSpan.annotations()).extracting("value").contains("jdbc.commit");
assertThat(connectionSpan.annotations()).extracting("value").contains("jdbc.rollback");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -112,6 +115,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(statementSpan.remoteServiceName()).isEqualTo("TESTDB-BAZ");
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME, "SELECT NOW()");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -134,6 +138,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME,
"UPDATE INFORMATION_SCHEMA.TABLES SET table_Name = '' WHERE 0 = 1");
assertThat(statementSpan.tags()).containsEntry(SPAN_ROW_COUNT_TAG_NAME, "0");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -156,6 +161,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME,
"UPDATE INFORMATION_SCHEMA.TABLES SET table_Name = '' WHERE 0 = 1");
assertThat(statementSpan.tags()).containsEntry(SPAN_ROW_COUNT_TAG_NAME, "0");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -185,6 +191,7 @@ abstract class TracingListenerStrategyTests {
if (isP6Spy(context)) {
assertThat(resultSetSpan.tags()).containsEntry(SPAN_ROW_COUNT_TAG_NAME, "2");
}
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -212,6 +219,7 @@ abstract class TracingListenerStrategyTests {
if (isP6Spy(context)) {
assertThat(resultSetSpan.tags()).containsEntry(SPAN_ROW_COUNT_TAG_NAME, "1");
}
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -236,6 +244,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME, "SELECT NOW()");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -259,6 +268,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME, "SELECT NOW()");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -284,6 +294,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME, "SELECT NOW()");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -312,6 +323,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME, "SELECT NOW()");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -330,6 +342,7 @@ abstract class TracingListenerStrategyTests {
assertThat(spanReporter.spans()).hasSize(1);
MutableSpan connectionSpan = spanReporter.spans().get(0);
assertThat(connectionSpan.name()).isEqualTo("connection");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -345,6 +358,7 @@ abstract class TracingListenerStrategyTests {
statement.executeQuery("SELECT NOW()");
}).isInstanceOf(SQLException.class);
connection.close();
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -362,6 +376,7 @@ abstract class TracingListenerStrategyTests {
}).isInstanceOf(SQLException.class);
statement.close();
connection.close();
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -373,14 +388,15 @@ abstract class TracingListenerStrategyTests {
Connection connection1 = dataSource.getConnection();
Connection connection2 = dataSource.getConnection();
connection1.close();
connection2.close();
connection1.close();
assertThat(spanReporter.spans()).hasSize(2);
MutableSpan connection1Span = spanReporter.spans().get(0);
MutableSpan connection2Span = spanReporter.spans().get(1);
assertThat(connection1Span.name()).isEqualTo("connection");
assertThat(connection2Span.name()).isEqualTo("connection");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -406,6 +422,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME, "SELECT NOW()");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -428,6 +445,7 @@ abstract class TracingListenerStrategyTests {
assertThat(listener).extracting("strategy").extracting("openConnections")
.isInstanceOfSatisfying(Map.class, map -> assertThat(map).isEmpty());
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -466,6 +484,7 @@ abstract class TracingListenerStrategyTests {
assertThat(spanReporter.spans()).hasSize(1 + 2 * 5);
assertThat(spanReporter.spans()).extracting("name").contains("select", "result-set", "connection");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -487,6 +506,7 @@ abstract class TracingListenerStrategyTests {
assertThat(spanReporter.spans()).hasSize(1);
MutableSpan connectionSpan = spanReporter.spans().get(0);
assertThat(connectionSpan.name()).isEqualTo("connection");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -507,6 +527,7 @@ abstract class TracingListenerStrategyTests {
assertThat(spanReporter.spans()).hasSize(1);
MutableSpan statementSpan = spanReporter.spans().get(0);
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -527,6 +548,7 @@ abstract class TracingListenerStrategyTests {
assertThat(spanReporter.spans()).hasSize(1);
MutableSpan resultSetSpan = spanReporter.spans().get(0);
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -550,6 +572,7 @@ abstract class TracingListenerStrategyTests {
MutableSpan statementSpan = spanReporter.spans().get(0);
assertThat(connectionSpan.name()).isEqualTo("connection");
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -573,6 +596,7 @@ abstract class TracingListenerStrategyTests {
MutableSpan resultSetSpan = spanReporter.spans().get(0);
assertThat(connectionSpan.name()).isEqualTo("connection");
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -596,6 +620,7 @@ abstract class TracingListenerStrategyTests {
MutableSpan statementSpan = spanReporter.spans().get(0);
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -608,12 +633,14 @@ abstract class TracingListenerStrategyTests {
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT NOW()");
connection.close();
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
assertThatThrownBy(statement::executeQuery).isInstanceOf(SQLException.class);
assertThat(spanReporter.spans()).hasSize(1);
MutableSpan connectionSpan = spanReporter.spans().get(0);
assertThat(connectionSpan.name()).isEqualTo("connection");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -634,6 +661,7 @@ abstract class TracingListenerStrategyTests {
MutableSpan statementSpan = spanReporter.spans().get(0);
assertThat(connectionSpan.name()).isEqualTo("connection");
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}
@@ -659,6 +687,7 @@ abstract class TracingListenerStrategyTests {
assertThat(statementSpan.name()).isEqualTo("select");
assertThat(resultSetSpan.name()).isEqualTo("result-set");
assertThat(statementSpan.tags()).containsEntry(SPAN_SQL_QUERY_TAG_NAME, "SELECT NOW()");
assertThat(context.getBean(Tracer.class).currentSpan()).isNull();
});
}