]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-23213 The Measures migration helper is available only on Enterprise and DataCen...
authorClaire Villard <claire.villard@sonarsource.com>
Thu, 3 Oct 2024 09:59:29 +0000 (11:59 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 14 Oct 2024 20:03:02 +0000 (20:03 +0000)
16 files changed:
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AbstractMigrateLiveMeasuresToMeasures.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToPortfoliosTable.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/AddMeasuresMigratedColumnToProjectBranchesTable.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnPortfoliosMeasuresMigrated.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateIndexOnProjectBranchesMeasuresMigrated.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/CreateMeasuresTable.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigrateBranchesLiveMeasuresToMeasures.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/adhoc/MigratePortfoliosLiveMeasuresToMeasures.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/MigrateMeasuresAction.java [deleted file]
server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/PrepareMigrationAction.java [deleted file]
server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/SystemWsModule.java
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-migrate_measures.json [deleted file]
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-prepare_migration.json [deleted file]
server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/MigrateMeasuresActionTest.java [deleted file]
server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/PrepareMigrationActionTest.java [deleted file]
server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/SystemWsModuleTest.java

index 5135d7aa85937cf848039adf39bafe6a9f28778a..bb23c7931726a21f1e7396769afd92640abfac77 100644 (file)
@@ -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);
index 6d45843234fefacc251a210357820775304b25b4..b626863fc72c34036a9f94020ff0adad5a4e6917 100644 (file)
  */
 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";
index 6f1475dcea8e2be2e378ffecb6e64f8509345ec5..53608f4168913effa723fa917cdf2c740911196f 100644 (file)
  */
 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";
index 414d305dbb27ca18cef1d3512f186056372b07f1..e8305ce3b7a4dd1b4586894a476277cc4166515c 100644 (file)
  */
 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";
index 2a8e0510ee1eb93c7302d6436c010597efb762dd..b19b1ec82a1e418cc6472808254a5e8cbe846212 100644 (file)
  */
 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";
index d6a0275812b7d3d137c418b7b952eeec4b6bbebf..bf5e4f190177ae88adda6ca9b6d5a18dc43f8951 100644 (file)
@@ -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";
index 3138470dcb24774af103fa7653400fecf96e959b..00bd163e54e4964690d5a931b74e679116488c12 100644 (file)
  */
 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) {
index 7ce171755f258278d16ca7276bec7c2dcda86ac7..e61dba2133e2da4b2419e02ee0b862017d1e2ef7 100644 (file)
  */
 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 (file)
index fd7d6b3..0000000
+++ /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 (file)
index bfb5ccd..0000000
+++ /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)));
-  }
-
-}
index 41c21b03174d81e55953d046407822da533b9067..e18d8946b6bb0e0b1b8c654623e102e6ff9c8d7c 100644 (file)
 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 (file)
index 60fb315..0000000
+++ /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 (file)
index 902e4c6..0000000
+++ /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 (file)
index a4b9207..0000000
+++ /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 (file)
index 11bc6c6..0000000
+++ /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());
-  }
-
-}
index 8c7a40815c2ea109a9bc819a4b60ff5909b8f047..0a75383e46ddc7d8ce9929a6607caa91265406b2 100644 (file)
@@ -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);
   }
 }