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;
});
}
- analysisMetadataHolder.getScmRevisionId().ifPresent(scmRevisionId -> analysisPropertyDtos.add(new AnalysisPropertyDto()
- .setUuid(uuidFactory.create())
- .setKey(SCM_REVISION_ID)
- .setValue(scmRevisionId)
- .setSnapshotUuid(analysisMetadataHolder.getUuid())));
-
if (analysisPropertyDtos.isEmpty()) {
return;
}
underTest.execute(new TestComputationStepContext());
- assertThat(dbTester.countRowsOfTable("analysis_properties")).isEqualTo(9);
- List<AnalysisPropertyDto> 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<AnalysisPropertyDto> propertyDtos = dbTester.getDbClient()
.analysisPropertiesDao().selectBySnapshotUuid(dbTester.getSession(), SNAPSHOT_UUID);
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<AnalysisPropertyDto> 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
.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);
}
}
--- /dev/null
+/*
+ * 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;
+ });
+ }
+}
@Test
public void verify_migration_count() {
- verifyMigrationCount(underTest, 7);
+ verifyMigrationCount(underTest, 8);
}
}
--- /dev/null
+/*
+ * 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<Long, String> 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<Long, String> 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());
+ }
+}
--- /dev/null
+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");
+