aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-12-07 15:04:10 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-12-14 12:11:51 +0100
commit080a0fb172ad6178fef529480b5ace5d0a66f06a (patch)
treedf39d41d1557e16955bf99621b2e5dc5d407a880 /server
parent460eee7ce980e719ee1de7873b8fd22bf40f3532 (diff)
downloadsonarqube-080a0fb172ad6178fef529480b5ace5d0a66f06a.tar.gz
sonarqube-080a0fb172ad6178fef529480b5ace5d0a66f06a.zip
SONAR-8445 handle creation of table SCHEMA_MIGRATIONS in Java
Diffstat (limited to 'server')
-rw-r--r--server/sonar-db-migration/pom.xml35
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTable.java48
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java80
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/package-info.java24
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImplTest.java77
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImplTest/empty.sql0
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java12
8 files changed, 274 insertions, 4 deletions
diff --git a/server/sonar-db-migration/pom.xml b/server/sonar-db-migration/pom.xml
index 9ece9a01e95..21f004d69eb 100644
--- a/server/sonar-db-migration/pom.xml
+++ b/server/sonar-db-migration/pom.xml
@@ -14,8 +14,43 @@
<description>Create SonarQube schema</description>
<dependencies>
+ <dependency>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonar-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonar-db</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- tests -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sonar-testing-harness</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sonar-db</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.dbunit</groupId>
+ <artifactId>dbunit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTable.java
new file mode 100644
index 00000000000..a74fd0866fb
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTable.java
@@ -0,0 +1,48 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.history;
+
+import org.sonar.api.Startable;
+
+/**
+ * This class is responsible for ensuring at startup that the persistence of migration history is possible.
+ * <p>
+ * Therefor, it will create the migration history table if it does not exist yet, update it if necessary and fail
+ * if any of the two previous operations fails.
+ * </p>
+ * <p>
+ * This class is intended to be present only in the WebServer and only the web server is the startup leader.
+ * </p>
+ */
+public interface MigrationHistoryTable extends Startable {
+ String NAME = "schema_migrations";
+
+ /**
+ * Ensures that the history of db migrations can be persisted to database:
+ * <ul>
+ * <li>underlying table {@code SCHEMA_MIGRATIONS} is created if it does not exist</li>
+ * <li>underlying table {@code SCHEMA_MIGRATIONS} is updated if needed</li>
+ * </ul>
+ *
+ * @throws IllegalStateException if we can not ensure that table {@code SCHEMA_MIGRATIONS} can be accessed correctly
+ */
+ @Override
+ void start();
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java
new file mode 100644
index 00000000000..68043682b38
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImpl.java
@@ -0,0 +1,80 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.history;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.db.DatabaseUtils;
+import org.sonar.db.DbClient;
+import org.sonar.db.version.CreateTableBuilder;
+import org.sonar.db.version.VarcharColumnDef;
+
+public class MigrationHistoryTableImpl implements MigrationHistoryTable {
+ private static final String VERSION_COLUMN_NAME = "version";
+
+ private final DbClient dbClient;
+
+ public MigrationHistoryTableImpl(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ @Override
+ public void start() {
+ try (Connection connection = createDdlConnection(dbClient)) {
+ if (!DatabaseUtils.tableExists(NAME, connection)) {
+ createTable(connection);
+ }
+ } catch (SQLException e) {
+ throw new IllegalStateException("Failed to create table " + NAME, e);
+ }
+ }
+
+ private void createTable(Connection connection) throws SQLException {
+ List<String> sqls = new CreateTableBuilder(dbClient.getDatabase().getDialect(), NAME)
+ .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder().setColumnName(VERSION_COLUMN_NAME).setIsNullable(false).setLimit(255).build())
+ .build();
+
+ Loggers.get(MigrationHistoryTableImpl.class).info("Creating table " + NAME);
+ for (String sql : sqls) {
+ execute(connection, sql);
+ }
+ }
+
+ private static Connection createDdlConnection(DbClient dbClient) throws SQLException {
+ Connection res = dbClient.getDatabase().getDataSource().getConnection();
+ res.setAutoCommit(false);
+ return res;
+ }
+
+ private static void execute(Connection connection, String sql) throws SQLException {
+ try (Statement stmt = connection.createStatement()) {
+ stmt.execute(sql);
+ connection.commit();
+ }
+ }
+
+ @Override
+ public void stop() {
+ // nothing to do
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/package-info.java
new file mode 100644
index 00000000000..894d41a5e42
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/history/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.platform.db.migration.history;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImplTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImplTest.java
new file mode 100644
index 00000000000..958728c17f3
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImplTest.java
@@ -0,0 +1,77 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.history;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MigrationHistoryTableImplTest {
+ private static final String TABLE_SCHEMA_MIGRATIONS = "schema_migrations";
+
+ @Rule
+ public DbTester dbTester = DbTester.createForSchema(System2.INSTANCE, MigrationHistoryTableImplTest.class, "empty.sql");
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private MigrationHistoryTableImpl underTest = new MigrationHistoryTableImpl(dbTester.getDbClient());
+
+ @Test
+ public void start_creates_table_on_empty_schema() {
+ underTest.start();
+
+ verifyTable();
+ }
+
+ @Test
+ public void start_does_not_fail_if_table_exists() throws SQLException {
+ executeDdl("create table " + TABLE_SCHEMA_MIGRATIONS + " (version varchar(255) not null)");
+ verifyTable();
+
+ underTest.start();
+
+ verifyTable();
+ }
+
+ private void executeDdl(String sql) throws SQLException {
+ try (DbSession dbSession = dbTester.getDbClient().openSession(false);
+ Connection connection = dbSession.getConnection()) {
+ connection.setAutoCommit(false);
+ try (Statement statement = connection.createStatement()) {
+ statement.execute(sql);
+ connection.commit();
+ }
+ }
+ }
+
+ private void verifyTable() {
+ assertThat(dbTester.countRowsOfTable(TABLE_SCHEMA_MIGRATIONS)).isEqualTo(0);
+ dbTester.assertColumnDefinition(TABLE_SCHEMA_MIGRATIONS, "version", Types.VARCHAR, 255, false);
+ }
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImplTest/empty.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImplTest/empty.sql
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/history/MigrationHistoryTableImplTest/empty.sql
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java
index 39a9bbcfe58..1435468e39a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/DatabaseMigrator.java
@@ -113,6 +113,6 @@ public class DatabaseMigrator implements Startable {
@VisibleForTesting
protected void createSchema(Connection connection, String dialectId) {
- DdlUtils.createSchema(connection, dialectId);
+ DdlUtils.createSchema(connection, dialectId, false);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
index b3786b8dc7d..c4356cec0d6 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
@@ -29,6 +29,7 @@ import org.sonar.db.version.MigrationStepModule;
import org.sonar.server.platform.DefaultServerUpgradeStatus;
import org.sonar.server.platform.StartupMetadataProvider;
import org.sonar.server.platform.db.CheckDatabaseCharsetAtStartup;
+import org.sonar.server.platform.db.migration.history.MigrationHistoryTableImpl;
import org.sonar.server.platform.db.migrations.DatabaseMigrator;
import org.sonar.server.platform.db.migrations.PlatformDatabaseMigration;
import org.sonar.server.platform.db.migrations.PlatformDatabaseMigrationExecutorServiceImpl;
@@ -67,11 +68,16 @@ public class PlatformLevel2 extends PlatformLevel {
// depends on plugins
RailsAppsDeployer.class,
DefaultI18n.class,
- RuleI18nManager.class,
+ RuleI18nManager.class);
- // DB migration
+ // Full Java DB Migration framework and configuration
+ addIfStartupLeader(MigrationHistoryTableImpl.class);
+ // platform DB migration (TODO remove call to Ruby's Active Record and use DbMigrationEngine instead)
+ add(
PlatformDatabaseMigrationExecutorServiceImpl.class,
- PlatformDatabaseMigration.class,
+ PlatformDatabaseMigration.class);
+ // Ruby DB Migration
+ add(
DatabaseMigrator.class,
MigrationStepModule.class);