Skip to content

Commit 8ab2b1e

Browse files
authored
Add support for MySQL 5/8 via MariaDB driver (spring-attic#5071)
* Use FlywayVendorReplacingEnvironmentPostProcessor to replace {vendor} in spring.flyways.locations * Add back in the MySQL schema * Use vendor (mysql) not driver in flyway configuration customizer See spring-attic#4887
1 parent 888666c commit 8ab2b1e

23 files changed

+1393
-141
lines changed

spring-cloud-dataflow-server-core/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,16 @@
195195
<artifactId>spring-batch-test</artifactId>
196196
<scope>test</scope>
197197
</dependency>
198+
<dependency>
199+
<groupId>org.testcontainers</groupId>
200+
<artifactId>junit-jupiter</artifactId>
201+
<scope>test</scope>
202+
</dependency>
203+
<dependency>
204+
<groupId>org.testcontainers</groupId>
205+
<artifactId>mariadb</artifactId>
206+
<scope>test</scope>
207+
</dependency>
198208
</dependencies>
199209
<build>
200210
<resources>

spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/db/migration/DataFlowFlywayConfigurationCustomizer.java

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,46 @@
1818
import javax.sql.DataSource;
1919

2020
import org.flywaydb.core.api.configuration.FluentConfiguration;
21+
import org.slf4j.Logger;
22+
import org.slf4j.LoggerFactory;
2123

2224
import org.springframework.boot.autoconfigure.flyway.FlywayConfigurationCustomizer;
2325
import org.springframework.boot.jdbc.DatabaseDriver;
26+
import org.springframework.cloud.dataflow.common.flyway.DatabaseDriverUtils;
2427
import org.springframework.cloud.dataflow.server.db.migration.db2.Db2BeforeBaseline;
2528
import org.springframework.cloud.dataflow.server.db.migration.mariadb.MariadbBeforeBaseline;
29+
import org.springframework.cloud.dataflow.server.db.migration.mysql.MysqlBeforeBaseline;
2630
import org.springframework.cloud.dataflow.server.db.migration.oracle.OracleBeforeBaseline;
2731
import org.springframework.cloud.dataflow.server.db.migration.postgresql.PostgresBeforeBaseline;
2832
import org.springframework.cloud.dataflow.server.db.migration.sqlserver.MsSqlBeforeBaseline;
29-
import org.springframework.jdbc.support.JdbcUtils;
30-
import org.springframework.jdbc.support.MetaDataAccessException;
3133

3234
/**
3335
* Flyway {@link FlywayConfigurationCustomizer} bean customizing callbacks per
3436
* active db vendor.
3537
*
3638
* @author Janne Valkealahti
37-
*
39+
* @author Chris Bono
3840
*/
3941
public class DataFlowFlywayConfigurationCustomizer implements FlywayConfigurationCustomizer {
4042

43+
private static final Logger LOG = LoggerFactory.getLogger(DataFlowFlywayConfigurationCustomizer.class);
44+
4145
@Override
4246
public void customize(FluentConfiguration configuration) {
43-
// boot's flyway auto-config doesn't allow to define callbacks per
47+
// Boot's flyway auto-config doesn't allow to define callbacks per
4448
// vendor id, so essentially customizing those here.
4549
DataSource dataSource = configuration.getDataSource();
46-
DatabaseDriver databaseDriver = getDatabaseDriver(dataSource);
50+
DatabaseDriver databaseDriver = DatabaseDriverUtils.getDatabaseDriver(dataSource);
51+
LOG.info("Adding vendor specific Flyway callback for {}", databaseDriver.name());
4752
if (databaseDriver == DatabaseDriver.POSTGRESQL) {
4853
configuration.callbacks(new PostgresBeforeBaseline());
4954
}
5055
else if (databaseDriver == DatabaseDriver.MARIADB) {
5156
configuration.callbacks(new MariadbBeforeBaseline());
5257
}
58+
else if (databaseDriver == DatabaseDriver.MYSQL) {
59+
configuration.callbacks(new MysqlBeforeBaseline());
60+
}
5361
else if (databaseDriver == DatabaseDriver.SQLSERVER) {
5462
configuration.callbacks(new MsSqlBeforeBaseline());
5563
}
@@ -60,15 +68,4 @@ else if (databaseDriver == DatabaseDriver.DB2) {
6068
configuration.callbacks(new Db2BeforeBaseline());
6169
}
6270
}
63-
64-
private DatabaseDriver getDatabaseDriver(DataSource dataSource) {
65-
// copied from boot's flyway auto-config to get matching db vendor id
66-
try {
67-
String url = JdbcUtils.extractDatabaseMetaData(dataSource, "getURL");
68-
return DatabaseDriver.fromJdbcUrl(url);
69-
}
70-
catch (MetaDataAccessException ex) {
71-
throw new IllegalStateException(ex);
72-
}
73-
}
7471
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/*
2+
* Copyright 2019-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.cloud.dataflow.server.db.migration.mysql;
17+
18+
import java.util.Arrays;
19+
import java.util.List;
20+
21+
import org.springframework.cloud.dataflow.common.flyway.SqlCommand;
22+
import org.springframework.cloud.dataflow.server.db.migration.AbstractBaselineCallback;
23+
24+
/**
25+
* Baselining schema setup for {@code postgres}.
26+
*
27+
* @author Janne Valkealahti
28+
* @author Chris Bono
29+
*/
30+
public class MysqlBeforeBaseline extends AbstractBaselineCallback {
31+
32+
public final static String DROP_AUDIT_RECORDS_AUDIT_ACTION_IDX_INDEX =
33+
"drop index AUDIT_RECORDS_AUDIT_ACTION_IDX on AUDIT_RECORDS";
34+
35+
public final static String DROP_AUDIT_RECORDS_AUDIT_OPERATION_IDX_INDEX =
36+
"drop index AUDIT_RECORDS_AUDIT_OPERATION_IDX on AUDIT_RECORDS";
37+
38+
public final static String DROP_AUDIT_RECORDS_CORRELATION_ID_IDX_INDEX =
39+
"drop index AUDIT_RECORDS_CORRELATION_ID_IDX on AUDIT_RECORDS";
40+
41+
public final static String DROP_AUDIT_RECORDS_CREATED_ON_IDX_INDEX =
42+
"drop index AUDIT_RECORDS_CREATED_ON_IDX on AUDIT_RECORDS";
43+
44+
public final static String CREATE_APP_REGISTRATION_TMP_TABLE =
45+
V1__Initial_Setup.CREATE_APP_REGISTRATION_TABLE.replaceFirst("app_registration", "app_registration_tmp");
46+
47+
public final static String INSERT_APP_REGISTRATION_DATA =
48+
"insert into\n" +
49+
" app_registration_tmp (id, object_version, default_version, metadata_uri, name, type, uri, version) \n" +
50+
" select id, object_Version, default_Version, metadata_Uri, name, type, uri, version\n" +
51+
" from APP_REGISTRATION";
52+
53+
public final static String DROP_APP_REGISTRATION_TABLE =
54+
"drop table APP_REGISTRATION";
55+
56+
public final static String RENAME_APP_REGISTRATION_TMP_TABLE =
57+
"alter table app_registration_tmp rename to app_registration";
58+
59+
public final static String CREATE_STREAM_DEFINITIONS_TMP_TABLE =
60+
V1__Initial_Setup.CREATE_STREAM_DEFINITIONS_TABLE.replaceFirst("stream_definitions", "stream_definitions_tmp");
61+
62+
public final static String INSERT_STREAM_DEFINITIONS_DATA =
63+
"insert into\n" +
64+
" stream_definitions_tmp (definition_name, definition) \n" +
65+
" select DEFINITION_NAME, DEFINITION\n" +
66+
" from STREAM_DEFINITIONS";
67+
68+
public final static String DROP_STREAM_DEFINITIONS_TABLE =
69+
"drop table STREAM_DEFINITIONS";
70+
71+
public final static String RENAME_STREAM_DEFINITIONS_TMP_TABLE =
72+
"alter table stream_definitions_tmp rename to stream_definitions";
73+
74+
public final static String CREATE_TASK_DEFINITIONS_TMP_TABLE =
75+
V1__Initial_Setup.CREATE_TASK_DEFINITIONS_TABLE.replaceFirst("task_definitions", "task_definitions_tmp");
76+
77+
public final static String INSERT_TASK_DEFINITIONS_DATA =
78+
"insert into\n" +
79+
" task_definitions_tmp (definition_name, definition) \n" +
80+
" select DEFINITION_NAME, DEFINITION\n" +
81+
" from TASK_DEFINITIONS";
82+
83+
public final static String DROP_TASK_DEFINITIONS_TABLE =
84+
"drop table TASK_DEFINITIONS";
85+
86+
public final static String RENAME_TASK_DEFINITIONS_TMP_TABLE =
87+
"alter table task_definitions_tmp rename to task_definitions";
88+
89+
public final static String CREATE_AUDIT_RECORDS_TMP_TABLE =
90+
V1__Initial_Setup.CREATE_AUDIT_RECORDS_TABLE.replaceFirst("audit_records", "audit_records_tmp");
91+
92+
public final static String INSERT_AUDIT_RECORDS_DATA =
93+
"insert into\n" +
94+
" audit_records_tmp (id, audit_action, audit_data, audit_operation, correlation_id, created_by, created_on)\n" +
95+
" select id, audit_Action, audit_data, audit_Operation, correlation_id, created_by, created_On\n" +
96+
" from AUDIT_RECORDS";
97+
98+
public final static String DROP_AUDIT_RECORDS_TABLE =
99+
"drop table AUDIT_RECORDS";
100+
101+
public final static String RENAME_AUDIT_RECORDS_TMP_TABLE =
102+
"alter table audit_records_tmp rename to audit_records";
103+
104+
public final static String CREATE_AUDIT_RECORDS_AUDIT_ACTION_IDX_INDEX =
105+
"create index audit_records_audit_action_idx on audit_records (audit_action)";
106+
107+
public final static String CREATE_AUDIT_RECORDS_AUDIT_OPERATION_IDX_INDEX =
108+
"create index audit_records_audit_operation_idx on audit_records (audit_operation)";
109+
110+
public final static String CREATE_AUDIT_RECORDS_CORRELATION_ID_IDX_INDEX =
111+
"create index audit_records_correlation_id_idx on audit_records (correlation_id)";
112+
113+
public final static String CREATE_AUDIT_RECORDS_CREATED_ON_IDX_INDEX =
114+
"create index audit_records_created_on_idx on audit_records (created_on)";
115+
116+
/**
117+
* Instantiates a new postgres before baseline.
118+
*/
119+
public MysqlBeforeBaseline() {
120+
super(new V1__Initial_Setup());
121+
}
122+
123+
@Override
124+
public List<SqlCommand> dropIndexes() {
125+
return Arrays.asList(
126+
SqlCommand.from(DROP_AUDIT_RECORDS_AUDIT_ACTION_IDX_INDEX),
127+
SqlCommand.from(DROP_AUDIT_RECORDS_AUDIT_OPERATION_IDX_INDEX),
128+
SqlCommand.from(DROP_AUDIT_RECORDS_CORRELATION_ID_IDX_INDEX),
129+
SqlCommand.from(DROP_AUDIT_RECORDS_CREATED_ON_IDX_INDEX));
130+
}
131+
132+
@Override
133+
public List<SqlCommand> changeAppRegistrationTable() {
134+
return Arrays.asList(
135+
SqlCommand.from(CREATE_APP_REGISTRATION_TMP_TABLE),
136+
SqlCommand.from(INSERT_APP_REGISTRATION_DATA),
137+
SqlCommand.from(DROP_APP_REGISTRATION_TABLE),
138+
SqlCommand.from(RENAME_APP_REGISTRATION_TMP_TABLE));
139+
}
140+
141+
@Override
142+
public List<SqlCommand> changeUriRegistryTable() {
143+
return Arrays.asList(
144+
new MysqlMigrateUriRegistrySqlCommand());
145+
}
146+
147+
@Override
148+
public List<SqlCommand> changeStreamDefinitionsTable() {
149+
return Arrays.asList(
150+
SqlCommand.from(CREATE_STREAM_DEFINITIONS_TMP_TABLE),
151+
SqlCommand.from(INSERT_STREAM_DEFINITIONS_DATA),
152+
SqlCommand.from(DROP_STREAM_DEFINITIONS_TABLE),
153+
SqlCommand.from(RENAME_STREAM_DEFINITIONS_TMP_TABLE));
154+
}
155+
156+
@Override
157+
public List<SqlCommand> changeTaskDefinitionsTable() {
158+
return Arrays.asList(
159+
SqlCommand.from(CREATE_TASK_DEFINITIONS_TMP_TABLE),
160+
SqlCommand.from(INSERT_TASK_DEFINITIONS_DATA),
161+
SqlCommand.from(DROP_TASK_DEFINITIONS_TABLE),
162+
SqlCommand.from(RENAME_TASK_DEFINITIONS_TMP_TABLE));
163+
}
164+
165+
@Override
166+
public List<SqlCommand> changeAuditRecordsTable() {
167+
return Arrays.asList(
168+
SqlCommand.from(CREATE_AUDIT_RECORDS_TMP_TABLE),
169+
SqlCommand.from(INSERT_AUDIT_RECORDS_DATA),
170+
SqlCommand.from(DROP_AUDIT_RECORDS_TABLE),
171+
SqlCommand.from(RENAME_AUDIT_RECORDS_TMP_TABLE));
172+
}
173+
174+
@Override
175+
public List<SqlCommand> createIndexes() {
176+
return Arrays.asList(
177+
SqlCommand.from(CREATE_AUDIT_RECORDS_AUDIT_ACTION_IDX_INDEX),
178+
SqlCommand.from(CREATE_AUDIT_RECORDS_AUDIT_OPERATION_IDX_INDEX),
179+
SqlCommand.from(CREATE_AUDIT_RECORDS_CORRELATION_ID_IDX_INDEX),
180+
SqlCommand.from(CREATE_AUDIT_RECORDS_CREATED_ON_IDX_INDEX));
181+
}
182+
183+
@Override
184+
public List<SqlCommand> createTaskLockTable() {
185+
return Arrays.asList(
186+
SqlCommand.from(V1__Initial_Setup.CREATE_TASK_LOCK_TABLE));
187+
}
188+
189+
@Override
190+
public List<SqlCommand> createTaskDeploymentTable() {
191+
return Arrays.asList(SqlCommand.from(
192+
V1__Initial_Setup.CREATE_TASK_DEPLOYMENT_TABLE));
193+
}
194+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2019-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.cloud.dataflow.server.db.migration.mysql;
17+
18+
import java.util.List;
19+
20+
import org.postgresql.core.SqlCommand;
21+
22+
import org.springframework.cloud.dataflow.server.db.migration.AbstractMigrateUriRegistrySqlCommand;
23+
import org.springframework.jdbc.core.JdbcTemplate;
24+
25+
/**
26+
* {@code mysql} related {@link SqlCommand} for migrating data from
27+
* {@code URI_REGISTRY} into {@code app_registration}.
28+
*
29+
* @author Janne Valkealahti
30+
* @author Chris Bono
31+
*/
32+
public class MysqlMigrateUriRegistrySqlCommand extends AbstractMigrateUriRegistrySqlCommand {
33+
34+
@Override
35+
protected void updateAppRegistration(JdbcTemplate jdbcTemplate, List<AppRegistrationMigrationData> data) {
36+
// get value from hibernate sequence table and update it later
37+
// depending on how many updates we did
38+
long nextVal = jdbcTemplate.queryForObject("select next_val as id_val from hibernate_sequence", Long.class);
39+
long nextValUpdates = nextVal;
40+
for (AppRegistrationMigrationData d : data) {
41+
jdbcTemplate.update(
42+
"insert into app_registration (id, object_version, default_version, metadata_uri, name, type, uri, version) values (?,?,?,?,?,?,?,?)",
43+
nextValUpdates++, 0, d.isDefaultVersion() ? 1 : 0, d.getMetadataUri(), d.getName(), d.getType(),
44+
d.getUri(), d.getVersion());
45+
}
46+
jdbcTemplate.update("update hibernate_sequence set next_val= ? where next_val=?", nextValUpdates, nextVal);
47+
}
48+
}

0 commit comments

Comments
 (0)