Quote CONDITION whenever necessary for JDBC
SO: https://stackoverflow.com/questions/70286480/how-can-spring-integration-5-5-x-use-mysql-as-message-store Turns out the condition word is reserved in many SQL DB vendors, e.g.: https://dev.mysql.com/doc/refman/8.0/en/keywords.html * Fix SQL scripts for quoting `CONDITION` column name for those vendors which have it as a reserved word * Fix `JdbcMessageStore` to have a `CONDITION` quoted to `""` by default and replaced to "`" for MySQL * Add `MySqlContainerTest` to test against MySQL Docker container * Looks like quoted identifiers work well even if they are not reserved words in the SQL vendor
This commit is contained in:
committed by
Gary Russell
parent
3c32daa25a
commit
b424cbe171
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 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.integration.jdbc.mysql;
|
||||
|
||||
import org.testcontainers.containers.MySQLContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
|
||||
/**
|
||||
* The base contract for JUnit tests based on the container for MqSQL.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 5.5.7
|
||||
*/
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
public interface MySqlContainerTest {
|
||||
|
||||
@Container
|
||||
MySQLContainer<?> MY_SQL_CONTAINER =
|
||||
new MySQLContainer<>(TestUtils.dockerRegistryFromEnv() + "mysql:latest")
|
||||
.withReuse(true);
|
||||
|
||||
|
||||
static String getDriverClassName() {
|
||||
return MY_SQL_CONTAINER.getDriverClassName();
|
||||
}
|
||||
|
||||
static String getJdbcUrl() {
|
||||
return MY_SQL_CONTAINER.getJdbcUrl();
|
||||
}
|
||||
|
||||
static String getUsername() {
|
||||
return MY_SQL_CONTAINER.getUsername();
|
||||
}
|
||||
|
||||
static String getPassword() {
|
||||
return MY_SQL_CONTAINER.getPassword();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?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">
|
||||
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
|
||||
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
|
||||
<property name="url" value="jdbc:mysql://localhost:3306/int30"/>
|
||||
<property name="username" value="root"/>
|
||||
<property name="password" value="root"/>
|
||||
<property name="maxActive" value="10"/>
|
||||
<property name="defaultAutoCommit" value="false"/>
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -25,59 +25,48 @@ 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.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.integration.IntegrationMessageHeaderAccessor;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.history.MessageHistory;
|
||||
import org.springframework.integration.jdbc.store.JdbcMessageStore;
|
||||
import org.springframework.integration.jdbc.store.JdbcMessageStoreTests;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.predicate.MessagePredicate;
|
||||
import org.springframework.integration.util.UUIDConverter;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||
import org.springframework.test.annotation.Repeat;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* Based on the test for Derby:
|
||||
*
|
||||
* {@link JdbcMessageStoreTests}
|
||||
*
|
||||
* This tests requires at least MySql 5.6.4 as it uses the fractional second support
|
||||
* in that version. For more information, please see:
|
||||
*
|
||||
* https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
|
||||
*
|
||||
* Also, please make sure you are using the respective DDL scripts:
|
||||
*
|
||||
* schema-mysql-5_6_4.sql
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
@Ignore
|
||||
public class MySqlJdbcMessageStoreTests {
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext
|
||||
public class MySqlJdbcMessageStoreTests implements MySqlContainerTest {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(MySqlJdbcMessageStoreTests.class);
|
||||
|
||||
@@ -89,13 +78,13 @@ public class MySqlJdbcMessageStoreTests {
|
||||
@Autowired
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
messageStore = new JdbcMessageStore(dataSource);
|
||||
messageStore.setRegion("JdbcMessageStoreTests");
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void afterTest() {
|
||||
final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
new TransactionTemplate(this.transactionManager).execute(status -> {
|
||||
@@ -203,7 +192,7 @@ public class MySqlJdbcMessageStoreTests {
|
||||
Message<String> message = MessageBuilder.withPayload("foo").build();
|
||||
message = messageStore.addMessage(message);
|
||||
Message<String> result = messageStore.addMessage(message);
|
||||
assertThat(result).isSameAs(message);
|
||||
assertThat(result).isEqualTo(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -336,6 +325,7 @@ public class MySqlJdbcMessageStoreTests {
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
@Disabled("Time sensitive")
|
||||
public void testExpireMessageGroupOnCreateOnly() throws Exception {
|
||||
String groupId = "X";
|
||||
Message<String> message = MessageBuilder.withPayload("foo").setCorrelationId(groupId).build();
|
||||
@@ -355,6 +345,7 @@ public class MySqlJdbcMessageStoreTests {
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
@Disabled("Time sensitive")
|
||||
public void testExpireMessageGroupOnIdleOnly() throws Exception {
|
||||
String groupId = "X";
|
||||
Message<String> message = MessageBuilder.withPayload("foo").setCorrelationId(groupId).build();
|
||||
@@ -496,4 +487,48 @@ public class MySqlJdbcMessageStoreTests {
|
||||
.isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageGroupCondition() {
|
||||
String groupId = "X";
|
||||
Message<String> message = MessageBuilder.withPayload("foo").build();
|
||||
this.messageStore.addMessagesToGroup(groupId, message);
|
||||
this.messageStore.setGroupCondition(groupId, "testCondition");
|
||||
assertThat(this.messageStore.getMessageGroup(groupId).getCondition()).isEqualTo("testCondition");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class Config {
|
||||
|
||||
@Value("org/springframework/integration/jdbc/schema-mysql.sql")
|
||||
Resource createSchemaScript;
|
||||
|
||||
@Value("org/springframework/integration/jdbc/schema-drop-mysql.sql")
|
||||
Resource dropSchemaScript;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Bean
|
||||
PlatformTransactionManager transactionManager() {
|
||||
return new DataSourceTransactionManager(dataSource());
|
||||
}
|
||||
|
||||
@Bean
|
||||
DataSourceInitializer dataSourceInitializer() {
|
||||
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
|
||||
dataSourceInitializer.setDataSource(dataSource());
|
||||
dataSourceInitializer.setDatabasePopulator(new ResourceDatabasePopulator(this.createSchemaScript));
|
||||
dataSourceInitializer.setDatabaseCleaner(new ResourceDatabasePopulator(this.dropSchemaScript));
|
||||
return dataSourceInitializer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
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">
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="H2">
|
||||
<jdbc:script location="org/springframework/integration/jdbc/schema-drop-h2.sql"/>
|
||||
<jdbc:script location="org/springframework/integration/jdbc/schema-h2.sql" />
|
||||
<jdbc:embedded-database id="dataSource" type="HSQL">
|
||||
<jdbc:script location="org/springframework/integration/jdbc/schema-drop-hsqldb.sql"/>
|
||||
<jdbc:script location="org/springframework/integration/jdbc/schema-hsqldb.sql" />
|
||||
</jdbc:embedded-database>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
|
||||
@@ -30,9 +30,8 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
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.integration.IntegrationMessageHeaderAccessor;
|
||||
@@ -47,8 +46,7 @@ import org.springframework.jdbc.core.PreparedStatementSetter;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
@@ -60,8 +58,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* @author Gary Russell
|
||||
* @author Will Schipp
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext // close at the end after class
|
||||
@Transactional
|
||||
public class JdbcMessageStoreTests {
|
||||
@@ -71,7 +68,7 @@ public class JdbcMessageStoreTests {
|
||||
|
||||
private JdbcMessageStore messageStore;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
messageStore = new JdbcMessageStore(dataSource);
|
||||
}
|
||||
@@ -219,12 +216,12 @@ public class JdbcMessageStoreTests {
|
||||
public void testAddAndRemoveMessagesFromMessageGroup() throws Exception {
|
||||
String groupId = "X";
|
||||
this.messageStore.setRemoveBatchSize(10);
|
||||
List<Message<?>> messages = new ArrayList<Message<?>>();
|
||||
List<Message<?>> messages = new ArrayList<>();
|
||||
for (int i = 0; i < 25; i++) {
|
||||
Message<String> message = MessageBuilder.withPayload("foo").setCorrelationId(groupId).build();
|
||||
messages.add(message);
|
||||
}
|
||||
this.messageStore.addMessagesToGroup(groupId, messages.toArray(new Message<?>[messages.size()]));
|
||||
this.messageStore.addMessagesToGroup(groupId, messages.toArray(new Message<?>[0]));
|
||||
MessageGroup group = this.messageStore.getMessageGroup(groupId);
|
||||
assertThat(group.size()).isEqualTo(25);
|
||||
this.messageStore.removeMessagesFromGroup(groupId, messages);
|
||||
@@ -261,7 +258,7 @@ public class JdbcMessageStoreTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateLastReleasedSequence() throws Exception {
|
||||
public void testUpdateLastReleasedSequence() {
|
||||
String groupId = "X";
|
||||
Message<String> message = MessageBuilder.withPayload("foo").setCorrelationId(groupId).build();
|
||||
messageStore.addMessagesToGroup(groupId, message);
|
||||
@@ -271,7 +268,7 @@ public class JdbcMessageStoreTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageGroupCount() throws Exception {
|
||||
public void testMessageGroupCount() {
|
||||
String groupId = "X";
|
||||
Message<String> message = MessageBuilder.withPayload("foo").build();
|
||||
messageStore.addMessagesToGroup(groupId, message);
|
||||
@@ -279,7 +276,7 @@ public class JdbcMessageStoreTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageGroupSizes() throws Exception {
|
||||
public void testMessageGroupSizes() {
|
||||
String groupId = "X";
|
||||
Message<String> message = MessageBuilder.withPayload("foo").build();
|
||||
messageStore.addMessagesToGroup(groupId, message);
|
||||
@@ -408,7 +405,7 @@ public class JdbcMessageStoreTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameMessageToMultipleGroups() throws Exception {
|
||||
public void testSameMessageToMultipleGroups() {
|
||||
|
||||
final String group1Id = "group1";
|
||||
final String group2Id = "group2";
|
||||
@@ -522,4 +519,13 @@ public class JdbcMessageStoreTests {
|
||||
assertThat(messageGroup.isComplete()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageGroupCondition() {
|
||||
String groupId = "X";
|
||||
Message<String> message = MessageBuilder.withPayload("foo").build();
|
||||
this.messageStore.addMessagesToGroup(groupId, message);
|
||||
this.messageStore.setGroupCondition(groupId, "testCondition");
|
||||
assertThat(this.messageStore.getMessageGroup(groupId).getCondition()).isEqualTo("testCondition");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user