GH-8680: Check DB for table on start (#8690)

* GH-8680: Check DB for table on start

Fixes https://github.com/spring-projects/spring-integration/issues/8680

If database is not initialized properly before application start, we may lose messages
at runtime when we fail to insert data into DB

* Implement `SmartLifecycle` on `JdbcMessageStore`, `JdbcChannelMessageStore`,
`JdbcMetadataStore`, and `DefaultLockRepository` to perform `SELECT COUNT` query in `start()`
to fail fast if no required table is present.
* Refactor `AbstractJdbcChannelMessageStoreTests` into JUnit 5 and use `MySqlContainerTest`
for more coverage
* Fix newly failed tests which had DB not initialized before
* Exclude `commons-logging` from `commons-dbcp2` dependency to avoid
classpath conflict
* Document the new feature

* * Fix HTTP URL in the `DataSource-mysql-context.xml`

* Fix language in docs

Co-authored-by: Gary Russell <grussell@vmware.com>

* * Add `setCheckDatabaseOnStart(false)` to disable the check query for all the SI JDBC components

* Fix language in Javadocs

Co-authored-by: Gary Russell <grussell@vmware.com>

---------

Co-authored-by: Gary Russell <grussell@vmware.com>
This commit is contained in:
Artem Bilan
2023-07-28 14:47:49 -04:00
committed by GitHub
parent 0c7d40d1e2
commit 7dcc0bb125
25 changed files with 414 additions and 104 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -20,8 +20,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.junit.After;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.serializer.DefaultDeserializer;
@@ -81,7 +81,7 @@ public class JdbcMessageStoreParserTests {
assertThat(ReflectionTestUtils.getField(store, "lobHandler")).isEqualTo(context.getBean(LobHandler.class));
}
@After
@AfterEach
public void tearDown() {
if (context != null) {
context.close();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -19,8 +19,8 @@ package org.springframework.integration.jdbc.config;
import java.sql.Types;
import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ConfigurableApplicationContext;
@@ -42,6 +42,8 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Gunnar Hillert
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.1
*
*/
@@ -54,7 +56,7 @@ public class StoredProcMessageHandlerParserTests {
private static volatile int adviceCalled;
@Test
public void testProcedureNameIsSet() throws Exception {
public void testProcedureNameIsSet() {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
@@ -72,7 +74,7 @@ public class StoredProcMessageHandlerParserTests {
@SuppressWarnings("unchecked")
@Test
public void testProcedurepParametersAreSet() throws Exception {
public void testProcedureParametersAreSet() {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
@@ -114,7 +116,7 @@ public class StoredProcMessageHandlerParserTests {
@SuppressWarnings("unchecked")
@Test
public void testSqlParametersAreSet() throws Exception {
public void testSqlParametersAreSet() {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
@@ -161,15 +163,15 @@ public class StoredProcMessageHandlerParserTests {
}
@Test
public void adviceCalled() throws Exception {
public void adviceCalled() {
setUp("advisedStoredProcOutboundChannelAdapterTest.xml", getClass());
MessageHandler handler = TestUtils.getPropertyValue(this.consumer, "handler", MessageHandler.class);
handler.handleMessage(new GenericMessage<String>("foo"));
handler.handleMessage(new GenericMessage<>("foo"));
assertThat(adviceCalled).isEqualTo(1);
}
@After
@AfterEach
public void tearDown() {
if (context != null) {
context.close();

View File

@@ -12,9 +12,7 @@
<int:channel id="target"/>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<int-jdbc:message-store id="messageStore" data-source="dataSource"/>
<int-jdbc:stored-proc-outbound-channel-adapter id="storedProcedureOutboundChannelAdapter"
<int-jdbc:stored-proc-outbound-channel-adapter id="storedProcedureOutboundChannelAdapter"
data-source="dataSource" channel="target"
stored-procedure-name="testProcedure1">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>

View File

@@ -1,30 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<int:channel id="target"/>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<int-jdbc:message-store id="messageStore" data-source="dataSource"/>
<int:channel id="target"/>
<int-jdbc:stored-proc-outbound-channel-adapter id="storedProcedureOutboundChannelAdapter"
data-source="dataSource" channel="target"
stored-procedure-name="testProcedure1">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT" />
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description" />
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<int-jdbc:stored-proc-outbound-channel-adapter id="storedProcedureOutboundChannelAdapter"
data-source="dataSource" channel="target"
stored-procedure-name="testProcedure1">
<int-jdbc:sql-parameter-definition name="username" direction="IN" type="VARCHAR"/>
<int-jdbc:sql-parameter-definition name="password" direction="OUT"/>
<int-jdbc:sql-parameter-definition name="age" direction="INOUT" type="INTEGER" scale="5"/>
<int-jdbc:sql-parameter-definition name="description"/>
<int-jdbc:parameter name="username" value="kenny" type="java.lang.String"/>
<int-jdbc:parameter name="description" value="Who killed Kenny?"/>
<int-jdbc:parameter name="password" expression="payload.username"/>
<int-jdbc:parameter name="age" value="30" type="java.lang.Integer"/>
</int-jdbc:stored-proc-outbound-channel-adapter>
</beans>

View File

@@ -7,7 +7,10 @@
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<jdbc:embedded-database id="dataSource">
<jdbc:script location="org/springframework/integration/jdbc/schema-drop-h2.sql"/>
<jdbc:script location="org/springframework/integration/jdbc/schema-h2.sql" />
</jdbc:embedded-database>
<int-jdbc:message-store id="messageStore" data-source="dataSource"/>

View File

@@ -7,8 +7,11 @@
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<jdbc:embedded-database id="dataSource">
<jdbc:script location="org/springframework/integration/jdbc/schema-drop-h2.sql"/>
<jdbc:script location="org/springframework/integration/jdbc/schema-h2.sql" />
</jdbc:embedded-database>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>

View File

@@ -5,7 +5,10 @@
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<jdbc:embedded-database id="dataSource" type="HSQL" />
<jdbc:embedded-database id="dataSource">
<jdbc:script location="org/springframework/integration/jdbc/schema-drop-h2.sql"/>
<jdbc:script location="org/springframework/integration/jdbc/schema-h2.sql" />
</jdbc:embedded-database>
<bean id="serializer" class="org.springframework.integration.jdbc.config.JdbcMessageStoreParserTests$EnhancedSerializer" />

View File

@@ -2,15 +2,19 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<int-jdbc:message-store id="messageStore" data-source="dataSource" lob-handler="lobHandler" region="FOO" table-prefix="BAR_"/>
<bean id="messageStore" class="org.springframework.integration.jdbc.store.JdbcMessageStore">
<constructor-arg ref="dataSource"/>
<property name="lobHandler" ref="lobHandler"/>
<property name="region" value="FOO"/>
<property name="tablePrefix" value="BAR_"/>
<property name="checkDatabaseOnStart" value="false"/>
</bean>
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -29,17 +29,20 @@ import java.util.concurrent.locks.Lock;
import javax.sql.DataSource;
import org.h2.jdbc.JdbcSQLSyntaxErrorException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.UUIDConverter;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.PlatformTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -68,6 +71,9 @@ public class JdbcLockRegistryTests {
@Autowired
private DataSource dataSource;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private ApplicationContext context;
@@ -483,6 +489,20 @@ public class JdbcLockRegistryTests {
toUUID("foo:5"));
}
@Test
void noTableThrowsExceptionOnStart() {
try (TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext()) {
DefaultLockRepository client = new DefaultLockRepository(this.dataSource);
client.setPrefix("TEST_");
client.setTransactionManager(this.transactionManager);
testApplicationContext.registerBean("client", client);
assertThatExceptionOfType(ApplicationContextException.class)
.isThrownBy(testApplicationContext::refresh)
.withRootCauseExactlyInstanceOf(JdbcSQLSyntaxErrorException.class)
.withStackTraceContaining("Table \"TEST_LOCK\" not found");
}
}
@SuppressWarnings("unchecked")
private static Map<String, Lock> getRegistryLocks(JdbcLockRegistry registry) {
return TestUtils.getPropertyValue(registry, "locks", Map.class);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 the original author or authors.
* Copyright 2017-2023 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.
@@ -18,15 +18,19 @@ package org.springframework.integration.jdbc.metadata;
import javax.sql.DataSource;
import org.apache.derby.shared.common.error.StandardException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContextException;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Bojan Vukasovic
@@ -105,4 +109,17 @@ public class JdbcMetadataStoreTests {
assertThat(bar).isEqualTo("bar");
}
@Test
void noTableThrowsExceptionOnStart() {
try (TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext()) {
JdbcMetadataStore jdbcMetadataStore = new JdbcMetadataStore(this.dataSource);
jdbcMetadataStore.setTablePrefix("TEST_");
testApplicationContext.registerBean("jdbcMetadataStore", jdbcMetadataStore);
assertThatExceptionOfType(ApplicationContextException.class)
.isThrownBy(testApplicationContext::refresh)
.withRootCauseExactlyInstanceOf(StandardException.class)
.withStackTraceContaining("Table/View 'TEST_METADATA_STORE' does not exist");
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2021-2022 the original author or authors.
* Copyright 2021-2023 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.
@@ -16,6 +16,9 @@
package org.springframework.integration.jdbc.mysql;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -57,4 +60,13 @@ public interface MySqlContainerTest {
return MY_SQL_CONTAINER.getPassword();
}
static DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(getDriverClassName());
dataSource.setUrl(getJdbcUrl());
dataSource.setUsername(getUsername());
dataSource.setPassword(getPassword());
return dataSource;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -23,7 +23,6 @@ import java.util.UUID;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.AfterEach;
@@ -509,12 +508,7 @@ public class MySqlJdbcMessageStoreTests implements MySqlContainerTest {
@Bean
DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(MySqlContainerTest.getDriverClassName());
dataSource.setUrl(MySqlContainerTest.getJdbcUrl());
dataSource.setUsername(MySqlContainerTest.getUsername());
dataSource.setPassword(MySqlContainerTest.getPassword());
return dataSource;
return MySqlContainerTest.dataSource();
}
@Bean

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -37,11 +37,13 @@ import org.apache.commons.dbcp2.PoolingDataSource;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.hsqldb.HsqlException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContextException;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.integration.IntegrationMessageHeaderAccessor;
@@ -51,6 +53,7 @@ import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.store.MessageGroup;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.predicate.MessagePredicate;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.UUIDConverter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
@@ -62,6 +65,7 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Dave Syer
@@ -577,6 +581,19 @@ public class JdbcMessageStoreTests {
pooledMessageStore.removeMessageGroup(groupId);
}
@Test
void noTableThrowsExceptionOnStart() {
try (TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext()) {
JdbcMessageStore jdbcMessageStore = new JdbcMessageStore(this.dataSource);
jdbcMessageStore.setTablePrefix("TEST_");
testApplicationContext.registerBean("jdbcMessageStore", jdbcMessageStore);
assertThatExceptionOfType(ApplicationContextException.class)
.isThrownBy(testApplicationContext::refresh)
.withRootCauseExactlyInstanceOf(HsqlException.class)
.withStackTraceContaining("user lacks privilege or object not found: TEST_MESSAGE_GROUP");
}
}
public void methodForCollectionOfPayloads(Collection<String> payloads) {
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@@ -21,9 +21,8 @@ import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.serializer.support.SerializingConverter;
@@ -33,7 +32,7 @@ import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.messaging.Message;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
@@ -50,13 +49,13 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Artem Bilan
*/
@RunWith(SpringRunner.class)
@SpringJUnitConfig
@DirtiesContext
public abstract class AbstractJdbcChannelMessageStoreTests {
protected static final String TEST_MESSAGE_GROUP = "AbstractJdbcChannelMessageStoreTests";
private static final String REGION = "AbstractJdbcChannelMessageStoreTests";
protected static final String REGION = "AbstractJdbcChannelMessageStoreTests";
@Autowired
protected DataSource dataSource;
@@ -69,8 +68,8 @@ public abstract class AbstractJdbcChannelMessageStoreTests {
@Autowired
protected ChannelMessageStoreQueryProvider queryProvider;
@Before
public void init() throws Exception {
@BeforeEach
public void init() {
messageStore = new JdbcChannelMessageStore(dataSource);
messageStore.setRegion(REGION);
messageStore.setChannelMessageStoreQueryProvider(queryProvider);

View File

@@ -1,16 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
<!-- <property name="defaultTimeout" value="2000" /> -->
<!-- Postgres 9 does not support send timeouts. You may see an exception like:
"java.sql.SQLFeatureNotSupportedException: Method org.postgresql.jdbc4.Jdbc4PreparedStatement.setQueryTimeout(int) is not yet implemented."
-->
<property name="defaultTimeout" value="2000" />
</bean>
</beans>

View File

@@ -1,22 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<import resource="classpath:org/springframework/integration/jdbc/store/channel/DataSource-common-context.xml" />
<import resource="classpath:org/springframework/integration/jdbc/store/channel/DataSource-common-context.xml"/>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/test" />
<property name="username" value="root" />
<property name="password" value="" />
<property name="initialSize" value="10" />
</bean>
<bean id="dataSource" class="org.springframework.integration.jdbc.mysql.MySqlContainerTest"
factory-method="dataSource"/>
<bean id="queryProvider" class="org.springframework.integration.jdbc.store.channel.MySqlChannelMessageStoreQueryProvider"/>
<jdbc:initialize-database ignore-failures="ALL">
<jdbc:script location="classpath:org/springframework/integration/jdbc/schema-drop-mysql.sql" />
<jdbc:script location="classpath:org/springframework/integration/jdbc/schema-mysql.sql" />
</jdbc:initialize-database>
<bean id="queryProvider"
class="org.springframework.integration.jdbc.store.channel.MySqlChannelMessageStoreQueryProvider"/>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2023 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.
@@ -16,11 +16,37 @@
package org.springframework.integration.jdbc.store.channel;
import org.h2.jdbc.JdbcSQLSyntaxErrorException;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContextException;
import org.springframework.integration.jdbc.store.JdbcChannelMessageStore;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.context.ContextConfiguration;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Gunnar Hillert
* @author Manuel Jordan
* @since 4.3
*/
@ContextConfiguration
public class H2JdbcChannelMessageStoreTests extends AbstractJdbcChannelMessageStoreTests {
@Test
void noTableThrowsExceptionOnStart() {
try (TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext()) {
JdbcChannelMessageStore jdbcChannelMessageStore = new JdbcChannelMessageStore(this.dataSource);
jdbcChannelMessageStore.setTablePrefix("TEST_");
jdbcChannelMessageStore.setRegion(REGION);
jdbcChannelMessageStore.setChannelMessageStoreQueryProvider(this.queryProvider);
testApplicationContext.registerBean("jdbcChannelMessageStore", jdbcChannelMessageStore);
assertThatExceptionOfType(ApplicationContextException.class)
.isThrownBy(testApplicationContext::refresh)
.withRootCauseExactlyInstanceOf(JdbcSQLSyntaxErrorException.class)
.withStackTraceContaining("Table \"TEST_CHANNEL_MESSAGE\" not found");
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2023 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.
@@ -16,15 +16,15 @@
package org.springframework.integration.jdbc.store.channel;
import org.junit.Ignore;
import org.springframework.integration.jdbc.mysql.MySqlContainerTest;
import org.springframework.test.context.ContextConfiguration;
/**
* @author Gunnar Hillert
* @author Artem Bilan
*/
@Ignore
@ContextConfiguration
public class MySqlJdbcChannelMessageStoreTests extends AbstractJdbcChannelMessageStoreTests {
public class MySqlJdbcChannelMessageStoreTests extends AbstractJdbcChannelMessageStoreTests
implements MySqlContainerTest {
}