aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaire Villard <claire.villard@sonarsource.com>2024-10-03 11:59:29 +0200
committersonartech <sonartech@sonarsource.com>2024-10-14 20:03:02 +0000
commit112170c17981556868bd0aedbbb636d1acdc8588 (patch)
treee666a2fe3baeb87d006755f20666581e034b585f
parentd7c1632113c8c1fe15766e3728a831a146c1de21 (diff)
downloadsonarqube-112170c17981556868bd0aedbbb636d1acdc8588.tar.gz
sonarqube-112170c17981556868bd0aedbbb636d1acdc8588.zip
SONAR-23213 The Measures migration helper is available only on Enterprise and DataCenter editions
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AbstractMigrateLiveMeasuresToMeasures.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToPortfoliosTable.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToProjectBranchesTable.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnPortfoliosMeasuresMigrated.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnProjectBranchesMeasuresMigrated.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateMeasuresTable.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigrateBranchesLiveMeasuresToMeasures.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigratePortfoliosLiveMeasuresToMeasures.java4
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/MigrateMeasuresAction.java153
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/PrepareMigrationAction.java118
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/SystemWsModule.java18
-rw-r--r--server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-migrate_measures.json8
-rw-r--r--server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-prepare_migration.json3
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/MigrateMeasuresActionTest.java233
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/PrepareMigrationActionTest.java181
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/SystemWsModuleTest.java2
16 files changed, 17 insertions, 717 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AbstractMigrateLiveMeasuresToMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AbstractMigrateLiveMeasuresToMeasures.java
index 5135d7aa859..bb23c793172 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AbstractMigrateLiveMeasuresToMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AbstractMigrateLiveMeasuresToMeasures.java
@@ -88,7 +88,7 @@ public abstract class AbstractMigrateLiveMeasuresToMeasures extends DataChange {
}
// This is a special entry point for the case of a configurable migration
- public final void migrate(List<String> uuids) throws SQLException {
+ public void migrate(List<String> uuids) throws SQLException {
try (Connection readConnection = createDdlConnection();
Connection writeConnection = createDdlConnection()) {
Context context = new Context(db, readConnection, writeConnection);
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToPortfoliosTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToPortfoliosTable.java
index 6d45843234f..b626863fc72 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToPortfoliosTable.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToPortfoliosTable.java
@@ -19,8 +19,10 @@
*/
package org.sonar.server.platform.db.migration.adhoc;
+import org.sonar.api.server.ServerSide;
import org.sonar.db.Database;
+@ServerSide
public class AddMeasuresMigratedColumnToPortfoliosTable extends AbstractAddMeasuresMigratedColumnToTable {
static final String PORTFOLIOS_TABLE_NAME = "portfolios";
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToProjectBranchesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToProjectBranchesTable.java
index 6f1475dcea8..53608f41689 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToProjectBranchesTable.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToProjectBranchesTable.java
@@ -19,8 +19,10 @@
*/
package org.sonar.server.platform.db.migration.adhoc;
+import org.sonar.api.server.ServerSide;
import org.sonar.db.Database;
+@ServerSide
public class AddMeasuresMigratedColumnToProjectBranchesTable extends AbstractAddMeasuresMigratedColumnToTable {
public static final String PROJECT_BRANCHES_TABLE_NAME = "project_branches";
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnPortfoliosMeasuresMigrated.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnPortfoliosMeasuresMigrated.java
index 414d305dbb2..e8305ce3b7a 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnPortfoliosMeasuresMigrated.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnPortfoliosMeasuresMigrated.java
@@ -19,8 +19,10 @@
*/
package org.sonar.server.platform.db.migration.adhoc;
+import org.sonar.api.server.ServerSide;
import org.sonar.db.Database;
+@ServerSide
public class CreateIndexOnPortfoliosMeasuresMigrated extends AbstractCreateIndexOnMeasuresMigrated {
static final String TABLE_NAME = "portfolios";
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnProjectBranchesMeasuresMigrated.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnProjectBranchesMeasuresMigrated.java
index 2a8e0510ee1..b19b1ec82a1 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnProjectBranchesMeasuresMigrated.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnProjectBranchesMeasuresMigrated.java
@@ -19,8 +19,10 @@
*/
package org.sonar.server.platform.db.migration.adhoc;
+import org.sonar.api.server.ServerSide;
import org.sonar.db.Database;
+@ServerSide
public class CreateIndexOnProjectBranchesMeasuresMigrated extends AbstractCreateIndexOnMeasuresMigrated {
static final String TABLE_NAME = "project_branches";
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateMeasuresTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateMeasuresTable.java
index d6a0275812b..bf5e4f19017 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateMeasuresTable.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateMeasuresTable.java
@@ -20,6 +20,7 @@
package org.sonar.server.platform.db.migration.adhoc;
import java.sql.SQLException;
+import org.sonar.api.server.ServerSide;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
import org.sonar.server.platform.db.migration.step.CreateTableChange;
@@ -30,6 +31,7 @@ import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobCo
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+@ServerSide
public class CreateMeasuresTable extends CreateTableChange {
static final String MEASURES_TABLE_NAME = "measures";
static final String COLUMN_COMPONENT_UUID = "component_uuid";
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigrateBranchesLiveMeasuresToMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigrateBranchesLiveMeasuresToMeasures.java
index 3138470dcb2..00bd163e54e 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigrateBranchesLiveMeasuresToMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigrateBranchesLiveMeasuresToMeasures.java
@@ -19,9 +19,11 @@
*/
package org.sonar.server.platform.db.migration.adhoc;
+import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.System2;
import org.sonar.db.Database;
+@ServerSide
public class MigrateBranchesLiveMeasuresToMeasures extends AbstractMigrateLiveMeasuresToMeasures {
public MigrateBranchesLiveMeasuresToMeasures(Database db, System2 system2) {
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigratePortfoliosLiveMeasuresToMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigratePortfoliosLiveMeasuresToMeasures.java
index 7ce171755f2..e61dba2133e 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigratePortfoliosLiveMeasuresToMeasures.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigratePortfoliosLiveMeasuresToMeasures.java
@@ -19,12 +19,14 @@
*/
package org.sonar.server.platform.db.migration.adhoc;
+import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.System2;
import org.sonar.db.Database;
+@ServerSide
public class MigratePortfoliosLiveMeasuresToMeasures extends AbstractMigrateLiveMeasuresToMeasures {
- protected MigratePortfoliosLiveMeasuresToMeasures(Database db, System2 system2) {
+ public MigratePortfoliosLiveMeasuresToMeasures(Database db, System2 system2) {
super(db, system2, "portfolios", "portfolio");
}
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/MigrateMeasuresAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/MigrateMeasuresAction.java
deleted file mode 100644
index fd7d6b35357..00000000000
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/MigrateMeasuresAction.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 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.platform.ws;
-
-import com.google.common.io.Resources;
-import java.sql.SQLException;
-import java.util.List;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.server.platform.db.migration.adhoc.MigrateBranchesLiveMeasuresToMeasures;
-import org.sonar.server.platform.db.migration.adhoc.MigratePortfoliosLiveMeasuresToMeasures;
-import org.sonar.server.user.UserSession;
-
-import static java.lang.String.format;
-import static java.util.Optional.ofNullable;
-
-public class MigrateMeasuresAction implements SystemWsAction {
- public static final String SYSTEM_MEASURES_MIGRATION_ENABLED = "system.measures.migration.enabled";
- public static final String PARAM_SIZE = "size";
-
- private final UserSession userSession;
- private final DbClient dbClient;
- private final MigrateBranchesLiveMeasuresToMeasures branchesMigration;
- private final MigratePortfoliosLiveMeasuresToMeasures portfoliosMigration;
-
- public MigrateMeasuresAction(UserSession userSession, DbClient dbClient,
- MigrateBranchesLiveMeasuresToMeasures branchesMigration, MigratePortfoliosLiveMeasuresToMeasures portfoliosMigration) {
- this.userSession = userSession;
- this.dbClient = dbClient;
- this.branchesMigration = branchesMigration;
- this.portfoliosMigration = portfoliosMigration;
- }
-
- @Override
- public void define(WebService.NewController controller) {
- WebService.NewAction action = controller.createAction("migrate_measures")
- .setDescription("Prepare the migration to the next major version of SonarQube." +
- "<br/>" +
- "Sending a POST request to this URL will migrate some rows from the 'live_measures' to the 'measures' table. " +
- "Requires system administration permission.")
- .setSince("9.9.8")
- .setPost(true)
- .setHandler(this)
- .setInternal(true)
- .setResponseExample(Resources.getResource(this.getClass(), "example-migrate_measures.json"));
-
- action.createParam(PARAM_SIZE)
- .setDescription("The number of branches or portfolios to migrate")
- .setDefaultValue(10);
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- userSession.checkIsSystemAdministrator();
-
- if (!isMigrationEnabled()) {
- throw new IllegalStateException("Migration is not enabled. Please call the endpoint /api/system/prepare_migration?enable=true and retry.");
- }
-
- int size = request.mandatoryParamAsInt(PARAM_SIZE);
- if (size <= 0) {
- throw new IllegalArgumentException("Size must be greater than 0");
- }
-
- int migratedItems = migrateBranches(size);
- if (migratedItems < size) {
- int remainingSize = size - migratedItems;
- migratedItems += migratePortfolios(remainingSize);
- }
-
- BranchStats statistics = getStatistics();
- try (JsonWriter json = response.newJsonWriter()) {
- json.beginObject()
- .prop("status", "success")
- .prop("message", format("%s branches or portfolios migrated", migratedItems))
- .prop("remainingBranches", statistics.remainingBranches)
- .prop("totalBranches", statistics.totalBranches)
- .prop("remainingPortfolios", statistics.remainingPortfolios)
- .prop("totalPortfolios", statistics.totalPortfolios)
- .endObject();
- }
- }
-
- private int migrateBranches(int size) throws SQLException {
- List<String> branchesToMigrate = getBranchesToMigrate(size);
- if (!branchesToMigrate.isEmpty()) {
- branchesMigration.migrate(branchesToMigrate);
- }
- return branchesToMigrate.size();
- }
-
- private List<String> getBranchesToMigrate(int size) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- return dbClient.branchDao().selectUuidsWithMeasuresMigratedFalse(dbSession, size);
- }
- }
-
- private int migratePortfolios(int size) throws SQLException {
- List<String> portfoliosToMigrate = getPortfoliosToMigrate(size);
- if (!portfoliosToMigrate.isEmpty()) {
- portfoliosMigration.migrate(portfoliosToMigrate);
- }
- return portfoliosToMigrate.size();
- }
-
- private List<String> getPortfoliosToMigrate(int size) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- return dbClient.portfolioDao().selectUuidsWithMeasuresMigratedFalse(dbSession, size);
- }
- }
-
- private boolean isMigrationEnabled() {
- return ofNullable(dbClient.propertiesDao().selectGlobalProperty(SYSTEM_MEASURES_MIGRATION_ENABLED))
- .map(p -> Boolean.parseBoolean(p.getValue()))
- .orElse(false);
- }
-
- private BranchStats getStatistics() {
- try (DbSession dbSession = dbClient.openSession(false)) {
- int remainingBranches = dbClient.branchDao().countByMeasuresMigratedFalse(dbSession);
- int totalBranches = dbClient.branchDao().countAll(dbSession);
- int remainingPortfolios = dbClient.portfolioDao().countByMeasuresMigratedFalse(dbSession);
- int totalPortfolios = dbClient.portfolioDao().selectAll(dbSession).size();
-
- return new BranchStats(remainingBranches, totalBranches, remainingPortfolios, totalPortfolios);
- }
- }
-
- private record BranchStats(int remainingBranches, int totalBranches, int remainingPortfolios, int totalPortfolios) {
- }
-
-}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/PrepareMigrationAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/PrepareMigrationAction.java
deleted file mode 100644
index bfb5ccda0a2..00000000000
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/PrepareMigrationAction.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 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.platform.ws;
-
-import com.google.common.io.Resources;
-import java.sql.SQLException;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.server.ws.WebService.NewAction;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.db.DbClient;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.server.platform.db.migration.adhoc.AddMeasuresMigratedColumnToPortfoliosTable;
-import org.sonar.server.platform.db.migration.adhoc.AddMeasuresMigratedColumnToProjectBranchesTable;
-import org.sonar.server.platform.db.migration.adhoc.CreateIndexOnPortfoliosMeasuresMigrated;
-import org.sonar.server.platform.db.migration.adhoc.CreateIndexOnProjectBranchesMeasuresMigrated;
-import org.sonar.server.platform.db.migration.adhoc.CreateMeasuresTable;
-import org.sonar.server.user.UserSession;
-
-import static java.lang.String.format;
-import static org.sonar.core.config.CorePropertyDefinitions.SYSTEM_MEASURES_MIGRATION_ENABLED;
-
-/**
- * Implementation of the {@code prepare_migration} action for the System WebService.
- */
-public class PrepareMigrationAction implements SystemWsAction {
-
- public static final String PARAM_ENABLE = "enable";
- private final UserSession userSession;
- private final DbClient dbClient;
- private final CreateMeasuresTable createMeasuresTable;
- private final AddMeasuresMigratedColumnToProjectBranchesTable addMeasuresMigratedColumnToProjectBranchesTable;
- private final AddMeasuresMigratedColumnToPortfoliosTable addMeasuresMigratedColumnToPortfoliosTable;
- private final CreateIndexOnProjectBranchesMeasuresMigrated createIndexOnProjectBranchesMeasuresMigrated;
- private final CreateIndexOnPortfoliosMeasuresMigrated createIndexOnPortfoliosMeasuresMigrated;
-
- public PrepareMigrationAction(UserSession userSession, DbClient dbClient, CreateMeasuresTable createMeasuresTable,
- AddMeasuresMigratedColumnToProjectBranchesTable addMeasuresMigratedColumnToProjectBranchesTable,
- AddMeasuresMigratedColumnToPortfoliosTable addMeasuresMigratedColumnToPortfoliosTable,
- CreateIndexOnProjectBranchesMeasuresMigrated createIndexOnProjectBranchesMeasuresMigrated,
- CreateIndexOnPortfoliosMeasuresMigrated createIndexOnPortfoliosMeasuresMigrated) {
- this.userSession = userSession;
- this.dbClient = dbClient;
- this.createMeasuresTable = createMeasuresTable;
- this.addMeasuresMigratedColumnToProjectBranchesTable = addMeasuresMigratedColumnToProjectBranchesTable;
- this.addMeasuresMigratedColumnToPortfoliosTable = addMeasuresMigratedColumnToPortfoliosTable;
- this.createIndexOnProjectBranchesMeasuresMigrated = createIndexOnProjectBranchesMeasuresMigrated;
- this.createIndexOnPortfoliosMeasuresMigrated = createIndexOnPortfoliosMeasuresMigrated;
- }
-
- @Override
- public void define(WebService.NewController controller) {
- NewAction action = controller.createAction("prepare_migration")
- .setDescription("Prepare the migration to the next major version of SonarQube." +
- "<br/>" +
- "Sending a POST request to this URL enables the 'live_measures' table migration. " +
- "It is strongly advised to <strong>make a database backup</strong> before invoking this WS. " +
- "Requires system administration permission.")
- .setSince("9.9.8")
- .setPost(true)
- .setHandler(this)
- .setInternal(true)
- .setResponseExample(Resources.getResource(this.getClass(), "example-prepare_migration.json"));
-
- action.createParam(PARAM_ENABLE)
- .setDescription("Set to true to enable the migration mode. Set to false to disable.")
- .setBooleanPossibleValues()
- .setRequired(true);
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- userSession.checkIsSystemAdministrator();
-
- boolean enable = request.mandatoryParamAsBoolean(PARAM_ENABLE);
- if (enable) {
- updateDdl();
- }
- updateProperty(enable);
-
- try (JsonWriter json = response.newJsonWriter()) {
- json.beginObject()
- .prop("message", format("The 'live_measures' migration mode is %s", enable ? "enabled" : "disabled"))
- .endObject();
- }
- }
-
- private void updateDdl() throws SQLException {
- createMeasuresTable.execute();
- addMeasuresMigratedColumnToProjectBranchesTable.execute();
- addMeasuresMigratedColumnToPortfoliosTable.execute();
- createIndexOnProjectBranchesMeasuresMigrated.execute();
- createIndexOnPortfoliosMeasuresMigrated.execute();
- }
-
- private void updateProperty(boolean enable) {
- dbClient.propertiesDao().saveProperty(new PropertyDto().setKey(SYSTEM_MEASURES_MIGRATION_ENABLED).setValue(Boolean.toString(enable)));
- }
-
-}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/SystemWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/SystemWsModule.java
index 41c21b03174..e18d8946b6b 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/SystemWsModule.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/SystemWsModule.java
@@ -20,13 +20,6 @@
package org.sonar.server.platform.ws;
import org.sonar.core.platform.Module;
-import org.sonar.server.platform.db.migration.adhoc.AddMeasuresMigratedColumnToPortfoliosTable;
-import org.sonar.server.platform.db.migration.adhoc.AddMeasuresMigratedColumnToProjectBranchesTable;
-import org.sonar.server.platform.db.migration.adhoc.CreateIndexOnPortfoliosMeasuresMigrated;
-import org.sonar.server.platform.db.migration.adhoc.CreateIndexOnProjectBranchesMeasuresMigrated;
-import org.sonar.server.platform.db.migration.adhoc.CreateMeasuresTable;
-import org.sonar.server.platform.db.migration.adhoc.MigrateBranchesLiveMeasuresToMeasures;
-import org.sonar.server.platform.db.migration.adhoc.MigratePortfoliosLiveMeasuresToMeasures;
public class SystemWsModule extends Module {
@@ -42,17 +35,6 @@ public class SystemWsModule extends Module {
LivenessActionSupport.class,
LivenessAction.class,
- CreateMeasuresTable.class,
- AddMeasuresMigratedColumnToProjectBranchesTable.class,
- AddMeasuresMigratedColumnToPortfoliosTable.class,
- CreateIndexOnProjectBranchesMeasuresMigrated.class,
- CreateIndexOnPortfoliosMeasuresMigrated.class,
- PrepareMigrationAction.class,
-
- MigrateBranchesLiveMeasuresToMeasures.class,
- MigratePortfoliosLiveMeasuresToMeasures.class,
- MigrateMeasuresAction.class,
-
InfoAction.class,
LogsAction.class,
MigrateDbAction.class,
diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-migrate_measures.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-migrate_measures.json
deleted file mode 100644
index 60fb3154d7a..00000000000
--- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-migrate_measures.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "status": "success",
- "message": "2 branches or portfolios migrated",
- "remainingBranches": 1,
- "totalBranches": 3,
- "remainingPortfolios": 1,
- "totalPortfolios": 2
-}
diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-prepare_migration.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-prepare_migration.json
deleted file mode 100644
index 902e4c6e249..00000000000
--- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-prepare_migration.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "message": "The 'live_measures' migration mode is enabled"
-}
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/MigrateMeasuresActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/MigrateMeasuresActionTest.java
deleted file mode 100644
index a4b92076fca..00000000000
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/MigrateMeasuresActionTest.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 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.platform.ws;
-
-import com.google.gson.Gson;
-import com.tngtech.java.junit.dataprovider.DataProvider;
-import com.tngtech.java.junit.dataprovider.DataProviderRunner;
-import java.sql.SQLException;
-import java.util.List;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.sonar.db.Database;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.BranchType;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.portfolio.PortfolioDto;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.platform.db.migration.adhoc.AddMeasuresMigratedColumnToPortfoliosTable;
-import org.sonar.server.platform.db.migration.adhoc.AddMeasuresMigratedColumnToProjectBranchesTable;
-import org.sonar.server.platform.db.migration.adhoc.MigrateBranchesLiveMeasuresToMeasures;
-import org.sonar.server.platform.db.migration.adhoc.MigratePortfoliosLiveMeasuresToMeasures;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.TestRequest;
-import org.sonar.server.ws.TestResponse;
-import org.sonar.server.ws.WsActionTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.sonar.db.component.BranchType.BRANCH;
-import static org.sonar.server.platform.ws.MigrateMeasuresAction.SYSTEM_MEASURES_MIGRATION_ENABLED;
-import static org.sonar.test.JsonAssert.assertJson;
-
-@RunWith(DataProviderRunner.class)
-public class MigrateMeasuresActionTest {
- private static final Gson GSON = new Gson();
-
- public static final String PARAM_SIZE = "size";
- @Rule
- public UserSessionRule userSessionRule = UserSessionRule.standalone().logIn().setSystemAdministrator();
-
- @Rule
- public DbTester dbTester = DbTester.create();
-
- private final MigrateBranchesLiveMeasuresToMeasures measuresMigration = mock();
- private final MigratePortfoliosLiveMeasuresToMeasures portfoliosMigration = mock();
- private final MigrateMeasuresAction underTest = new MigrateMeasuresAction(userSessionRule, dbTester.getDbClient(), measuresMigration, portfoliosMigration);
- private final WsActionTester tester = new WsActionTester(underTest);
-
- @Test
- public void should_throw_if_migration_is_not_enabled() {
- TestRequest request = tester.newRequest();
-
- assertThatIllegalStateException()
- .isThrownBy(request::execute)
- .withMessage("Migration is not enabled. Please call the endpoint /api/system/prepare_migration?enable=true and retry.");
- }
-
- @Test
- @DataProvider(value = {"0", "-1", "-100"})
- public void should_throws_IAE_if_size_in_invalid(int size) throws SQLException {
- enableMigration();
-
- TestRequest request = tester
- .newRequest()
- .setParam(PARAM_SIZE, Integer.toString(size));
-
- assertThatIllegalArgumentException()
- .isThrownBy(request::execute)
- .withMessage("Size must be greater than 0");
- }
-
- @Test
- public void verify_example() throws SQLException {
- enableMigration();
- // 3 branches, 2 migrated
- ComponentDto project = dbTester.components().insertPrivateProject();
- ComponentDto branch1 = dbTester.components().insertProjectBranch(project, b -> b.setBranchType(BRANCH));
- dbTester.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
- dbTester.getDbClient().branchDao().updateMeasuresMigrated(dbTester.getSession(), project.branchUuid(), true);
- dbTester.getDbClient().branchDao().updateMeasuresMigrated(dbTester.getSession(), branch1.branchUuid(), true);
- // 2 portfolios, 1 migrated
- PortfolioDto portfolio1 = dbTester.components().insertPrivatePortfolioDto("name1");
- dbTester.components().insertPrivatePortfolioDto("name2");
- dbTester.getDbClient().portfolioDao().updateMeasuresMigrated(dbTester.getSession(), portfolio1.getUuid(), true);
- dbTester.getSession().commit();
-
- TestResponse response = tester.newRequest()
- .execute();
-
- assertJson(response.getInput()).isSimilarTo(getClass().getResource("example-migrate_measures.json"));
- }
-
- @Test
- public void does_not_migrate_portfolios_if_measures_are_not_finished() throws SQLException {
- enableMigration();
- // 2 branches
- ComponentDto project = dbTester.components().insertPrivateProject();
- ComponentDto branch = dbTester.components().insertProjectBranch(project, b -> b.setBranchType(BRANCH));
- dbTester.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
-
- TestResponse response = tester.newRequest()
- .setParam(PARAM_SIZE, "2")
- .execute();
-
- assertThat(GSON.fromJson(response.getInput(), ActionResponse.class))
- .isEqualTo(new ActionResponse("success", "2 branches or portfolios migrated", 3, 3, 0, 0));
- verify(measuresMigration).migrate(List.of(project.uuid(), branch.uuid()));
- verifyNoInteractions(portfoliosMigration);
- }
-
- @Test
- public void migrate_portfolios_to_reach_the_requested_size() throws SQLException {
- enableMigration();
-
- // 1 branch
- ComponentDto project = dbTester.components().insertPrivateProject();
- // 2 portfolios
- PortfolioDto portfolio1 = dbTester.components().insertPrivatePortfolioDto("name1");
- dbTester.components().insertPrivatePortfolioDto("name2");
-
- TestResponse response = tester.newRequest()
- .setParam(PARAM_SIZE, "2")
- .execute();
-
- assertThat(GSON.fromJson(response.getInput(), ActionResponse.class))
- .isEqualTo(new ActionResponse("success", "2 branches or portfolios migrated", 1, 1, 2, 2));
- verify(measuresMigration).migrate(List.of(project.uuid()));
- verify(portfoliosMigration).migrate(List.of(portfolio1.getUuid()));
- }
-
- @Test
- public void migrate_portfolios_only_if_measures_are_done() throws SQLException {
- enableMigration();
- // 2 branches, all migrated
- ComponentDto project = dbTester.components().insertPrivateProject();
- ComponentDto branch1 = dbTester.components().insertProjectBranch(project, b -> b.setBranchType(BRANCH));
- dbTester.getDbClient().branchDao().updateMeasuresMigrated(dbTester.getSession(), project.branchUuid(), true);
- dbTester.getDbClient().branchDao().updateMeasuresMigrated(dbTester.getSession(), branch1.branchUuid(), true);
- // 2 portfolios, 1 migrated
- PortfolioDto portfolio1 = dbTester.components().insertPrivatePortfolioDto("name1");
- PortfolioDto portfolio2 = dbTester.components().insertPrivatePortfolioDto("name2");
- dbTester.getDbClient().portfolioDao().updateMeasuresMigrated(dbTester.getSession(), portfolio1.getUuid(), true);
- dbTester.commit();
-
- TestResponse response = tester.newRequest()
- .setParam(PARAM_SIZE, "2")
- .execute();
-
- assertThat(GSON.fromJson(response.getInput(), ActionResponse.class))
- .isEqualTo(new ActionResponse("success", "1 branches or portfolios migrated", 0, 2, 1, 2));
- verifyNoInteractions(measuresMigration);
- verify(portfoliosMigration).migrate(List.of(portfolio2.getUuid()));
- }
-
- @Test
- public void does_nothing_if_migration_is_finished() throws SQLException {
- enableMigration();
- // 2 branches, all migrated
- ComponentDto project = dbTester.components().insertPrivateProject();
- ComponentDto branch1 = dbTester.components().insertProjectBranch(project, b -> b.setBranchType(BRANCH));
- dbTester.getDbClient().branchDao().updateMeasuresMigrated(dbTester.getSession(), project.branchUuid(), true);
- dbTester.getDbClient().branchDao().updateMeasuresMigrated(dbTester.getSession(), branch1.branchUuid(), true);
- // 2 portfolios, all migrated
- PortfolioDto portfolio1 = dbTester.components().insertPrivatePortfolioDto("name1");
- PortfolioDto portfolio2 = dbTester.components().insertPrivatePortfolioDto("name2");
- dbTester.getDbClient().portfolioDao().updateMeasuresMigrated(dbTester.getSession(), portfolio1.getUuid(), true);
- dbTester.getDbClient().portfolioDao().updateMeasuresMigrated(dbTester.getSession(), portfolio2.getUuid(), true);
- dbTester.commit();
-
- TestResponse response = tester.newRequest()
- .setParam(PARAM_SIZE, "2")
- .execute();
-
- assertThat(GSON.fromJson(response.getInput(), ActionResponse.class))
- .isEqualTo(new ActionResponse("success", "0 branches or portfolios migrated", 0, 2, 0, 2));
- verifyNoInteractions(measuresMigration, portfoliosMigration);
- }
-
- private void enableMigration() throws SQLException {
- Database database = dbTester.getDbClient().getDatabase();
- new AddMeasuresMigratedColumnToProjectBranchesTable(database).execute();
- new AddMeasuresMigratedColumnToPortfoliosTable(database).execute();
- dbTester.getDbClient().propertiesDao().saveProperty(new PropertyDto().setKey(SYSTEM_MEASURES_MIGRATION_ENABLED).setValue("true"));
- }
-
- @Test
- public void throws_ForbiddenException_if_user_is_not_logged_in() {
- userSessionRule.anonymous();
-
- TestRequest request = tester.newRequest();
-
- assertThatExceptionOfType(ForbiddenException.class)
- .isThrownBy(request::execute);
- }
-
- @Test
- public void throws_ForbiddenException_if_user_is_not_system_admin() {
- userSessionRule.logIn();
-
- TestRequest request = tester.newRequest();
-
- assertThatExceptionOfType(ForbiddenException.class)
- .isThrownBy(request::execute);
- }
-
- private record ActionResponse(String status, String message, int remainingBranches, int totalBranches, int remainingPortfolios,
- int totalPortfolios) {
- }
-}
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/PrepareMigrationActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/PrepareMigrationActionTest.java
deleted file mode 100644
index 11bc6c69226..00000000000
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/PrepareMigrationActionTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2024 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.platform.ws;
-
-import com.tngtech.java.junit.dataprovider.DataProvider;
-import com.tngtech.java.junit.dataprovider.DataProviderRunner;
-import java.sql.SQLException;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.sonar.db.DbTester;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.platform.db.migration.adhoc.AddMeasuresMigratedColumnToPortfoliosTable;
-import org.sonar.server.platform.db.migration.adhoc.AddMeasuresMigratedColumnToProjectBranchesTable;
-import org.sonar.server.platform.db.migration.adhoc.CreateIndexOnPortfoliosMeasuresMigrated;
-import org.sonar.server.platform.db.migration.adhoc.CreateIndexOnProjectBranchesMeasuresMigrated;
-import org.sonar.server.platform.db.migration.adhoc.CreateMeasuresTable;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.TestRequest;
-import org.sonar.server.ws.TestResponse;
-import org.sonar.server.ws.WsActionTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.sonar.core.config.CorePropertyDefinitions.SYSTEM_MEASURES_MIGRATION_ENABLED;
-import static org.sonar.test.JsonAssert.assertJson;
-
-@RunWith(DataProviderRunner.class)
-public class PrepareMigrationActionTest {
-
- public static final String PARAM_ENABLE = "enable";
- @Rule
- public UserSessionRule userSessionRule = UserSessionRule.standalone().logIn().setSystemAdministrator();
-
- @Rule
- public DbTester dbTester = DbTester.create();
-
- private final CreateMeasuresTable createMeasuresTable = mock();
- private final AddMeasuresMigratedColumnToProjectBranchesTable addMeasuresMigratedColumnToProjectBranchesTable = mock();
- private final AddMeasuresMigratedColumnToPortfoliosTable addMeasuresMigratedColumnToPortfoliosTable = mock();
- private final CreateIndexOnProjectBranchesMeasuresMigrated createIndexOnProjectBranchesMeasuresMigrated = mock();
- private final CreateIndexOnPortfoliosMeasuresMigrated createIndexOnPortfoliosMeasuresMigrated = mock();
-
- private final PrepareMigrationAction underTest = new PrepareMigrationAction(userSessionRule, dbTester.getDbClient(), createMeasuresTable,
- addMeasuresMigratedColumnToProjectBranchesTable, addMeasuresMigratedColumnToPortfoliosTable, createIndexOnProjectBranchesMeasuresMigrated, createIndexOnPortfoliosMeasuresMigrated);
- private final WsActionTester tester = new WsActionTester(underTest);
-
- @Test
- public void should_throw_if_enable_parameter_is_missing() {
- TestRequest request = tester.newRequest();
-
- assertThatIllegalArgumentException()
- .isThrownBy(request::execute)
- .withMessage("The 'enable' parameter is missing");
- }
-
- @Test
- public void verify_example() {
- TestResponse response = tester.newRequest()
- .setParam(PARAM_ENABLE, "true")
- .execute();
-
- assertJson(response.getInput()).isSimilarTo(getClass().getResource("example-prepare_migration.json"));
- }
-
- @Test
- public void throws_ForbiddenException_if_user_is_not_logged_in() {
- userSessionRule.anonymous();
-
- TestRequest request = tester.newRequest();
-
- assertThatExceptionOfType(ForbiddenException.class)
- .isThrownBy(request::execute);
- }
-
- @Test
- public void throws_ForbiddenException_if_user_is_not_system_admin() {
- userSessionRule.logIn();
-
- TestRequest request = tester.newRequest();
-
- assertThatExceptionOfType(ForbiddenException.class)
- .isThrownBy(request::execute);
- }
-
- @Test
- @DataProvider(value = {"true", "yes"})
- public void should_enable_migration(String enableParamValue) throws SQLException {
- assertThat(getPropertyValue()).isNull();
-
- TestResponse response = tester.newRequest()
- .setParam(PARAM_ENABLE, enableParamValue)
- .execute();
-
- assertThat(response.getStatus()).isEqualTo(200);
- assertThat(getPropertyValue()).isTrue();
-
- verify(createMeasuresTable).execute();
- verify(addMeasuresMigratedColumnToProjectBranchesTable).execute();
- verify(addMeasuresMigratedColumnToPortfoliosTable).execute();
- verify(createIndexOnProjectBranchesMeasuresMigrated).execute();
- verify(createIndexOnPortfoliosMeasuresMigrated).execute();
-
- // reentrant
- response = tester.newRequest()
- .setParam(PARAM_ENABLE, enableParamValue)
- .execute();
-
- assertThat(response.getStatus()).isEqualTo(200);
- assertThat(getPropertyValue()).isTrue();
- }
-
- @Test
- public void property_is_unchanged_if_the_migrations_failed() throws SQLException {
- doThrow(new SQLException("Oops")).when(createMeasuresTable).execute();
-
- TestRequest request = tester.newRequest()
- .setParam(PARAM_ENABLE, "true");
-
- assertThatExceptionOfType(RuntimeException.class)
- .isThrownBy(request::execute);
-
- assertThat(getPropertyValue()).isNull();
- }
-
- @Test
- @DataProvider(value = {"false", "no"})
- public void should_disable_migration(String disableParamValue) {
- dbTester.getDbClient().propertiesDao().saveProperty(new PropertyDto().setKey(SYSTEM_MEASURES_MIGRATION_ENABLED).setValue("true"));
-
- TestResponse response = tester.newRequest()
- .setParam(PARAM_ENABLE, disableParamValue)
- .execute();
-
- assertThat(response.getStatus()).isEqualTo(200);
- assertThat(getPropertyValue()).isFalse();
-
- verifyNoInteractions(createMeasuresTable, addMeasuresMigratedColumnToPortfoliosTable, addMeasuresMigratedColumnToProjectBranchesTable,
- createIndexOnProjectBranchesMeasuresMigrated, createIndexOnPortfoliosMeasuresMigrated);
-
- // reentrant
- response = tester.newRequest()
- .setParam(PARAM_ENABLE, disableParamValue)
- .execute();
-
- assertThat(response.getStatus()).isEqualTo(200);
- assertThat(getPropertyValue()).isFalse();
- }
-
- private Boolean getPropertyValue() {
- PropertyDto propertyDto = dbTester.getDbClient().propertiesDao().selectGlobalProperty(SYSTEM_MEASURES_MIGRATION_ENABLED);
- if (propertyDto == null) {
- return null;
- }
- return Boolean.parseBoolean(propertyDto.getValue());
- }
-
-}
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/SystemWsModuleTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/SystemWsModuleTest.java
index 8c7a40815c2..0a75383e46d 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/SystemWsModuleTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/SystemWsModuleTest.java
@@ -29,6 +29,6 @@ public class SystemWsModuleTest {
public void verify_count_of_added_components() {
ListContainer container = new ListContainer();
new SystemWsModule().configure(container);
- assertThat(container.getAddedObjects()).hasSize(24);
+ assertThat(container.getAddedObjects()).hasSize(15);
}
}