From c814f41901217412df14b6cb97eb4575877366ec Mon Sep 17 00:00:00 2001 From: Eric Hartmann Date: Thu, 15 Feb 2018 11:32:15 +0100 Subject: [PATCH] SONAR-10420 Fail at startup when cluster enabled on MySQL --- .../platformlevel/PlatformLevel2.java | 5 ++ .../startup/ClusterConfigurationCheck.java | 50 +++++++++++++ .../platformlevel/PlatformLevel2Test.java | 26 +++++++ .../ClusterConfigurationCheckTest.java | 71 +++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/startup/ClusterConfigurationCheck.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/startup/ClusterConfigurationCheckTest.java 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 a969f6c6a4d..46b544f865d 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 @@ -39,6 +39,7 @@ import org.sonar.server.plugins.InstalledPluginReferentialFactory; import org.sonar.server.plugins.ServerPluginJarExploder; import org.sonar.server.plugins.ServerPluginRepository; import org.sonar.server.plugins.WebServerExtensionInstaller; +import org.sonar.server.startup.ClusterConfigurationCheck; public class PlatformLevel2 extends PlatformLevel { public PlatformLevel2(PlatformLevel parent) { @@ -75,6 +76,10 @@ public class PlatformLevel2 extends PlatformLevel { DatabaseMigrationStateImpl.class, DatabaseMigrationExecutorServiceImpl.class); + addIfCluster( + ClusterConfigurationCheck.class + ); + addIfStartupLeader( DatabaseCharsetChecker.class, CheckDatabaseCharsetAtStartup.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/startup/ClusterConfigurationCheck.java b/server/sonar-server/src/main/java/org/sonar/server/startup/ClusterConfigurationCheck.java new file mode 100644 index 00000000000..c40a839711e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/startup/ClusterConfigurationCheck.java @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info 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.startup; + +import org.picocontainer.Startable; +import org.sonar.db.Database; +import org.sonar.db.dialect.MySql; + +/** + * This class will be check the configuration for a SonarQube cluster + * + * See SONAR-10420 + */ +public class ClusterConfigurationCheck implements Startable { + + private final Database database; + + public ClusterConfigurationCheck(Database database) { + this.database = database; + } + + @Override + public void start() { + if (MySql.ID.equals(database.getDialect().getId())) { + throw new IllegalStateException("MySQL is not supported for Data Center Edition. Please connect to a supported database: Oracle, PostgreSQL, Microsoft SQL Server."); + } + } + + public void stop() { + // Nothing to do + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java b/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java index ba25f1b3fd4..7053b0cf34d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java @@ -30,6 +30,7 @@ import org.sonar.process.ProcessProperties; import org.sonar.server.platform.Platform; import org.sonar.server.platform.WebServer; import org.sonar.server.platform.db.migration.charset.DatabaseCharsetChecker; +import org.sonar.server.startup.ClusterConfigurationCheck; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -85,4 +86,29 @@ public class PlatformLevel2Test { // level2 component that is injected only on "startup leaders" assertThat(underTest.getOptional(DatabaseCharsetChecker.class)).isNotPresent(); } + + @Test + public void add_ClusterConfigurationCheck_when_cluster_mode_activated() { + props.setProperty("sonar.cluster.enabled", "true"); + PlatformLevel1 level1 = new PlatformLevel1(mock(Platform.class), props); + level1.configure(); + + PlatformLevel2 underTest = new PlatformLevel2(level1); + underTest.configure(); + + assertThat(underTest.getOptional(ClusterConfigurationCheck.class)).isPresent(); + } + + @Test + public void do_NOT_add_ClusterConfigurationCheck_when_cluster_mode_NOT_activated() { + props.setProperty("sonar.cluster.enabled", "false"); + PlatformLevel1 level1 = new PlatformLevel1(mock(Platform.class), props); + level1.configure(); + + PlatformLevel2 underTest = new PlatformLevel2(level1); + underTest.configure(); + + assertThat(underTest.getOptional(ClusterConfigurationCheck.class)).isNotPresent(); + + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/ClusterConfigurationCheckTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/ClusterConfigurationCheckTest.java new file mode 100644 index 00000000000..d8da1778dc8 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/startup/ClusterConfigurationCheckTest.java @@ -0,0 +1,71 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info 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.startup; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.db.Database; +import org.sonar.db.dialect.MsSql; +import org.sonar.db.dialect.MySql; +import org.sonar.db.dialect.Oracle; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ClusterConfigurationCheckTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private Database database = mock(Database.class); + private ClusterConfigurationCheck underTest = new ClusterConfigurationCheck(database); + + @Test + public void when_SQ_is_connected_to_MySql_an_ISE_should_be_thrown() { + when(database.getDialect()).thenReturn(new MySql()); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("MySQL is not supported for Data Center Edition. Please connect to a supported database: Oracle, PostgreSQL, Microsoft SQL Server."); + + underTest.start(); + } + + @Test + public void when_SQ_is_connected_to_MsSql_an_ISE_should_NOT_be_thrown() { + when(database.getDialect()).thenReturn(new MsSql()); + + underTest.start(); + } + + @Test + public void when_SQ_is_connected_to_Oracle_an_ISE_should_NOT_be_thrown() { + when(database.getDialect()).thenReturn(new Oracle()); + + underTest.start(); + } + + @Test + public void when_SQ_is_connected_to_Postgres_an_ISE_should_NOT_be_thrown() { + when(database.getDialect()).thenReturn(new Oracle()); + + underTest.start(); + } +} -- 2.39.5