aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java74
-rw-r--r--sonar-db/src/test/java/org/sonar/db/DatabaseCheckerTest.java63
2 files changed, 101 insertions, 36 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java b/sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java
index 1e74532700d..eb436a8a155 100644
--- a/sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java
+++ b/sonar-db/src/main/java/org/sonar/db/DatabaseChecker.java
@@ -20,19 +20,34 @@
package org.sonar.db;
import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
import java.sql.Connection;
import java.sql.SQLException;
-import org.apache.commons.dbutils.DbUtils;
+import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.picocontainer.Startable;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+/**
+ * Fail-fast checks of some database requirements
+ */
public class DatabaseChecker implements Startable {
- public static final int ORACLE_MIN_MAJOR_VERSION = 11;
+ private static final Map<String, Version> MINIMAL_SUPPORTED_DB_VERSIONS = ImmutableMap.of(
+ // MsSQL 2008 is 10.x
+ // MsSQL 2012 is 11.x
+ // MsSQL 2014 is 12.x
+ // https://support.microsoft.com/en-us/kb/321185
+ MsSql.ID, new Version(10, 0),
+ MySql.ID, new Version(5, 6),
+ Oracle.ID, new Version(11, 0),
+ PostgreSql.ID, new Version(8, 0));
private final Database db;
@@ -43,12 +58,15 @@ public class DatabaseChecker implements Startable {
@Override
public void start() {
try {
+ checkMinDatabaseVersion();
+
+ // additional checks
if (H2.ID.equals(db.getDialect().getId())) {
Loggers.get(DatabaseChecker.class).warn("H2 database should be used for evaluation purpose only");
} else if (Oracle.ID.equals(db.getDialect().getId())) {
- checkOracleVersion();
+ checkOracleDriverVersion();
}
- } catch (Exception e) {
+ } catch (SQLException e) {
Throwables.propagate(e);
}
}
@@ -58,29 +76,49 @@ public class DatabaseChecker implements Startable {
// nothing to do
}
- private void checkOracleVersion() throws SQLException {
- Connection connection = db.getDataSource().getConnection();
- try {
- // check version of db
- // See http://jira.sonarsource.com/browse/SONAR-6434
- int majorVersion = connection.getMetaData().getDatabaseMajorVersion();
- if (majorVersion < ORACLE_MIN_MAJOR_VERSION) {
- throw MessageException.of(String.format(
- "Unsupported Oracle version: %s. Minimal required version is %d.", connection.getMetaData().getDatabaseProductVersion(), ORACLE_MIN_MAJOR_VERSION));
+ private void checkMinDatabaseVersion() throws SQLException {
+ Version minDbVersion = MINIMAL_SUPPORTED_DB_VERSIONS.get(db.getDialect().getId());
+ if (minDbVersion != null) {
+ try (Connection connection = db.getDataSource().getConnection()) {
+ int dbMajorVersion = connection.getMetaData().getDatabaseMajorVersion();
+ int dbMinorVersion = connection.getMetaData().getDatabaseMinorVersion();
+ Version dbVersion = new Version(dbMajorVersion, dbMinorVersion);
+ if (!dbVersion.isGreaterThanOrEqual(minDbVersion)) {
+ throw MessageException.of(String.format(
+ "Unsupported %s version: %s. Minimal supported version is %s.", db.getDialect().getId(), dbVersion, minDbVersion));
+ }
}
+ }
+ }
- // check version of driver
+ private void checkOracleDriverVersion() throws SQLException {
+ try (Connection connection = db.getDataSource().getConnection()) {
String driverVersion = connection.getMetaData().getDriverVersion();
String[] parts = StringUtils.split(driverVersion, ".");
int intVersion = Integer.parseInt(parts[0]) * 100 + Integer.parseInt(parts[1]);
if (intVersion < 1102) {
throw MessageException.of(String.format(
- "Unsupported Oracle JDBC driver version: %s. Minimal required version is 11.2.", driverVersion));
+ "Unsupported Oracle driver version: %s. Minimal supported version is 11.2.", driverVersion));
}
-
- } finally {
- DbUtils.closeQuietly(connection);
}
}
+ private static class Version {
+ private final int major;
+ private final int minor;
+
+ public Version(int major, int minor) {
+ this.major = major;
+ this.minor = minor;
+ }
+
+ public boolean isGreaterThanOrEqual(Version other) {
+ return major >= other.major && (major != other.major || minor >= other.minor);
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder().append(major).append(".").append(minor).toString();
+ }
+ }
}
diff --git a/sonar-db/src/test/java/org/sonar/db/DatabaseCheckerTest.java b/sonar-db/src/test/java/org/sonar/db/DatabaseCheckerTest.java
index 3b09f853c60..59ffa7f3af8 100644
--- a/sonar-db/src/test/java/org/sonar/db/DatabaseCheckerTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/DatabaseCheckerTest.java
@@ -20,8 +20,9 @@
package org.sonar.db;
import java.sql.SQLException;
-import org.apache.commons.lang.StringUtils;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import org.sonar.api.utils.MessageException;
import org.sonar.db.dialect.Dialect;
@@ -30,66 +31,70 @@ import org.sonar.db.dialect.MySql;
import org.sonar.db.dialect.Oracle;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.is;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class DatabaseCheckerTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
@Test
public void requires_oracle_driver_11_2() throws Exception {
- Database db = mockDb(new Oracle(), "11.2.1", "11.2.0.0.1");
+ Database db = mockDb(new Oracle(), 11, 2, "11.2.0.0.1");
new DatabaseChecker(db).start();
// no error
- db = mockDb(new Oracle(), "11.2.1", "11.3.1");
+ db = mockDb(new Oracle(), 11, 2, "11.3.1");
new DatabaseChecker(db).start();
// no error
- db = mockDb(new Oracle(), "11.2.1", "12.0.2");
+ db = mockDb(new Oracle(), 11, 2, "12.0.2");
new DatabaseChecker(db).start();
// no error
- db = mockDb(new Oracle(), "11.2.1", "11.1.0.2");
+ db = mockDb(new Oracle(), 11, 2, "11.1.0.2");
try {
new DatabaseChecker(db).start();
fail();
} catch (MessageException e) {
- assertThat(e).hasMessage("Unsupported Oracle JDBC driver version: 11.1.0.2. Minimal required version is 11.2.");
+ assertThat(e).hasMessage("Unsupported Oracle driver version: 11.1.0.2. Minimal supported version is 11.2.");
}
}
@Test
public void requires_oracle_11g_or_greater() throws Exception {
// oracle 11.0 is ok
- Database db = mockDb(new Oracle(), "11.0.1", "11.2.0.0.1");
+ Database db = mockDb(new Oracle(), 11, 0, "11.2.0.0.1");
new DatabaseChecker(db).start();
// oracle 11.1 is ok
- db = mockDb(new Oracle(), "11.1.1", "11.2.0.0.1");
+ db = mockDb(new Oracle(), 11, 1, "11.2.0.0.1");
new DatabaseChecker(db).start();
// oracle 11.2 is ok
- db = mockDb(new Oracle(), "11.2.1", "11.2.0.0.1");
+ db = mockDb(new Oracle(), 11, 2, "11.2.0.0.1");
new DatabaseChecker(db).start();
// oracle 12 is ok
- db = mockDb(new Oracle(), "12.0.1", "11.2.0.0.1");
+ db = mockDb(new Oracle(), 12, 0, "11.2.0.0.1");
new DatabaseChecker(db).start();
// oracle 10 is not supported
- db = mockDb(new Oracle(), "10.2.1", "11.2.0.0.1");
+ db = mockDb(new Oracle(), 10, 2, "11.2.0.0.1");
try {
new DatabaseChecker(db).start();
fail();
} catch (MessageException e) {
- assertThat(e).hasMessage("Unsupported Oracle version: 10.2.1. Minimal required version is 11.");
+ assertThat(e).hasMessage("Unsupported oracle version: 10.2. Minimal supported version is 11.0.");
}
}
@Test
public void log_warning_if_h2() throws Exception {
- Database db = mockDb(new H2(), "13.4", "13.4");
+ Database db = mockDb(new H2(), 13, 4, "13.4");
DatabaseChecker checker = new DatabaseChecker(db);
checker.start();
checker.stop();
@@ -97,17 +102,39 @@ public class DatabaseCheckerTest {
}
@Test
- public void do_not_fail_if_mysql() throws Exception {
- Database db = mockDb(new MySql(), "5.7", "5.7");
+ public void test_mysql() throws Exception {
+ Database db = mockDb(new MySql(), 5, 7, "5.7");
new DatabaseChecker(db).start();
// no error
}
- private Database mockDb(Dialect dialect, String dbVersion, String driverVersion) throws SQLException {
+ @Test
+ public void fail_if_mysql_less_than_5_6() throws Exception {
+ expectedException.expect(MessageException.class);
+ expectedException.expectMessage("Unsupported mysql version: 5.5. Minimal supported version is 5.6.");
+
+ Database db = mockDb(new MySql(), 5, 5, "5.6");
+ new DatabaseChecker(db).start();
+ }
+
+ @Test
+ public void fail_if_cant_get_db_version() throws Exception {
+ SQLException sqlException = new SQLException();
+ expectedException.expect(RuntimeException.class);
+ expectedException.expectCause(is(sqlException));
+
+ Database db = mock(Database.class, Mockito.RETURNS_DEEP_STUBS);
+ when(db.getDialect()).thenReturn(new MySql());
+ when(db.getDataSource().getConnection().getMetaData()).thenThrow(sqlException);
+
+ new DatabaseChecker(db).start();
+ }
+
+ private Database mockDb(Dialect dialect, int dbMajorVersion, int dbMinorVersion, String driverVersion) throws SQLException {
Database db = mock(Database.class, Mockito.RETURNS_DEEP_STUBS);
when(db.getDialect()).thenReturn(dialect);
- when(db.getDataSource().getConnection().getMetaData().getDatabaseMajorVersion()).thenReturn(Integer.parseInt(StringUtils.substringBefore(dbVersion, ".")));
- when(db.getDataSource().getConnection().getMetaData().getDatabaseProductVersion()).thenReturn(dbVersion);
+ when(db.getDataSource().getConnection().getMetaData().getDatabaseMajorVersion()).thenReturn(dbMajorVersion);
+ when(db.getDataSource().getConnection().getMetaData().getDatabaseMinorVersion()).thenReturn(dbMinorVersion);
when(db.getDataSource().getConnection().getMetaData().getDriverVersion()).thenReturn(driverVersion);
return db;
}