aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Hartmann <hartmann.eric@gmail.com>2017-09-29 18:07:31 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-10-17 15:13:58 +0200
commitc1f4d7c77fcf0e9b8d385167a7f34a68ac6c6550 (patch)
tree0615811c23f9434bc33289e8ecbd05365a6f1e51
parent80645fca839ea97ee472f01ebb81f40af0f179f5 (diff)
downloadsonarqube-c1f4d7c77fcf0e9b8d385167a7f34a68ac6c6550.tar.gz
sonarqube-c1f4d7c77fcf0e9b8d385167a7f34a68ac6c6550.zip
SONAR-9882 Implements storage of sonar.analysis.* properties
-rw-r--r--server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java2
-rw-r--r--server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl19
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java2
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java7
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java4
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertiesDao.java78
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertiesMapper.java35
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertyDto.java114
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/component/ScrapAnalysisPropertyDto.java42
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java10
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java2
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/component/AnalysisPropertiesMapper.xml76
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml9
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java3
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/component/AnalysisPropertiesDaoTest.java182
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/component/AnalysisPropertyDtoTest.java169
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/component/ScrapAnalysisPropertyDtoTest.java58
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java12
-rw-r--r--server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldDeleteResource.xml9
-rw-r--r--server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis-result.xml16
-rw-r--r--server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis.xml18
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisProperties.java88
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67.java4
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisPropertiesTest.java53
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67Test.java2
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisPropertiesTest/empty.sql0
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistAnalysisPropertiesStep.java81
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistAnalysisPropertiesStepTest.java94
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistAnalysisStepTest.java7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistAnalysisStepTest.java4
31 files changed, 1182 insertions, 19 deletions
diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
index b080ec9da78..a4c1e7822fb 100644
--- a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
+++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
@@ -152,7 +152,7 @@ public class ComputeEngineContainerImplTest {
assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize(
COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION
+ 26 // level 1
- + 51 // content of DaoModule
+ + 52 // content of DaoModule
+ 3 // content of EsSearchModule
+ 66 // content of CorePropertyDefinitions
+ 1 // StopFlagContainer
diff --git a/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl b/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl
index 6afd58a258b..f3bedc4ba6b 100644
--- a/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl
+++ b/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl
@@ -197,7 +197,7 @@ CREATE UNIQUE INDEX "RULES_REPO_KEY" ON "RULES" ("PLUGIN_NAME", "PLUGIN_RULE_KEY
CREATE TABLE "RULES_METADATA" (
"RULE_ID" INTEGER NOT NULL,
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
- "NOTE_DATA" CLOB(2147483647),
+ "NOTE_DATA" CLOB,
"NOTE_USER_LOGIN" VARCHAR(255),
"NOTE_CREATED_AT" BIGINT,
"NOTE_UPDATED_AT" BIGINT,
@@ -255,7 +255,7 @@ CREATE TABLE "PROPERTIES" (
"USER_ID" INTEGER,
"IS_EMPTY" BOOLEAN NOT NULL,
"TEXT_VALUE" VARCHAR(4000),
- "CLOB_VALUE" CLOB(2147483647),
+ "CLOB_VALUE" CLOB,
"CREATED_AT" BIGINT
);
CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES" ("PROP_KEY");
@@ -579,7 +579,7 @@ CREATE TABLE "FILE_SOURCES" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"PROJECT_UUID" VARCHAR(50) NOT NULL,
"FILE_UUID" VARCHAR(50) NOT NULL,
- "LINE_HASHES" CLOB(2147483647),
+ "LINE_HASHES" CLOB,
"BINARY_DATA" BLOB,
"DATA_TYPE" VARCHAR(20),
"DATA_HASH" VARCHAR(50),
@@ -630,7 +630,7 @@ CREATE TABLE "CE_ACTIVITY" (
"UPDATED_AT" BIGINT NOT NULL,
"EXECUTION_TIME_MS" BIGINT NULL,
"ERROR_MESSAGE" VARCHAR(1000),
- "ERROR_STACKTRACE" CLOB(2147483647),
+ "ERROR_STACKTRACE" CLOB,
"ERROR_TYPE" VARCHAR(20)
);
@@ -727,3 +727,14 @@ CREATE TABLE "PROJECT_BRANCHES" (
);
CREATE UNIQUE INDEX "PK_PROJECT_BRANCHES" ON "PROJECT_BRANCHES" ("UUID");
CREATE UNIQUE INDEX "PROJECT_BRANCHES_KEE" ON "PROJECT_BRANCHES" ("PROJECT_UUID", "KEE");
+
+CREATE TABLE "ANALYSIS_PROPERTIES" (
+ "UUID" VARCHAR(40) NOT NULL PRIMARY KEY,
+ "SNAPSHOT_UUID" VARCHAR(40) NOT NULL,
+ "KEE" VARCHAR(512) NOT NULL,
+ "TEXT_VALUE" VARCHAR(4000),
+ "CLOB_VALUE" CLOB,
+ "IS_EMPTY" BOOLEAN NOT NULL,
+ "CREATED_AT" BIGINT NOT NULL
+);
+CREATE INDEX "SNAPSHOT_UUID" ON "ANALYSIS_PROPERTIES" ("SNAPSHOT_UUID");
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java
index f3b621fe326..e70920b964e 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java
@@ -28,6 +28,7 @@ import org.sonar.db.ce.CeQueueDao;
import org.sonar.db.ce.CeScannerContextDao;
import org.sonar.db.ce.CeTaskCharacteristicDao;
import org.sonar.db.ce.CeTaskInputDao;
+import org.sonar.db.component.AnalysisPropertiesDao;
import org.sonar.db.component.BranchDao;
import org.sonar.db.component.ComponentDao;
import org.sonar.db.component.ComponentKeyUpdaterDao;
@@ -81,6 +82,7 @@ public class DaoModule extends Module {
// for readability and easier merge, keep list ordered alphabetically
// =====================================================================
ActiveRuleDao.class,
+ AnalysisPropertiesDao.class,
AuthorizationDao.class,
BranchDao.class,
CeActivityDao.class,
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java
index ae81a02f4cf..5df791543f1 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java
@@ -26,6 +26,7 @@ import org.sonar.db.ce.CeQueueDao;
import org.sonar.db.ce.CeScannerContextDao;
import org.sonar.db.ce.CeTaskCharacteristicDao;
import org.sonar.db.ce.CeTaskInputDao;
+import org.sonar.db.component.AnalysisPropertiesDao;
import org.sonar.db.component.BranchDao;
import org.sonar.db.component.ComponentDao;
import org.sonar.db.component.ComponentKeyUpdaterDao;
@@ -128,6 +129,7 @@ public class DbClient {
private final EsQueueDao esQueueDao;
private final PluginDao pluginDao;
private final BranchDao branchDao;
+ private final AnalysisPropertiesDao analysisPropertiesDao;
private final QProfileEditUsersDao qProfileEditUsersDao;
private final QProfileEditGroupsDao qProfileEditGroupsDao;
@@ -189,6 +191,7 @@ public class DbClient {
esQueueDao = getDao(map, EsQueueDao.class);
pluginDao = getDao(map, PluginDao.class);
branchDao = getDao(map, BranchDao.class);
+ analysisPropertiesDao = getDao(map, AnalysisPropertiesDao.class);
qProfileEditUsersDao = getDao(map, QProfileEditUsersDao.class);
qProfileEditGroupsDao = getDao(map, QProfileEditGroupsDao.class);
}
@@ -245,6 +248,10 @@ public class DbClient {
return snapshotDao;
}
+ public AnalysisPropertiesDao analysisPropertiesDao() {
+ return analysisPropertiesDao;
+ }
+
public ComponentDao componentDao() {
return componentDao;
}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
index 7cd8e4ab309..bfb866e758d 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
@@ -35,6 +35,7 @@ import org.sonar.db.ce.CeScannerContextMapper;
import org.sonar.db.ce.CeTaskCharacteristicDto;
import org.sonar.db.ce.CeTaskCharacteristicMapper;
import org.sonar.db.ce.CeTaskInputMapper;
+import org.sonar.db.component.AnalysisPropertiesMapper;
import org.sonar.db.component.BranchMapper;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentDtoWithSnapshotId;
@@ -45,6 +46,7 @@ import org.sonar.db.component.ComponentMapper;
import org.sonar.db.component.FilePathWithHashDto;
import org.sonar.db.component.KeyWithUuidDto;
import org.sonar.db.component.ResourceDto;
+import org.sonar.db.component.ScrapAnalysisPropertyDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.component.SnapshotMapper;
import org.sonar.db.component.UuidWithProjectUuidDto;
@@ -184,6 +186,7 @@ public class MyBatis implements Startable {
confBuilder.loadAlias("Rule", RuleDto.class);
confBuilder.loadAlias("SchemaMigration", SchemaMigrationDto.class);
confBuilder.loadAlias("ScrapProperty", ScrapPropertyDto.class);
+ confBuilder.loadAlias("ScrapAnalysisProperty", ScrapAnalysisPropertyDto.class);
confBuilder.loadAlias("Snapshot", SnapshotDto.class);
confBuilder.loadAlias("UserGroup", UserGroupDto.class);
confBuilder.loadAlias("UserPermission", UserPermissionDto.class);
@@ -196,6 +199,7 @@ public class MyBatis implements Startable {
// keep them sorted alphabetically
Class<?>[] mappers = {
ActiveRuleMapper.class,
+ AnalysisPropertiesMapper.class,
AuthorizationMapper.class,
BranchMapper.class,
CeActivityMapper.class,
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertiesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertiesDao.java
new file mode 100644
index 00000000000..3bc80676119
--- /dev/null
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertiesDao.java
@@ -0,0 +1,78 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.component;
+
+import java.util.List;
+import javax.annotation.Nullable;
+import org.sonar.api.utils.System2;
+import org.sonar.db.Dao;
+import org.sonar.db.DbSession;
+
+import static java.util.Objects.requireNonNull;
+
+public class AnalysisPropertiesDao implements Dao {
+ private static final int VARCHAR_MAXSIZE = 4000;
+
+ private final System2 system2;
+
+ public AnalysisPropertiesDao(System2 system2) {
+ this.system2 = system2;
+ }
+
+ public List<AnalysisPropertyDto> selectBySnapshotUuid(DbSession session, String snapshotUuid) {
+ requireNonNull(snapshotUuid);
+ return getMapper(session).selectBySnapshotUuid(snapshotUuid);
+ }
+
+ public void insert(DbSession session, List<AnalysisPropertyDto> analysisPropertyDto) {
+ analysisPropertyDto.forEach(a -> insert(session, a));
+ }
+
+ public void insert(DbSession session, AnalysisPropertyDto analysisPropertyDto) {
+ requireNonNull(analysisPropertyDto.getUuid(), "uuid cannot be null");
+ requireNonNull(analysisPropertyDto.getKey(), "key cannot be null");
+ requireNonNull(analysisPropertyDto.getSnapshotUuid(), "snapshot uuid cannot be null");
+ requireNonNull(analysisPropertyDto.getValue(), "value cannot be null");
+
+ String value = analysisPropertyDto.getValue();
+ long now = system2.now();
+
+ if (isEmpty(value)) {
+ getMapper(session).insertAsEmpty(analysisPropertyDto, now);
+ } else if (mustBeStoredInClob(value)) {
+ getMapper(session).insertAsClob(analysisPropertyDto, now);
+ } else {
+ getMapper(session).insertAsText(analysisPropertyDto, now);
+ }
+ }
+
+ private static boolean mustBeStoredInClob(String value) {
+ return value.length() > VARCHAR_MAXSIZE;
+ }
+
+ private static boolean isEmpty(@Nullable String str) {
+ return str == null || str.isEmpty();
+ }
+
+ private static AnalysisPropertiesMapper getMapper(DbSession session) {
+ return session.getMapper(AnalysisPropertiesMapper.class);
+ }
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertiesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertiesMapper.java
new file mode 100644
index 00000000000..3df83a34354
--- /dev/null
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertiesMapper.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.component;
+
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface AnalysisPropertiesMapper {
+
+ List<AnalysisPropertyDto> selectBySnapshotUuid(@Param("snapshotUuid") String snapshotUuid);
+
+ void insertAsEmpty(@Param("analysisPropertyDto") AnalysisPropertyDto analysisPropertyDto, @Param("createdAt") long createdAt);
+
+ void insertAsClob(@Param("analysisPropertyDto") AnalysisPropertyDto analysisPropertyDto, @Param("createdAt") long createdAt);
+
+ void insertAsText(@Param("analysisPropertyDto") AnalysisPropertyDto analysisPropertyDto, @Param("createdAt") long createdAt);
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertyDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertyDto.java
new file mode 100644
index 00000000000..d11bb18e59a
--- /dev/null
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/AnalysisPropertyDto.java
@@ -0,0 +1,114 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.component;
+
+import java.util.Objects;
+
+import static java.util.Objects.requireNonNull;
+
+public class AnalysisPropertyDto {
+
+ private String uuid;
+ private String snapshotUuid;
+ private String key;
+ private String value;
+ private Long createdAt;
+
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public AnalysisPropertyDto setUuid(String uuid) {
+ requireNonNull(uuid, "uuid cannot be null");
+ this.uuid = uuid;
+ return this;
+ }
+
+ public String getSnapshotUuid() {
+ return snapshotUuid;
+ }
+
+ public AnalysisPropertyDto setSnapshotUuid(String snapshotUuid) {
+ requireNonNull(snapshotUuid, "snapshotUuid cannot be null");
+ this.snapshotUuid = snapshotUuid;
+ return this;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public AnalysisPropertyDto setKey(String key) {
+ requireNonNull(key, "key cannot be null");
+ this.key = key;
+ return this;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public AnalysisPropertyDto setValue(String value) {
+ requireNonNull(value, "value cannot be null");
+ this.value = value;
+ return this;
+ }
+
+ public Long getCreatedAt() {
+ return createdAt;
+ }
+
+ public AnalysisPropertyDto setCreatedAt(Long createdAt) {
+ this.createdAt = createdAt;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "BranchDto{" + "uuid='" + uuid + '\'' +
+ ", snapshotUuid='" + snapshotUuid + '\'' +
+ ", key='" + key + '\'' +
+ ", value='" + value + "'" +
+ ", createdAt=" + createdAt +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof AnalysisPropertyDto)) {
+ return false;
+ }
+ AnalysisPropertyDto that = (AnalysisPropertyDto) o;
+ return Objects.equals(uuid, that.uuid) &&
+ Objects.equals(snapshotUuid, that.snapshotUuid) &&
+ Objects.equals(key, that.key) &&
+ Objects.equals(value, that.value) &&
+ Objects.equals(createdAt, that.createdAt);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(uuid, snapshotUuid, key, value, createdAt);
+ }
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ScrapAnalysisPropertyDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ScrapAnalysisPropertyDto.java
new file mode 100644
index 00000000000..e71061a5644
--- /dev/null
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ScrapAnalysisPropertyDto.java
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.component;
+
+import javax.annotation.Nullable;
+
+public class ScrapAnalysisPropertyDto extends AnalysisPropertyDto {
+ public void setEmpty(boolean flag) {
+ if (flag) {
+ setValue("");
+ }
+ }
+
+ public void setTextValue(@Nullable String value) {
+ if (value != null) {
+ setValue(value);
+ }
+ }
+
+ public void setClobValue(@Nullable String value) {
+ if (value != null) {
+ setValue(value);
+ }
+ }
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java
index 91039c40d61..9d65a9834c8 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java
@@ -76,6 +76,11 @@ class PurgeCommands {
analysisUuidsPartitions.forEach(purgeMapper::deleteAnalyses);
session.commit();
profiler.stop();
+
+ profiler.start("deleteAnalyses (analysis_properties)");
+ analysisUuidsPartitions.forEach(purgeMapper::deleteAnalysisProperties);
+ session.commit();
+ profiler.stop();
}
void deleteAnalyses(PurgeSnapshotQuery... queries) {
@@ -105,6 +110,11 @@ class PurgeCommands {
analysisUuidsPartitions.forEach(purgeMapper::deleteAnalyses);
session.commit();
profiler.stop();
+
+ profiler.start("deleteAnalyses (analysis_properties)");
+ analysisUuidsPartitions.forEach(purgeMapper::deleteAnalysisProperties);
+ session.commit();
+ profiler.stop();
}
void purgeAnalyses(List<IdUuidPair> analysisUuids) {
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java
index 6ea97e7aa28..3961aa6a335 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java
@@ -34,6 +34,8 @@ public interface PurgeMapper {
void deleteAnalyses(@Param("analysisUuids") List<String> analysisUuids);
+ void deleteAnalysisProperties(@Param("analysisUuids") List<String> analysisUuids);
+
void deleteAnalysisDuplications(@Param("analysisUuids") List<String> analysisUuids);
void deleteAnalysisEvents(@Param("analysisUuids") List<String> analysisUuids);
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/AnalysisPropertiesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/AnalysisPropertiesMapper.xml
new file mode 100644
index 00000000000..2dcfb5bc662
--- /dev/null
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/AnalysisPropertiesMapper.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
+<mapper namespace="org.sonar.db.component.AnalysisPropertiesMapper">
+
+ <sql id="columns">
+ uuid as "uuid",
+ snapshot_uuid as "snapshotUuid",
+ kee as "key",
+ text_value as "textValue",
+ clob_value as "clobValue",
+ is_empty as "empty",
+ created_at as "createdAt"
+ </sql>
+
+ <select id="selectBySnapshotUuid" parameterType="string" resultType="ScrapAnalysisProperty">
+ SELECT
+ <include refid="columns"/>
+ FROM
+ analysis_properties
+ WHERE
+ snapshot_uuid = #{snapshotUuid}
+ </select>
+
+ <insert id="insertAsEmpty" parameterType="map" useGeneratedKeys="false">
+ INSERT INTO analysis_properties (
+ uuid,
+ snapshot_uuid,
+ kee,
+ is_empty,
+ created_at
+ ) VALUES (
+ #{analysisPropertyDto.uuid, jdbcType=VARCHAR},
+ #{analysisPropertyDto.snapshotUuid, jdbcType=VARCHAR},
+ #{analysisPropertyDto.key, jdbcType=VARCHAR},
+ ${_true},
+ #{createdAt}
+ )
+ </insert>
+
+ <insert id="insertAsText" parameterType="map" useGeneratedKeys="false">
+ INSERT INTO analysis_properties (
+ uuid,
+ snapshot_uuid,
+ kee,
+ text_value,
+ is_empty,
+ created_at
+ ) VALUES (
+ #{analysisPropertyDto.uuid, jdbcType=VARCHAR},
+ #{analysisPropertyDto.snapshotUuid, jdbcType=VARCHAR},
+ #{analysisPropertyDto.key, jdbcType=VARCHAR},
+ #{analysisPropertyDto.value, jdbcType=VARCHAR},
+ ${_false},
+ #{createdAt}
+ )
+ </insert>
+
+ <insert id="insertAsClob" parameterType="Map" useGeneratedKeys="false">
+ INSERT INTO analysis_properties (
+ uuid,
+ snapshot_uuid,
+ kee,
+ clob_value,
+ is_empty,
+ created_at
+ ) VALUES (
+ #{analysisPropertyDto.uuid, jdbcType=VARCHAR},
+ #{analysisPropertyDto.snapshotUuid, jdbcType=VARCHAR},
+ #{analysisPropertyDto.key, jdbcType=VARCHAR},
+ #{analysisPropertyDto.value, jdbcType=VARCHAR},
+ ${_false},
+ #{createdAt}
+ )
+ </insert>
+
+</mapper>
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml
index 1b167408045..1316351dced 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml
@@ -136,6 +136,15 @@
</foreach>
</delete>
+ <delete id="deleteAnalysisProperties" parameterType="map">
+ DELETE FROM analysis_properties
+ WHERE
+ snapshot_uuid IN
+ <foreach collection="analysisUuids" open="(" close=")" item="analysisUuid" separator=",">
+ #{analysisUuid,jdbcType=VARCHAR}
+ </foreach>
+ </delete>
+
<delete id="deleteAnalysisWastedMeasures" parameterType="map">
delete from project_measures
<where>
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java
index 4fe76690889..5ff22c1e2fd 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java
@@ -23,12 +23,13 @@ import org.junit.Test;
import org.sonar.core.platform.ComponentContainer;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER;
public class DaoModuleTest {
@Test
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new DaoModule().configure(container);
- assertThat(container.size()).isEqualTo(2 + 51);
+ assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 52);
}
}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/AnalysisPropertiesDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/AnalysisPropertiesDaoTest.java
new file mode 100644
index 00000000000..0295573904c
--- /dev/null
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/AnalysisPropertiesDaoTest.java
@@ -0,0 +1,182 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.component;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.TestSystem2;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AnalysisPropertiesDaoTest {
+ private static final long NOW = 1_000L;
+
+ @Rule
+ public DbTester dbTester = DbTester.create(System2.INSTANCE);
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private final System2 system2 = new TestSystem2().setNow(NOW);
+ private final DbSession dbSession = dbTester.getSession();
+ private final AnalysisPropertiesDao underTest = new AnalysisPropertiesDao(system2);
+ private final Random random = new Random();
+
+ @Test
+ public void insert_with_null_uuid_throws_NPE() {
+ AnalysisPropertyDto analysisPropertyDto = new AnalysisPropertyDto()
+ .setSnapshotUuid(randomAlphanumeric(10))
+ .setKey(randomAlphanumeric(10))
+ .setValue(randomAlphanumeric(10));
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("uuid cannot be null");
+
+ underTest.insert(dbSession, analysisPropertyDto);
+ }
+
+ @Test
+ public void insert_with_null_key_throws_NPE() {
+ AnalysisPropertyDto analysisPropertyDto = new AnalysisPropertyDto()
+ .setSnapshotUuid(randomAlphanumeric(10))
+ .setUuid(randomAlphanumeric(10))
+ .setValue(randomAlphanumeric(10));
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("key cannot be null");
+
+ underTest.insert(dbSession, analysisPropertyDto);
+ }
+
+ @Test
+ public void insert_with_null_snapshot_uuid_throws_NPE() {
+ AnalysisPropertyDto analysisPropertyDto = new AnalysisPropertyDto()
+ .setUuid(randomAlphanumeric(10))
+ .setKey(randomAlphanumeric(10))
+ .setValue(randomAlphanumeric(10));
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("snapshot uuid cannot be null");
+
+ underTest.insert(dbSession, analysisPropertyDto);
+ }
+
+ @Test
+ public void insert_with_null_value_throws_NPE() {
+ AnalysisPropertyDto analysisPropertyDto = new AnalysisPropertyDto()
+ .setSnapshotUuid(randomAlphanumeric(10))
+ .setUuid(randomAlphanumeric(10))
+ .setKey(randomAlphanumeric(10));
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("value cannot be null");
+
+ underTest.insert(dbSession, analysisPropertyDto);
+ }
+
+ @Test
+ public void insert_as_empty() {
+ AnalysisPropertyDto analysisPropertyDto = insertAnalysisPropertyDto(0);
+
+ assertThat(dbTester.countRowsOfTable(dbSession, "ANALYSIS_PROPERTIES")).isEqualTo(1);
+ compareFirstValueWith(analysisPropertyDto);
+ }
+
+ @Test
+ public void insert_as_text() {
+ AnalysisPropertyDto analysisPropertyDto = insertAnalysisPropertyDto(1 + random.nextInt(3999));
+
+ assertThat(dbTester.countRowsOfTable(dbSession, "ANALYSIS_PROPERTIES")).isEqualTo(1);
+ compareFirstValueWith(analysisPropertyDto);
+ }
+
+ @Test
+ public void insert_as_clob() {
+ AnalysisPropertyDto analysisPropertyDto = insertAnalysisPropertyDto(4000 + random.nextInt(100));
+
+ assertThat(dbTester.countRowsOfTable(dbSession, "ANALYSIS_PROPERTIES")).isEqualTo(1);
+ compareFirstValueWith(analysisPropertyDto);
+ }
+
+ @Test
+ public void insert_a_list() {
+ List<AnalysisPropertyDto> propertyDtos = Arrays.asList(
+ newAnalysisPropertyDto(random.nextInt(8000), randomAlphanumeric(40)),
+ newAnalysisPropertyDto(random.nextInt(8000), randomAlphanumeric(40)),
+ newAnalysisPropertyDto(random.nextInt(8000), randomAlphanumeric(40)),
+ newAnalysisPropertyDto(random.nextInt(8000), randomAlphanumeric(40)),
+ newAnalysisPropertyDto(random.nextInt(8000), randomAlphanumeric(40)),
+ newAnalysisPropertyDto(random.nextInt(8000), randomAlphanumeric(40)),
+ newAnalysisPropertyDto(random.nextInt(8000), randomAlphanumeric(40)),
+ newAnalysisPropertyDto(random.nextInt(8000), randomAlphanumeric(40)));
+
+ underTest.insert(dbSession, propertyDtos);
+ assertThat(dbTester.countRowsOfTable(dbSession, "ANALYSIS_PROPERTIES")).isEqualTo(propertyDtos.size());
+ }
+
+ @Test
+ public void selectByAnalysisUuid_should_return_correct_values() {
+ String snapshotUuid = randomAlphanumeric(40);
+
+ List<AnalysisPropertyDto> propertyDtos = Arrays.asList(
+ newAnalysisPropertyDto(random.nextInt(8000), snapshotUuid),
+ newAnalysisPropertyDto(random.nextInt(8000), snapshotUuid),
+ newAnalysisPropertyDto(random.nextInt(8000), snapshotUuid),
+ newAnalysisPropertyDto(random.nextInt(8000), snapshotUuid),
+ newAnalysisPropertyDto(random.nextInt(8000), snapshotUuid),
+ newAnalysisPropertyDto(random.nextInt(8000), snapshotUuid),
+ newAnalysisPropertyDto(random.nextInt(8000), snapshotUuid),
+ newAnalysisPropertyDto(random.nextInt(8000), snapshotUuid));
+
+ underTest.insert(dbSession, propertyDtos);
+ assertThat(dbTester.countRowsOfTable(dbSession, "ANALYSIS_PROPERTIES")).isEqualTo(propertyDtos.size());
+
+ List<AnalysisPropertyDto> result = underTest.selectBySnapshotUuid(dbSession, snapshotUuid);
+ assertThat(result).containsExactlyInAnyOrder((AnalysisPropertyDto[]) propertyDtos.toArray());
+ }
+
+ private AnalysisPropertyDto insertAnalysisPropertyDto(int valueLength) {
+ AnalysisPropertyDto analysisPropertyDto = newAnalysisPropertyDto(valueLength, randomAlphanumeric(40));
+ underTest.insert(dbSession, analysisPropertyDto);
+ return analysisPropertyDto;
+ }
+
+ private AnalysisPropertyDto newAnalysisPropertyDto(int valueLength, String snapshotUuid) {
+ return new AnalysisPropertyDto()
+ .setSnapshotUuid(snapshotUuid)
+ .setKey(randomAlphanumeric(512))
+ .setUuid(randomAlphanumeric(40))
+ .setValue(randomAlphanumeric(valueLength))
+ .setCreatedAt( 1_000L);
+ }
+
+ private void compareFirstValueWith(AnalysisPropertyDto analysisPropertyDto) {
+ AnalysisPropertyDto dtoFromDatabase = underTest.selectBySnapshotUuid(dbSession, analysisPropertyDto.getSnapshotUuid()).get(0);
+ assertThat(dtoFromDatabase).isEqualTo(analysisPropertyDto);
+ }
+}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/AnalysisPropertyDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/AnalysisPropertyDtoTest.java
new file mode 100644
index 00000000000..252df3efc52
--- /dev/null
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/AnalysisPropertyDtoTest.java
@@ -0,0 +1,169 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.component;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AnalysisPropertyDtoTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private AnalysisPropertyDto underTest;
+
+ @Test
+ public void null_key_should_throw_NPE() {
+ underTest = new AnalysisPropertyDto();
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("key cannot be null");
+
+ underTest.setKey(null);
+ }
+
+ @Test
+ public void null_value_should_throw_NPE() {
+ underTest = new AnalysisPropertyDto();
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("value cannot be null");
+
+ underTest.setValue(null);
+ }
+
+ @Test
+ public void null_uuid_should_throw_NPE() {
+ underTest = new AnalysisPropertyDto();
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("uuid cannot be null");
+
+ underTest.setUuid(null);
+ }
+
+ @Test
+ public void null_snapshot_uuid_should_throw_NPE() {
+ underTest = new AnalysisPropertyDto();
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("snapshotUuid cannot be null");
+
+ underTest.setSnapshotUuid(null);
+ }
+
+ @Test
+ public void test_equality() {
+ underTest = new AnalysisPropertyDto()
+ .setUuid(randomAlphanumeric(40))
+ .setSnapshotUuid(randomAlphanumeric(40))
+ .setKey(randomAlphanumeric(512))
+ .setValue(randomAlphanumeric(10000));
+
+ assertThat(underTest).isEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid(underTest.getUuid())
+ .setSnapshotUuid(underTest.getSnapshotUuid())
+ .setKey(underTest.getKey())
+ .setValue(underTest.getValue()));
+
+ assertThat(underTest).isNotEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid("1" + underTest.getUuid())
+ .setSnapshotUuid(underTest.getSnapshotUuid())
+ .setKey(underTest.getKey())
+ .setValue(underTest.getValue()));
+
+ assertThat(underTest).isNotEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid(underTest.getUuid())
+ .setSnapshotUuid("1" + underTest.getSnapshotUuid())
+ .setKey(underTest.getKey())
+ .setValue(underTest.getValue()));
+
+ assertThat(underTest).isNotEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid(underTest.getUuid())
+ .setSnapshotUuid(underTest.getSnapshotUuid())
+ .setKey("1" + underTest.getKey())
+ .setValue(underTest.getValue()));
+
+ assertThat(underTest).isNotEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid(underTest.getUuid())
+ .setSnapshotUuid(underTest.getSnapshotUuid())
+ .setKey(underTest.getKey())
+ .setValue("1" + underTest.getValue()));
+ }
+
+ @Test
+ public void test_hashcode() {
+ underTest = new AnalysisPropertyDto()
+ .setUuid(randomAlphanumeric(40))
+ .setSnapshotUuid(randomAlphanumeric(40))
+ .setKey(randomAlphanumeric(512))
+ .setValue(randomAlphanumeric(10000));
+
+ assertThat(underTest.hashCode()).isEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid(underTest.getUuid())
+ .setSnapshotUuid(underTest.getSnapshotUuid())
+ .setKey(underTest.getKey())
+ .setValue(underTest.getValue())
+ .hashCode());
+
+ assertThat(underTest.hashCode()).isNotEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid("1" + underTest.getUuid())
+ .setSnapshotUuid(underTest.getSnapshotUuid())
+ .setKey(underTest.getKey())
+ .setValue(underTest.getValue())
+ .hashCode());
+
+ assertThat(underTest.hashCode()).isNotEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid(underTest.getUuid())
+ .setSnapshotUuid("1" + underTest.getSnapshotUuid())
+ .setKey(underTest.getKey())
+ .setValue(underTest.getValue())
+ .hashCode());
+
+ assertThat(underTest.hashCode()).isNotEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid(underTest.getUuid())
+ .setSnapshotUuid(underTest.getSnapshotUuid())
+ .setKey("1" + underTest.getKey())
+ .setValue(underTest.getValue())
+ .hashCode());
+
+ assertThat(underTest.hashCode()).isNotEqualTo(
+ new AnalysisPropertyDto()
+ .setUuid(underTest.getUuid())
+ .setSnapshotUuid(underTest.getSnapshotUuid())
+ .setKey(underTest.getKey())
+ .setValue("1" + underTest.getValue())
+ .hashCode());
+ }
+}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ScrapAnalysisPropertyDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ScrapAnalysisPropertyDtoTest.java
new file mode 100644
index 00000000000..d1ccaa5d4fe
--- /dev/null
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ScrapAnalysisPropertyDtoTest.java
@@ -0,0 +1,58 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.component;
+
+import java.util.Random;
+import org.junit.Test;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ScrapAnalysisPropertyDtoTest {
+
+ private Random random = new Random();
+
+ @Test
+ public void test_empty_value() {
+ ScrapAnalysisPropertyDto underTest = new ScrapAnalysisPropertyDto();
+ underTest.setEmpty(true);
+
+ assertThat(underTest.getValue()).isEqualTo("");
+ }
+
+ @Test
+ public void test_text_set() {
+ ScrapAnalysisPropertyDto underTest = new ScrapAnalysisPropertyDto();
+ String value = randomAlphanumeric(random.nextInt(4000));
+ underTest.setTextValue(value);
+
+ assertThat(underTest.getValue()).isEqualTo(value);
+ }
+
+ @Test
+ public void test_clob_set() {
+ ScrapAnalysisPropertyDto underTest = new ScrapAnalysisPropertyDto();
+ String value = randomAlphanumeric(4000 + random.nextInt(4000));
+ underTest.setClobValue(value);
+
+ assertThat(underTest.getValue()).isEqualTo(value);
+ }
+}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java
index 81196f56e0b..d6b7f01f9f9 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java
@@ -20,6 +20,7 @@
package org.sonar.db.purge;
import java.util.List;
+import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
@@ -43,6 +44,14 @@ public class PurgeCommandsTest {
private PurgeProfiler profiler = new PurgeProfiler();
/**
+ * Required because there is no autogenerated keys for analysis_properties
+ */
+ @After
+ public void resetAnalysisProperties() {
+ dbTester.executeUpdateSql("DELETE FROM analysis_properties");
+ }
+
+ /**
* Test that SQL queries execution do not fail with a huge number of parameter
*/
@Test
@@ -60,7 +69,7 @@ public class PurgeCommandsTest {
new PurgeCommands(dbTester.getSession(), profiler).purgeAnalyses(singletonList(new IdUuidPair(1, "u1")));
- dbTester.assertDbUnit(getClass(), "shouldPurgeAnalysis-result.xml", "snapshots", "project_measures", "duplications_index", "events");
+ dbTester.assertDbUnit(getClass(), "shouldPurgeAnalysis-result.xml", "snapshots", "analysis_properties", "project_measures", "duplications_index", "events");
}
@Test
@@ -105,6 +114,7 @@ public class PurgeCommandsTest {
assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(1);
assertThat(dbTester.countRowsOfTable("snapshots")).isZero();
+ assertThat(dbTester.countRowsOfTable("analysis_properties")).isZero();
assertThat(dbTester.countRowsOfTable("events")).isZero();
assertThat(dbTester.countRowsOfTable("issues")).isEqualTo(1);
assertThat(dbTester.countRowsOfTable("issue_changes")).isEqualTo(1);
diff --git a/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldDeleteResource.xml b/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldDeleteResource.xml
index 330057a1b73..ba8ac69dff9 100644
--- a/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldDeleteResource.xml
+++ b/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldDeleteResource.xml
@@ -44,6 +44,15 @@
version="[null]"
/>
+ <analysis_properties uuid="u1"
+ snapshot_uuid="u1"
+ kee="key1"
+ clob_value="[null]"
+ text_value="value1"
+ is_empty="[false]"
+ created_at="1228222680000"
+ />
+
<events id="1"
uuid="P1"
analysis_uuid="u1"
diff --git a/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis-result.xml b/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis-result.xml
index 6cb45a58538..9b8cfc57b26 100644
--- a/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis-result.xml
+++ b/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis-result.xml
@@ -33,6 +33,14 @@ Note that measures, events and reviews are not deleted.
build_date="1228222680000"
version="[null]"
/>
+ <analysis_properties uuid="u1"
+ snapshot_uuid="u1"
+ kee="key1"
+ text_value="value1"
+ clob_value="[null]"
+ is_empty="[false]"
+ created_at="1228222680000"
+ />
<!--switched_off="[null]" permanent_id="[null]" FAILURE_LEVEL="2"-->
<!--MESSAGE="msg1" LINE="[null]" COST="[null]"-->
@@ -98,6 +106,14 @@ Note that measures, events and reviews are not deleted.
version="[null]"
/>
+ <analysis_properties uuid="u2"
+ snapshot_uuid="u2"
+ kee="key2"
+ clob_value="[null]"
+ text_value="value2"
+ is_empty="[false]"
+ created_at="1228222680000"
+ />
<project_measures ID="2"
component_uuid="2"
diff --git a/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis.xml b/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis.xml
index d086021a151..70b5a8db7c1 100644
--- a/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis.xml
+++ b/server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis.xml
@@ -26,6 +26,15 @@
version="[null]"
/>
+ <analysis_properties uuid="u1"
+ snapshot_uuid="u1"
+ kee="key1"
+ clob_value="[null]"
+ text_value="value1"
+ is_empty="[false]"
+ created_at="1228222680000"
+ />
+
<project_measures ID="1"
component_uuid="1"
analysis_uuid="u1"
@@ -90,6 +99,15 @@
version="[null]"
/>
+ <analysis_properties uuid="u2"
+ snapshot_uuid="u2"
+ kee="key2"
+ clob_value="[null]"
+ text_value="value2"
+ is_empty="[false]"
+ created_at="1228222680000"
+ />
+
<project_measures ID="2"
component_uuid="2"
analysis_uuid="u2"
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisProperties.java
new file mode 100644
index 00000000000..f683f860adc
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisProperties.java
@@ -0,0 +1,88 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.platform.db.migration.version.v67;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef;
+import org.sonar.server.platform.db.migration.def.BooleanColumnDef;
+import org.sonar.server.platform.db.migration.def.ClobColumnDef;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateTableBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class CreateTableAnalysisProperties extends DdlChange {
+ private static final String TABLE_NAME = "analysis_properties";
+ private static final String SNAPSHOT_UUID = "snapshot_uuid";
+ private static final VarcharColumnDef SNAPSHOT_UUID_COLUMN = VarcharColumnDef.newVarcharColumnDefBuilder()
+ .setColumnName(SNAPSHOT_UUID)
+ .setIsNullable(false)
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .build();
+
+ public CreateTableAnalysisProperties(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new CreateTableBuilder(getDialect(), TABLE_NAME)
+ .addPkColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+ .setColumnName("uuid")
+ .setIsNullable(false)
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .build())
+ .addColumn(SNAPSHOT_UUID_COLUMN)
+ .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+ .setColumnName("kee")
+ .setIsNullable(false)
+ .setLimit(512)
+ .build())
+ .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+ .setColumnName("text_value")
+ .setIsNullable(true)
+ .setLimit(VarcharColumnDef.MAX_SIZE)
+ .build())
+ .addColumn(ClobColumnDef.newClobColumnDefBuilder()
+ .setColumnName("clob_value")
+ .setIsNullable(true)
+ .build())
+ .addColumn(BooleanColumnDef.newBooleanColumnDefBuilder()
+ .setColumnName("is_empty")
+ .setIsNullable(false)
+ .build())
+ .addColumn(BigIntegerColumnDef.newBigIntegerColumnDefBuilder()
+ .setColumnName("created_at")
+ .setIsNullable(false)
+ .build())
+ .build()
+ );
+
+ context.execute(new CreateIndexBuilder(getDialect())
+ .addColumn(SNAPSHOT_UUID_COLUMN)
+ .setUnique(false)
+ .setTable(TABLE_NAME)
+ .setName("ix_snapshot_uuid")
+ .build()
+ );
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67.java
index e5b479e4d1d..475e3df7db0 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67.java
@@ -27,6 +27,8 @@ public class DbVersion67 implements DbVersion {
public void addSteps(MigrationStepRegistry registry) {
registry
.add(1830, "Copy deprecated server ID", CopyDeprecatedServerId.class)
- .add(1831, "Add webhook_deliveries.analysis_uuid", AddAnalysisUuidToWebhookDeliveries.class);
+ .add(1831, "Add webhook_deliveries.analysis_uuid", AddAnalysisUuidToWebhookDeliveries.class)
+ .add(1832, "Create table ANALYSIS_PROPERTIES", CreateTableAnalysisProperties.class)
+ ;
}
}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisPropertiesTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisPropertiesTest.java
new file mode 100644
index 00000000000..e667d96b124
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisPropertiesTest.java
@@ -0,0 +1,53 @@
+package org.sonar.server.platform.db.migration.version.v67;/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CreateTableAnalysisPropertiesTest {
+ private static final String TABLE = "analysis_properties";
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(CreateTableAnalysisPropertiesTest.class, "empty.sql");
+
+ private CreateTableAnalysisProperties underTest = new CreateTableAnalysisProperties(db.database());
+
+ @Test
+ public void creates_table_on_empty_db() throws SQLException {
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable(TABLE)).isEqualTo(0);
+
+ db.assertColumnDefinition(TABLE, "uuid", Types.VARCHAR, 40, false);
+ db.assertColumnDefinition(TABLE, "snapshot_uuid", Types.VARCHAR, 40, false);
+ db.assertColumnDefinition(TABLE, "kee", Types.VARCHAR, 512, false);
+ db.assertColumnDefinition(TABLE, "text_value", Types.VARCHAR, 4000, true);
+ db.assertColumnDefinition(TABLE, "clob_value", Types.CLOB, 2147483647, true);
+ db.assertColumnDefinition(TABLE, "is_empty", Types.BOOLEAN, null, false);
+ db.assertColumnDefinition(TABLE, "created_at", Types.BIGINT, null, false);
+
+ db.assertIndex(TABLE, "ix_snapshot_uuid", "snapshot_uuid");
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67Test.java
index ada1069cc8d..4fef78d7e20 100644
--- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67Test.java
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v67/DbVersion67Test.java
@@ -36,7 +36,7 @@ public class DbVersion67Test {
@Test
public void verify_migration_count() {
- verifyMigrationCount(underTest, 2);
+ verifyMigrationCount(underTest, 3);
}
}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisPropertiesTest/empty.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisPropertiesTest/empty.sql
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v67/CreateTableAnalysisPropertiesTest/empty.sql
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistAnalysisPropertiesStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistAnalysisPropertiesStep.java
new file mode 100644
index 00000000000..c85504e3755
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistAnalysisPropertiesStep.java
@@ -0,0 +1,81 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.step;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.AnalysisPropertyDto;
+import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
+import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReader;
+import org.sonar.server.computation.task.step.ComputationStep;
+
+/**
+ * Persist analysis properties
+ * Only properties starting with "sonar.analysis" will be persisted in database
+ */
+public class PersistAnalysisPropertiesStep implements ComputationStep {
+
+ private static final String SONAR_ANALYSIS = "sonar.analysis.";
+
+ private final DbClient dbClient;
+ private final AnalysisMetadataHolder analysisMetadataHolder;
+ private final BatchReportReader reportReader;
+ private final UuidFactory uuidFactory;
+
+ public PersistAnalysisPropertiesStep(DbClient dbClient, AnalysisMetadataHolder analysisMetadataHolder,
+ BatchReportReader reportReader, UuidFactory uuidFactory) {
+ this.dbClient = dbClient;
+ this.analysisMetadataHolder = analysisMetadataHolder;
+ this.reportReader = reportReader;
+ this.uuidFactory = uuidFactory;
+ }
+
+ @Override
+ public void execute() {
+ final List<AnalysisPropertyDto> analysisPropertyDtos = new ArrayList<>();
+ reportReader.readContextProperties().forEachRemaining(
+ contextProperty -> {
+ if (contextProperty.getKey().startsWith(SONAR_ANALYSIS)) {
+ analysisPropertyDtos.add(new AnalysisPropertyDto()
+ .setUuid(uuidFactory.create())
+ .setKey(contextProperty.getKey())
+ .setValue(contextProperty.getValue())
+ .setSnapshotUuid(analysisMetadataHolder.getUuid()));
+ }
+ });
+
+ if (analysisPropertyDtos.isEmpty()) {
+ return;
+ }
+
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ dbClient.analysisPropertiesDao().insert(dbSession, analysisPropertyDtos);
+ dbSession.commit();
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Persist analysis properties";
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java
index d60f9441d46..108ca3b9d84 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java
@@ -86,6 +86,7 @@ public class ReportComputationSteps extends AbstractComputationSteps {
// Persist data
PersistComponentsStep.class,
PersistAnalysisStep.class,
+ PersistAnalysisPropertiesStep.class,
PersistMeasuresStep.class,
PersistIssuesStep.class,
PersistProjectLinksStep.class,
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistAnalysisPropertiesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistAnalysisPropertiesStepTest.java
new file mode 100644
index 00000000000..3006fba9b41
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistAnalysisPropertiesStepTest.java
@@ -0,0 +1,94 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.computation.task.projectanalysis.step;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.core.util.CloseableIterator;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.AnalysisPropertyDto;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
+import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReader;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PersistAnalysisPropertiesStepTest {
+ private static final String SNAPSHOT_UUID = randomAlphanumeric(40);
+ private static final String SMALL_VALUE1 = randomAlphanumeric(50);
+ private static final String SMALL_VALUE2 = randomAlphanumeric(50);
+ private static final String BIG_VALUE = randomAlphanumeric(5000);
+ private static final List<ScannerReport.ContextProperty> PROPERTIES = Arrays.asList(
+ newContextProperty("key1", "value1"),
+ newContextProperty("key2", "value1"),
+ newContextProperty("sonar.analysis", SMALL_VALUE1),
+ newContextProperty("sonar.analysis.branch", SMALL_VALUE1),
+ newContextProperty("sonar.analysis.empty_string", ""),
+ newContextProperty("sonar.analysis.big_value", BIG_VALUE),
+ newContextProperty("sonar.analysis.", SMALL_VALUE2));
+
+ @Rule
+ public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+ private BatchReportReader batchReportReader = mock(BatchReportReader.class);
+ private AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
+ private PersistAnalysisPropertiesStep underTest = new PersistAnalysisPropertiesStep(dbTester.getDbClient(), analysisMetadataHolder, batchReportReader, UuidFactoryFast.getInstance());
+
+ @Before
+ public void setup() {
+ when(batchReportReader.readContextProperties()).thenReturn(CloseableIterator.from(PROPERTIES.iterator()));
+ when(analysisMetadataHolder.getUuid()).thenReturn(SNAPSHOT_UUID);
+ }
+
+ @Test
+ public void persist_should_store_only_sonarDotAnalysis_properties() {
+ underTest.execute();
+ assertThat(dbTester.countRowsOfTable("analysis_properties")).isEqualTo(4);
+
+ 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_VALUE1),
+ tuple(SNAPSHOT_UUID, "sonar.analysis.empty_string", ""),
+ tuple(SNAPSHOT_UUID, "sonar.analysis.big_value", BIG_VALUE),
+ tuple(SNAPSHOT_UUID, "sonar.analysis.", SMALL_VALUE2)
+ );
+ }
+
+ private static ScannerReport.ContextProperty newContextProperty(String key, String value) {
+ return ScannerReport.ContextProperty.newBuilder()
+ .setKey(key)
+ .setValue(value)
+ .build();
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistAnalysisStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistAnalysisStepTest.java
index 40fbf42f133..3a3bb64bdd8 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistAnalysisStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ReportPersistAnalysisStepTest.java
@@ -63,16 +63,11 @@ public class ReportPersistAnalysisStepTest extends BaseStepTest {
public PeriodHolderRule periodsHolder = new PeriodHolderRule();
private System2 system2 = mock(System2.class);
-
private DbIdsRepositoryImpl dbIdsRepository;
-
private DbClient dbClient = dbTester.getDbClient();
-
private long analysisDate;
-
private long now;
-
- PersistAnalysisStep underTest;
+ private PersistAnalysisStep underTest;
@Before
public void setup() {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistAnalysisStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistAnalysisStepTest.java
index ba90ba20e89..7d7434d56b3 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistAnalysisStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistAnalysisStepTest.java
@@ -64,13 +64,9 @@ public class ViewsPersistAnalysisStepTest extends BaseStepTest {
public PeriodHolderRule periodsHolder = new PeriodHolderRule();
private System2 system2 = mock(System2.class);
-
private DbClient dbClient = dbTester.getDbClient();
-
private long analysisDate;
-
private long now;
-
private PersistAnalysisStep underTest;
@Before