diff --git a/addons/common/flyway/pom.xml b/addons/common/flyway/pom.xml index 8c4eb821c66..0f87d80d7b3 100644 --- a/addons/common/flyway/pom.xml +++ b/addons/common/flyway/pom.xml @@ -86,6 +86,16 @@ h2 test + + org.mockito + mockito-core + test + + + org.mockito + mockito-junit-jupiter + test + \ No newline at end of file diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieFlywayInitializer.java b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieFlywayInitializer.java index 8986b7a428f..20ed87864a5 100644 --- a/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieFlywayInitializer.java +++ b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/KieFlywayInitializer.java @@ -19,7 +19,6 @@ package org.kie.flyway.initializer; -import java.sql.Connection; import java.util.*; import java.util.stream.Collectors; @@ -27,12 +26,14 @@ import org.flywaydb.core.Flyway; import org.kie.flyway.KieFlywayException; +import org.kie.flyway.initializer.db.DataBaseInfo; import org.kie.flyway.initializer.impl.DefaultKieModuleFlywayConfigLoader; import org.kie.flyway.model.KieFlywayModuleConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static java.util.stream.Collectors.groupingBy; +import static org.kie.flyway.initializer.db.KieFlywayDataBaseHelper.readDataBaseInfo; public class KieFlywayInitializer { private static final String KIE_FLYWAY_BASELINE_VERSION = "0.0"; @@ -45,13 +46,13 @@ public class KieFlywayInitializer { private final KieModuleFlywayConfigLoader configLoader; private final DataSource dataSource; - private final String databaseType; + private final DataBaseInfo databaseInfo; private final List moduleExclusions; private KieFlywayInitializer(KieModuleFlywayConfigLoader configLoader, DataSource dataSource, Collection moduleExclusions) { this.configLoader = configLoader; this.dataSource = dataSource; - this.databaseType = getDataSourceType(dataSource); + this.databaseInfo = readDataBaseInfo(dataSource); this.moduleExclusions = new ArrayList<>(moduleExclusions); } @@ -80,15 +81,6 @@ private void checkDuplicatedModuleConfigs(Collection conf } } - private String getDataSourceType(DataSource dataSource) { - try (Connection con = dataSource.getConnection()) { - return con.getMetaData().getDatabaseProductName().toLowerCase(); - } catch (Exception e) { - LOGGER.error("Kie Flyway: Couldn't extract database product name from datasource ", e); - throw new KieFlywayException("Kie Flyway: Couldn't extract database product name from datasource.", e); - } - } - private void runFlyway(KieFlywayModuleConfig config) { LOGGER.debug("Running Flyway for module: {}", config.getModule()); @@ -97,11 +89,11 @@ private void runFlyway(KieFlywayModuleConfig config) { return; } - String[] locations = config.getDBScriptLocations(databaseType); + String[] locations = config.getDBScriptLocations(databaseInfo.getNormalizedName()); if (Objects.isNull(locations)) { - LOGGER.warn("Cannot run Flyway migration for module `{}`, cannot find SQL Script locations for db `{}`", config.getModule(), databaseType); - throw new KieFlywayException("Cannot run Flyway migration for module `" + config.getModule() + "`, cannot find SQL Script locations for db `" + databaseType + "`"); + LOGGER.warn("Cannot run Flyway migration for module `{}`, cannot find SQL Script locations for db `{}`", config.getModule(), databaseInfo); + throw new KieFlywayException("Cannot run Flyway migration for module `" + config.getModule() + "`, cannot find SQL Script locations for db `" + databaseInfo + "`"); } Flyway.configure() diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/initializer/db/DataBaseInfo.java b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/db/DataBaseInfo.java new file mode 100644 index 00000000000..6bafef374b8 --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/db/DataBaseInfo.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.kie.flyway.initializer.db; + +public class DataBaseInfo { + + private final String name; + private final String version; + private final String normalizedName; + + public DataBaseInfo(String name, String version) { + this.name = name; + this.version = version; + this.normalizedName = normalizeName(name); + } + + public String getName() { + return name; + } + + public String getVersion() { + return version; + } + + public String getNormalizedName() { + return normalizedName; + } + + private String normalizeName(String name) { + final String NORMALIZATION_REGEX = "[^a-zA-Z0-9]+"; + String[] fragments = name.split(NORMALIZATION_REGEX); + return String.join("-", fragments).toLowerCase(); + } +} diff --git a/addons/common/flyway/src/main/java/org/kie/flyway/initializer/db/KieFlywayDataBaseHelper.java b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/db/KieFlywayDataBaseHelper.java new file mode 100644 index 00000000000..fa8b7bb074d --- /dev/null +++ b/addons/common/flyway/src/main/java/org/kie/flyway/initializer/db/KieFlywayDataBaseHelper.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.kie.flyway.initializer.db; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; + +import javax.sql.DataSource; + +import org.kie.flyway.KieFlywayException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KieFlywayDataBaseHelper { + private static final Logger LOGGER = LoggerFactory.getLogger(KieFlywayDataBaseHelper.class); + + private KieFlywayDataBaseHelper() { + } + + public static DataBaseInfo readDataBaseInfo(DataSource ds) { + try (Connection con = ds.getConnection()) { + + DatabaseMetaData metadata = con.getMetaData(); + + String name = metadata.getDatabaseProductName(); + String version = metadata.getDatabaseProductVersion(); + + LOGGER.info("Reading DataBase Product: '{}' Version: '{}'", name, version); + + return new DataBaseInfo(name, version); + } catch (Exception e) { + LOGGER.error("Kie Flyway: Couldn't extract database product name from datasource ", e); + throw new KieFlywayException("Kie Flyway: Couldn't extract database product name from datasource.", e); + } + } +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/initializer/db/KieFlywayDataBaseHelperTest.java b/addons/common/flyway/src/test/java/org/kie/flyway/initializer/db/KieFlywayDataBaseHelperTest.java new file mode 100644 index 00000000000..d4d02470734 --- /dev/null +++ b/addons/common/flyway/src/test/java/org/kie/flyway/initializer/db/KieFlywayDataBaseHelperTest.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.kie.flyway.initializer.db; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.util.stream.Stream; + +import javax.sql.DataSource; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.kie.flyway.KieFlywayException; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.kie.flyway.initializer.db.KieFlywayDataBaseHelper.readDataBaseInfo; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class KieFlywayDataBaseHelperTest { + + @Mock + private DataSource dataSource; + + @Mock + private Connection connection; + + @Mock + private DatabaseMetaData metaData; + + @BeforeEach + public void setup() throws Exception { + when(dataSource.getConnection()).thenReturn(connection); + when(connection.getMetaData()).thenReturn(metaData); + } + + @Test + public void testReadDataBaseInfoWithException() { + Assertions.assertThatThrownBy(() -> readDataBaseInfo(dataSource)) + .isInstanceOf(KieFlywayException.class) + .hasMessage("Kie Flyway: Couldn't extract database product name from datasource."); + } + + @ParameterizedTest + @MethodSource("getDataBaseData") + public void testReadDataBaseInfo(String productName, String version, String normalizedName) throws Exception { + when(metaData.getDatabaseProductName()).thenReturn(productName); + when(metaData.getDatabaseProductVersion()).thenReturn(version); + + Assertions.assertThat(readDataBaseInfo(dataSource)) + .hasFieldOrPropertyWithValue("name", productName) + .hasFieldOrPropertyWithValue("version", version) + .hasFieldOrPropertyWithValue("normalizedName", normalizedName); + } + + public static Stream getDataBaseData() { + return Stream.of(Arguments.of("H2", "2.3.232", "h2"), + Arguments.of("PostgreSQL", "42.7.4", "postgresql"), + Arguments.of("My Custom DB Type.", "v1.0", "my-custom-db-type")); + } + +} diff --git a/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/PostgreSQLTestDataSource.java b/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/PostgreSQLTestDataSource.java index dc909d0fa54..b8374493580 100644 --- a/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/PostgreSQLTestDataSource.java +++ b/addons/common/flyway/src/test/java/org/kie/flyway/test/dataSources/PostgreSQLTestDataSource.java @@ -26,7 +26,7 @@ public class PostgreSQLTestDataSource implements TestDataSource { - private PGSimpleDataSource dataSource; + private final PGSimpleDataSource dataSource; public PostgreSQLTestDataSource(KogitoPostgreSqlContainer pgContainer) { dataSource = new PGSimpleDataSource();