From 2410133d009b32f7e61beab9dae6d15a7aabf0f7 Mon Sep 17 00:00:00 2001 From: Michal Duda Date: Thu, 9 May 2019 16:23:52 +0200 Subject: [PATCH] SONAR-11950 copy revisions migration --- .../step/PersistAnalysisPropertiesStep.java | 7 -- .../PersistAnalysisPropertiesStepTest.java | 38 +------- .../db/migration/version/v78/DbVersion78.java | 1 + .../version/v78/MigrateRevision.java | 50 ++++++++++ .../version/v78/DbVersion78Test.java | 2 +- .../version/v78/MigrateRevisionTest.java | 94 +++++++++++++++++++ .../v78/MigrateRevisionTest/snapshots.sql | 45 +++++++++ 7 files changed, 194 insertions(+), 43 deletions(-) create mode 100644 server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v78/MigrateRevision.java create mode 100644 server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v78/MigrateRevisionTest.java create mode 100644 server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v78/MigrateRevisionTest/snapshots.sql diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisPropertiesStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisPropertiesStep.java index 2557964e411..57b39a71fd3 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisPropertiesStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisPropertiesStep.java @@ -40,7 +40,6 @@ import static org.sonar.core.config.CorePropertyDefinitions.SONAR_ANALYSIS; public class PersistAnalysisPropertiesStep implements ComputationStep { private static final String SONAR_PULL_REQUEST = "sonar.pullrequest."; - private static final String SCM_REVISION_ID = "sonar.analysis.scm_revision_id"; private final DbClient dbClient; private final AnalysisMetadataHolder analysisMetadataHolder; @@ -72,12 +71,6 @@ public class PersistAnalysisPropertiesStep implements ComputationStep { }); } - analysisMetadataHolder.getScmRevisionId().ifPresent(scmRevisionId -> analysisPropertyDtos.add(new AnalysisPropertyDto() - .setUuid(uuidFactory.create()) - .setKey(SCM_REVISION_ID) - .setValue(scmRevisionId) - .setSnapshotUuid(analysisMetadataHolder.getUuid()))); - if (analysisPropertyDtos.isEmpty()) { return; } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisPropertiesStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisPropertiesStepTest.java index d4d4222a878..956fbc1d4e4 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisPropertiesStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisPropertiesStepTest.java @@ -79,32 +79,6 @@ public class PersistAnalysisPropertiesStepTest { underTest.execute(new TestComputationStepContext()); - assertThat(dbTester.countRowsOfTable("analysis_properties")).isEqualTo(9); - List propertyDtos = dbTester.getDbClient() - .analysisPropertiesDao().selectBySnapshotUuid(dbTester.getSession(), SNAPSHOT_UUID); - - assertThat(propertyDtos) - .extracting(AnalysisPropertyDto::getSnapshotUuid, AnalysisPropertyDto::getKey, AnalysisPropertyDto::getValue) - .containsExactlyInAnyOrder( - tuple(SNAPSHOT_UUID, "sonar.analysis.branch", SMALL_VALUE2), - tuple(SNAPSHOT_UUID, "sonar.analysis.empty_string", ""), - tuple(SNAPSHOT_UUID, "sonar.analysis.big_value", BIG_VALUE), - tuple(SNAPSHOT_UUID, "sonar.analysis.", SMALL_VALUE3), - tuple(SNAPSHOT_UUID, "sonar.analysis.scm_revision_id", SCM_REV_ID), - tuple(SNAPSHOT_UUID, "sonar.pullrequest.branch", VALUE_PREFIX_FOR_PR_PROPERTIES + SMALL_VALUE2), - tuple(SNAPSHOT_UUID, "sonar.pullrequest.empty_string", ""), - tuple(SNAPSHOT_UUID, "sonar.pullrequest.big_value", VALUE_PREFIX_FOR_PR_PROPERTIES + BIG_VALUE), - tuple(SNAPSHOT_UUID, "sonar.pullrequest.", VALUE_PREFIX_FOR_PR_PROPERTIES + SMALL_VALUE3)); - } - - @Test - public void persist_should_not_stores_sonarDotAnalysisDotscm_revision_id_properties_when_its_not_available_in_report_metada() { - when(batchReportReader.readContextProperties()).thenReturn(CloseableIterator.from(PROPERTIES.iterator())); - when(analysisMetadataHolder.getUuid()).thenReturn(SNAPSHOT_UUID); - when(analysisMetadataHolder.getScmRevisionId()).thenReturn(Optional.empty()); - - underTest.execute(new TestComputationStepContext()); - assertThat(dbTester.countRowsOfTable("analysis_properties")).isEqualTo(8); List propertyDtos = dbTester.getDbClient() .analysisPropertiesDao().selectBySnapshotUuid(dbTester.getSession(), SNAPSHOT_UUID); @@ -136,24 +110,18 @@ public class PersistAnalysisPropertiesStepTest { underTest.execute(new TestComputationStepContext()); - assertThat(dbTester.countRowsOfTable("analysis_properties")).isEqualTo(1); + assertThat(dbTester.countRowsOfTable("analysis_properties")).isEqualTo(0); } @Test - public void persist_should_only_store_scmRevisionId_if_there_is_no_context_properties() { + public void persist_should_store_nothing_if_there_are_no_context_properties() { when(analysisMetadataHolder.getScmRevisionId()).thenReturn(Optional.of(SCM_REV_ID)); when(batchReportReader.readContextProperties()).thenReturn(CloseableIterator.emptyCloseableIterator()); when(analysisMetadataHolder.getUuid()).thenReturn(SNAPSHOT_UUID); underTest.execute(new TestComputationStepContext()); - assertThat(dbTester.countRowsOfTable("analysis_properties")).isEqualTo(1); - List propertyDtos = dbTester.getDbClient() - .analysisPropertiesDao().selectBySnapshotUuid(dbTester.getSession(), SNAPSHOT_UUID); - - assertThat(propertyDtos) - .extracting(AnalysisPropertyDto::getSnapshotUuid, AnalysisPropertyDto::getKey, AnalysisPropertyDto::getValue) - .containsExactlyInAnyOrder(tuple(SNAPSHOT_UUID, "sonar.analysis.scm_revision_id", SCM_REV_ID)); + assertThat(dbTester.countRowsOfTable("analysis_properties")).isEqualTo(0); } @Test diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v78/DbVersion78.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v78/DbVersion78.java index 635a74ab53b..77651d22b04 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v78/DbVersion78.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v78/DbVersion78.java @@ -33,6 +33,7 @@ public class DbVersion78 implements DbVersion { .add(2703, "Add security fields to Elasticsearch indices", AddSecurityFieldsToElasticsearchIndices.class) .add(2704, "Add InternalComponentProperties table", CreateInternalComponentPropertiesTable.class) .add(2705, "Add column snapshots.revision", AddSnapshotRevision.class) + .add(2706, "Migrate revision from analysis_properties to snapshots.revision", MigrateRevision.class) .add(2707, "Update statuses of Security Hotspots", UpdateSecurityHotspotsStatuses.class); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v78/MigrateRevision.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v78/MigrateRevision.java new file mode 100644 index 00000000000..5959a6e4cca --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v78/MigrateRevision.java @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.db.migration.version.v78; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.SupportsBlueGreen; +import org.sonar.server.platform.db.migration.step.DataChange; +import org.sonar.server.platform.db.migration.step.MassUpdate; + +@SupportsBlueGreen +public class MigrateRevision extends DataChange { + public MigrateRevision(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select ap.snapshot_uuid, ap.text_value" + + " from analysis_properties ap" + + " where kee = 'sonar.analysis.scm_revision_id'"); + massUpdate.update("update snapshots set revision=? where uuid=?"); + massUpdate.rowPluralName("migrate revision from analysis_properties to snapshots"); + massUpdate.execute((row, update) -> { + String snapshotUuid = row.getString(1); + String revision = row.getString(2); + update.setString(1, revision); + update.setString(2, snapshotUuid); + return true; + }); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v78/DbVersion78Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v78/DbVersion78Test.java index b97a927666c..e0fc5f75175 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v78/DbVersion78Test.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v78/DbVersion78Test.java @@ -35,7 +35,7 @@ public class DbVersion78Test { @Test public void verify_migration_count() { - verifyMigrationCount(underTest, 7); + verifyMigrationCount(underTest, 8); } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v78/MigrateRevisionTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v78/MigrateRevisionTest.java new file mode 100644 index 00000000000..9cef01de6b9 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v78/MigrateRevisionTest.java @@ -0,0 +1,94 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.db.migration.version.v78; + +import java.sql.SQLException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.db.CoreDbTester; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MigrateRevisionTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(MigrateRevisionTest.class, "snapshots.sql"); + + private MigrateRevision underTest = new MigrateRevision(db.database()); + + @Test + public void copies_revision_from_analysis_properties_to_snapshots() throws SQLException { + insertSnapshot(1, "uuid1", "cuuid1"); + insertAnalysisProperty("uuid1", "sonar.analysis.scm_revision_id", "000b17c1db52814d41e4f1425292435b4261ef22"); + insertAnalysisProperty("uuid1", "sonar.pullrequest.base", "master"); + insertSnapshot(2, "uuid2", "cuuid2"); + insertSnapshot(3, "uuid3", "cuuid3"); + insertAnalysisProperty("uuid3", "sonar.analysis.scm_revision_id", "7e1071e0606e8c7c8181602f8263bc6f56509ac4"); + + underTest.execute(); + + Map result = db.select("select ID, REVISION from SNAPSHOTS") + .stream() + .collect(HashMap::new, (m, v) -> m.put((Long) v.get("ID"), (String) v.get("REVISION")), HashMap::putAll); + assertThat(result.get(1L)).isEqualTo("000b17c1db52814d41e4f1425292435b4261ef22"); + assertThat(result.get(2L)).isNull(); + assertThat(result.get(3L)).isEqualTo("7e1071e0606e8c7c8181602f8263bc6f56509ac4"); + } + + @Test + public void migration_is_reentrant() throws SQLException { + insertSnapshot(1, "uuid1", "cuuid1"); + insertAnalysisProperty("uuid1", "sonar.analysis.scm_revision_id", "7e1071e0606e8c7c8181602f8263bc6f56509ac4"); + + underTest.execute(); + underTest.execute(); + + Map result = db.select("select ID, REVISION from SNAPSHOTS") + .stream() + .collect(HashMap::new, (m, v) -> m.put((Long) v.get("ID"), (String) v.get("REVISION")), HashMap::putAll); + assertThat(result.get(1L)).isEqualTo("7e1071e0606e8c7c8181602f8263bc6f56509ac4"); + } + + private void insertSnapshot(long id, String uuid, String componentUuid) { + db.executeInsert( + "snapshots", + "id", id, + "uuid", uuid, + "component_uuid", componentUuid); + } + + private void insertAnalysisProperty(String snapshotUuid, String name, String value) { + db.executeInsert( + "analysis_properties", + "UUID", UUID.randomUUID(), + "SNAPSHOT_UUID", snapshotUuid, + "KEE", name, + "TEXT_VALUE", value, + "IS_EMPTY", false, + "CREATED_AT", new Date().getTime()); + } +} diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v78/MigrateRevisionTest/snapshots.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v78/MigrateRevisionTest/snapshots.sql new file mode 100644 index 00000000000..993aeb14007 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v78/MigrateRevisionTest/snapshots.sql @@ -0,0 +1,45 @@ +CREATE TABLE "SNAPSHOTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "UUID" VARCHAR(50) NOT NULL, + "CREATED_AT" BIGINT, + "BUILD_DATE" BIGINT, + "COMPONENT_UUID" VARCHAR(50) NOT NULL, + "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U', + "PURGE_STATUS" INTEGER, + "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE, + "VERSION" VARCHAR(500), + "BUILD_STRING" VARCHAR(100), + "PERIOD1_MODE" VARCHAR(100), + "PERIOD1_PARAM" VARCHAR(100), + "PERIOD1_DATE" BIGINT, + "PERIOD2_MODE" VARCHAR(100), + "PERIOD2_PARAM" VARCHAR(100), + "PERIOD2_DATE" BIGINT, + "PERIOD3_MODE" VARCHAR(100), + "PERIOD3_PARAM" VARCHAR(100), + "PERIOD3_DATE" BIGINT, + "PERIOD4_MODE" VARCHAR(100), + "PERIOD4_PARAM" VARCHAR(100), + "PERIOD4_DATE" BIGINT, + "PERIOD5_MODE" VARCHAR(100), + "PERIOD5_PARAM" VARCHAR(100), + "PERIOD5_DATE" BIGINT, + "REVISION" VARCHAR(100) +); +CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS" ("COMPONENT_UUID"); +CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS" ("UUID"); + + +CREATE TABLE "ANALYSIS_PROPERTIES" ( + "UUID" character varying(40) PRIMARY KEY, + "SNAPSHOT_UUID" character varying(40) NOT NULL, + "KEE" character varying(512) NOT NULL, + "TEXT_VALUE" character varying(4000), + "CLOB_VALUE" text, + "IS_EMPTY" boolean NOT NULL, + "CREATED_AT" bigint NOT NULL +); + +CREATE UNIQUE INDEX "PK_ANALYSIS_PROPERTIES" ON "ANALYSIS_PROPERTIES"("UUID"); +CREATE INDEX "IX_SNAPSHOT_UUID" ON "ANALYSIS_PROPERTIES"("SNAPSHOT_UUID"); + -- 2.39.5