INSERT INTO GROUPS(ID, ORGANIZATION_UUID, NAME, DESCRIPTION, CREATED_AT, UPDATED_AT) VALUES (2, 'AVdqnciQUUs7Zd3KPvFD', 'sonar-users', 'Any new users created will automatically join this group', '2011-09-26 22:27:51.0', '2011-09-26 22:27:51.0');
ALTER TABLE GROUPS ALTER COLUMN ID RESTART WITH 3;
-INSERT INTO QUALITY_GATES(ID, NAME, IS_BUILT_IN, CREATED_AT, UPDATED_AT) VALUES (1, 'Sonar Way', true, '2011-09-26 22:27:51.0', '2011-09-26 22:27:51.0');
+INSERT INTO QUALITY_GATES(ID, UUID, NAME, IS_BUILT_IN, CREATED_AT, UPDATED_AT) VALUES (1, 'AWASGWAKYOI_InFKS3UF', 'Sonar Way', true, '2011-09-26 22:27:51.0', '2011-09-26 22:27:51.0');
INSERT INTO ORGANIZATIONS (UUID, KEE, NAME, GUARDED, NEW_PROJECT_PRIVATE, DEFAULT_GROUP_ID, DEFAULT_QUALITY_GATE_UUID, CREATED_AT, UPDATED_AT) VALUES ('AVdqnciQUUs7Zd3KPvFD', 'default-organization', 'Default Organization', true, false, 2, 1, '1474962596482', '1474962596482');
INSERT INTO INTERNAL_PROPERTIES (KEE, IS_EMPTY, TEXT_VALUE, CREATED_AT) VALUES ('organization.default', false, 'AVdqnciQUUs7Zd3KPvFD', '1474962596482');
CREATE TABLE "QUALITY_GATES" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "UUID" VARCHAR(40) NOT NULL,
"NAME" VARCHAR(100) NOT NULL,
"IS_BUILT_IN" BOOLEAN NOT NULL,
"CREATED_AT" TIMESTAMP,
"UPDATED_AT" TIMESTAMP,
);
CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES" ON "QUALITY_GATES" ("NAME");
+CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES_UUID" ON "QUALITY_GATES" ("UUID");
CREATE TABLE "QUALITY_GATE_CONDITIONS" (
private Long id;
private String name;
+ private String uuid;
private boolean isBuiltIn;
private Date createdAt;
private Date updatedAt;
+ public String getUuid() {
+ return uuid;
+ }
+
+ public QualityGateDto setUuid(String uuid) {
+ this.uuid = uuid;
+ return this;
+ }
+
public Long getId() {
return id;
}
<mapper namespace="org.sonar.db.qualitygate.QualityGateMapper">
<insert id="insert" parameterType="QualityGate" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
- insert into quality_gates (name, is_built_in, created_at, updated_at)
- values (#{name}, #{isBuiltIn}, #{createdAt}, #{updatedAt})
+ insert into quality_gates (name, uuid, is_built_in, created_at, updated_at)
+ values (#{name}, #{uuid}, #{isBuiltIn}, #{createdAt}, #{updatedAt})
</insert>
<sql id="gateColumns">
- id, name, is_built_in as isBuiltIn, created_at as createdAt, updated_at as updatedAt
+ id, name, uuid, is_built_in as isBuiltIn, created_at as createdAt, updated_at as updatedAt
</sql>
<select id="selectAll" resultType="QualityGate">
name=#{name},
is_built_in=#{isBuiltIn},
updated_at=#{updatedAt}
- where id=#{id}
+ where uuid=#{uuid}
</update>
<update id="ensureOneBuiltInQualityGate" parameterType="string">
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
@Test
public void testInsert() {
- QualityGateDto newQgate = new QualityGateDto().setName("My Quality Gate");
+ QualityGateDto newQgate = new QualityGateDto().setName("My Quality Gate").setUuid(Uuids.createFast());
underTest.insert(dbSession, newQgate);
dbSession.commit();
@Test
public void insert_built_in() {
- underTest.insert(db.getSession(), new QualityGateDto().setName("test").setBuiltIn(true));
+ underTest.insert(db.getSession(), new QualityGateDto().setName("test").setBuiltIn(true).setUuid(Uuids.createFast()));
QualityGateDto reloaded = underTest.selectByName(db.getSession(), "test");
import java.util.Arrays;
import java.util.function.Consumer;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
public final QualityGateDto insertQualityGate(Consumer<QualityGateDto>... dtoPopulators) {
QualityGateDto qualityGate = new QualityGateDto()
.setName(randomAlphanumeric(30))
+ .setUuid(Uuids.createFast())
.setBuiltIn(false);
Arrays.stream(dtoPopulators).forEach(dtoPopulator -> dtoPopulator.accept(qualityGate));
QualityGateDto updatedUser = dbClient.qualityGateDao().insert(dbSession, qualityGate);
import java.util.Optional;
import java.util.function.Consumer;
import org.sonar.api.rule.Severity;
-import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
public void addUserPermission(QProfileDto profile, UserDto user){
checkArgument(!profile.isBuiltIn(), "Built-In profile cannot be used");
dbClient.qProfileEditUsersDao().insert(dbSession, new QProfileEditUsersDto()
- .setUuid(UuidFactoryFast.getInstance().create())
+ .setUuid(Uuids.createFast())
.setUserId(user.getId())
.setQProfileUuid(profile.getKee())
);
public void addGroupPermission(QProfileDto profile, GroupDto group){
checkArgument(!profile.isBuiltIn(), "Built-In profile cannot be used");
dbClient.qProfileEditGroupsDao().insert(dbSession, new QProfileEditGroupsDto()
- .setUuid(UuidFactoryFast.getInstance().create())
+ .setUuid(Uuids.createFast())
.setGroupId(group.getId())
.setQProfileUuid(profile.getKee())
);
<dataset>
- <quality_gates id="42"
+ <quality_gates id="42" uuid="1"
name="Golden" is_built_in="[true]"/>
- <quality_gates id="43"
+ <quality_gates id="43" uuid="2"
name="Ninth" is_built_in="[false]"/>
<projects organization_uuid="org1"
--- /dev/null
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class AddUuidToQualityGates extends DdlChange {
+
+ public AddUuidToQualityGates(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AddColumnsBuilder(getDialect(), "quality_gates")
+ .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder()
+ .setColumnName("uuid")
+ .setIsNullable(true)
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .build())
+ .build());
+ }
+}
*/
package org.sonar.server.platform.db.migration.version.v70;
+import java.util.UUID;
import org.sonar.server.platform.db.migration.step.MigrationStepRegistry;
import org.sonar.server.platform.db.migration.version.DbVersion;
.add(1909, "Drop index on project_measures.person_id", DropIndexOnPersonMeasures.class)
.add(1910, "Create ORG_QUALITY_GATES table", CreateOrgQualityGatesTable.class)
.add(1911, "Add ORGANIZATIONS.DEFAULT_QUALITY_GATE_UUID", AddDefaultQualityGateUuidToOrganizations.class)
+ .add(1912, "Create QUALITY_GATES.UUID", AddUuidToQualityGates.class)
+ .add(1913, "Populate QUALITY_GATES.UUID", PopulateUuidOnQualityGates.class)
+ .add(1914, "Make QUALITY_GATES.UUID not nullable", MakeUuidNotNullableOnQualityGates.class)
;
}
}
--- /dev/null
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class MakeUuidNotNullableOnQualityGates extends DdlChange {
+
+ private static final VarcharColumnDef UUID_COLUMN = VarcharColumnDef.newVarcharColumnDefBuilder()
+ .setColumnName("uuid")
+ .setIsNullable(false)
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .build();
+ private static final String TABLE_NAME = "quality_gates";
+
+ public MakeUuidNotNullableOnQualityGates(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME)
+ .updateColumn(UUID_COLUMN)
+ .build());
+
+ context.execute(new CreateIndexBuilder(getDialect())
+ .addColumn(UUID_COLUMN)
+ .setUnique(true)
+ .setTable(TABLE_NAME)
+ .setName("uniq_quality_gates_uuid")
+ .build()
+ );
+ }
+}
--- /dev/null
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.Date;
+import org.sonar.api.utils.System2;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+
+public class PopulateUuidOnQualityGates extends DataChange {
+
+ private final System2 system2;
+ private final UuidFactory uuidFactory;
+
+ public PopulateUuidOnQualityGates(Database db, System2 system2, UuidFactory uuidFactory) {
+ super(db);
+ this.system2 = system2;
+ this.uuidFactory = uuidFactory;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("select id, name from quality_gates where uuid is null");
+ massUpdate.rowPluralName("quality gates");
+ massUpdate.update("update quality_gates set uuid=?, updated_at=? where id=?");
+ massUpdate.execute((row, update) -> {
+ String name = row.getString(2);
+ update.setString(1, uuidFactory.create());
+ update.setDate(2, new Date(system2.now()));
+ update.setLong(3, row.getLong(1));
+ return true;
+ });
+ }
+
+}
--- /dev/null
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.CoreDbTester;
+
+import static java.sql.Types.VARCHAR;
+
+public class AddUuidToQualityGatesTest {
+ @Rule
+ public final CoreDbTester dbTester = CoreDbTester.createForSchema(AddUuidToQualityGatesTest.class, "quality_gates.sql");
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private AddUuidToQualityGates underTest = new AddUuidToQualityGates(dbTester.database());
+
+ @Test
+ public void column_is_added_to_table() throws SQLException {
+ underTest.execute();
+
+ dbTester.assertColumnDefinition("quality_gates", "uuid", VARCHAR, 40, true);
+ }
+
+ @Test
+ public void migration_is_not_reentrant() throws SQLException {
+ underTest.execute();
+
+ expectedException.expect(IllegalStateException.class);
+
+ underTest.execute();
+ }
+}
@Test
public void verify_migration_count() {
- verifyMigrationCount(underTest, 11);
+ verifyMigrationCount(underTest, 15);
}
}
--- /dev/null
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.CoreDbTester;
+
+import static java.sql.Types.VARCHAR;
+
+public class MakeUuidNotNullableOnQualityGatesTest {
+ @Rule
+ public final CoreDbTester dbTester = CoreDbTester.createForSchema(MakeUuidNotNullableOnQualityGatesTest.class, "quality_gates.sql");
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private MakeUuidNotNullableOnQualityGates underTest = new MakeUuidNotNullableOnQualityGates(dbTester.database());
+
+ @Test
+ public void column_is_added_to_table() throws SQLException {
+ underTest.execute();
+
+ dbTester.assertColumnDefinition("quality_gates", "uuid", VARCHAR, 40, false);
+ dbTester.assertUniqueIndex("quality_gates", "uniq_quality_gates_uuid", "uuid");
+ }
+
+ @Test
+ public void migration_is_not_reentrant() throws SQLException {
+ underTest.execute();
+
+ expectedException.expect(IllegalStateException.class);
+
+ underTest.execute();
+ }
+}
--- /dev/null
+/*
+ * 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.v70;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.assertj.core.api.AbstractListAssert;
+import org.assertj.core.groups.Tuple;
+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.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+
+import static java.util.stream.Collectors.toList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+
+public class PopulateUuidOnQualityGatesTest {
+
+ private final static long PAST = 10_000_000_000L;
+ private final static long NOW = 50_000_000_000L;
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(PopulateUuidOnQualityGatesTest.class, "quality_gates.sql");
+
+ private System2 system2 = new TestSystem2().setNow(NOW);
+
+ private PopulateUuidOnQualityGates underTest = new PopulateUuidOnQualityGates(db.database(), system2, UuidFactoryFast.getInstance());
+
+ @Test
+ public void has_no_effect_if_table_is_empty() throws SQLException {
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(0);
+ }
+
+ @Test
+ public void updates_uuid_when_uuid_is_null() throws SQLException {
+ insertQualityGate("Test 1", null);
+ insertQualityGate("Test 2", null);
+
+ underTest.execute();
+
+ List<Tuple> tuples = selectAllQualityGates("NAME", "IS_BUILT_IN", "CREATED_AT", "UPDATED_AT");
+
+ assertThat(selectAllQualityGates("NAME", "IS_BUILT_IN", "CREATED_AT", "UPDATED_AT"))
+ .containsExactlyInAnyOrder(
+ tuple("Test 1", false, new Date(PAST), new Date(NOW)),
+ tuple("Test 2", false, new Date(PAST), new Date(NOW)));
+
+ selectAllQualityGates("UUID").forEach(c -> assertThat(c).isNotNull());
+ }
+
+ @Test
+ public void does_not_update_uuid_when_uuid_is_not_null() throws SQLException {
+ insertQualityGate("Test 1", "1");
+ insertQualityGate("Test 2", "2");
+
+ underTest.execute();
+
+ assertThat(selectAllQualityGates("UUID", "NAME", "IS_BUILT_IN", "CREATED_AT", "UPDATED_AT"))
+ .containsExactlyInAnyOrder(
+ tuple("1", "Test 1", false, new Date(PAST), new Date(PAST)),
+ tuple("2", "Test 2", false, new Date(PAST), new Date(PAST)));
+ }
+
+ @Test
+ public void execute_is_reentreant() throws SQLException {
+ insertQualityGate("Test 1", null);
+ insertQualityGate("Test 2", null);
+
+ underTest.execute();
+ underTest.execute();
+
+ assertThat(selectAllQualityGates("NAME", "IS_BUILT_IN", "CREATED_AT", "UPDATED_AT"))
+ .containsExactlyInAnyOrder(
+ tuple("Test 1", false, new Date(PAST), new Date(NOW)),
+ tuple("Test 2", false, new Date(PAST), new Date(NOW)));
+
+ selectAllQualityGates("UUID").forEach(c -> assertThat(c).isNotNull());
+ }
+
+ private List<Tuple> selectAllQualityGates(String... columns) {
+ return db.select("SELECT UUID, NAME, IS_BUILT_IN, CREATED_AT, UPDATED_AT FROM QUALITY_GATES")
+ .stream()
+ .map(map -> new Tuple(Arrays.stream(columns).map(c -> map.get(c)).collect(toList()).toArray()))
+ .collect(toList());
+ }
+
+ private void insertQualityGate(String name, @Nullable String uuid) {
+ db.executeInsert(
+ "QUALITY_GATES",
+ "NAME", name,
+ "UUID", uuid,
+ "IS_BUILT_IN", false,
+ "CREATED_AT", new Date(PAST),
+ "UPDATED_AT", new Date(PAST));
+ }
+
+}
--- /dev/null
+CREATE TABLE "QUALITY_GATES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(100) NOT NULL,
+ "IS_BUILT_IN" BOOLEAN NOT NULL,
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP,
+);
+CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES" ON "QUALITY_GATES" ("NAME");
--- /dev/null
+CREATE TABLE "QUALITY_GATES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "UUID" VARCHAR(40),
+ "NAME" VARCHAR(100) NOT NULL,
+ "IS_BUILT_IN" BOOLEAN NOT NULL,
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP,
+);
+CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES" ON "QUALITY_GATES" ("NAME");
--- /dev/null
+CREATE TABLE "QUALITY_GATES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "UUID" VARCHAR(40),
+ "NAME" VARCHAR(100) NOT NULL,
+ "IS_BUILT_IN" BOOLEAN NOT NULL,
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP,
+);
+CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES" ON "QUALITY_GATES" ("NAME");
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
+import org.sonar.core.util.UuidFactory;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.property.PropertyDto;
public static final String SONAR_QUALITYGATE_PROPERTY = "sonar.qualitygate";
private final DbClient dbClient;
+ private final UuidFactory uuidFactory;
- public QualityGateUpdater(DbClient dbClient) {
+ public QualityGateUpdater(DbClient dbClient, UuidFactory uuidFactory) {
this.dbClient = dbClient;
+ this.uuidFactory = uuidFactory;
}
public QualityGateDto create(DbSession dbSession, String name) {
validateQualityGate(dbSession, null, name);
- QualityGateDto newQualityGate = new QualityGateDto().setName(name).setBuiltIn(false);
+ QualityGateDto newQualityGate = new QualityGateDto()
+ .setName(name)
+ .setBuiltIn(false)
+ .setUuid(uuidFactory.create());
dbClient.qualityGateDao().insert(dbSession, newQualityGate);
return newQualityGate;
}
import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.web.UserRole;
+import org.sonar.core.util.UuidFactory;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
private final PropertiesDao propertiesDao;
private final UserSession userSession;
private final DefaultOrganizationProvider organizationProvider;
+ private final UuidFactory uuidFactory;
- public QualityGates(DbClient dbClient, UserSession userSession, DefaultOrganizationProvider organizationProvider) {
+ public QualityGates(DbClient dbClient, UserSession userSession, DefaultOrganizationProvider organizationProvider, UuidFactory uuidFactory) {
this.dbClient = dbClient;
this.dao = dbClient.qualityGateDao();
this.conditionDao = dbClient.gateConditionDao();
this.propertiesDao = dbClient.propertiesDao();
this.userSession = userSession;
this.organizationProvider = organizationProvider;
+ this.uuidFactory = uuidFactory;
}
public QualityGateDto copy(long sourceId, String destinationName) {
getNonNullQgate(sourceId);
try (DbSession dbSession = dbClient.openSession(false)) {
validateQualityGate(dbSession, null, destinationName);
- QualityGateDto destinationGate = new QualityGateDto().setName(destinationName).setBuiltIn(false);
+ QualityGateDto destinationGate = new QualityGateDto().setName(destinationName).setBuiltIn(false).setUuid(uuidFactory.create());
dao.insert(dbSession, destinationGate);
for (QualityGateConditionDto sourceCondition : conditionDao.selectForQualityGate(dbSession, sourceId)) {
conditionDao.insert(new QualityGateConditionDto().setQualityGateId(destinationGate.getId())
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.util.UuidFactory;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
private final QualityGateUpdater qualityGateUpdater;
private final QualityGateDao qualityGateDao;
private final QualityGateConditionDao qualityGateConditionDao;
+ private final UuidFactory uuidFactory;
private final System2 system2;
public RegisterQualityGates(DbClient dbClient, QualityGateUpdater qualityGateUpdater,
- QualityGateConditionsUpdater qualityGateConditionsUpdater, QualityGateFinder qualityGateFinder, System2 system2) {
+ QualityGateConditionsUpdater qualityGateConditionsUpdater, QualityGateFinder qualityGateFinder, UuidFactory uuidFactory, System2 system2) {
this.dbClient = dbClient;
this.qualityGateConditionsUpdater = qualityGateConditionsUpdater;
this.qualityGateUpdater = qualityGateUpdater;
this.qualityGateFinder = qualityGateFinder;
this.qualityGateDao = dbClient.qualityGateDao();
this.qualityGateConditionDao = dbClient.gateConditionDao();
+ this.uuidFactory = uuidFactory;
this.system2 = system2;
}
QualityGateDto qualityGate = new QualityGateDto()
.setName(name)
.setBuiltIn(true)
+ .setUuid(uuidFactory.create())
.setCreatedAt(new Date(system2.now()));
return dbClient.qualityGateDao().insert(dbSession, qualityGate);
}
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
@Before
public void setUp() throws Exception {
- qGate = new QualityGateDto().setName("Default Quality Gate");
+ qGate = new QualityGateDto().setName("Default Quality Gate").setUuid(Uuids.createFast());
dbClient.qualityGateDao().insert(dbSession, qGate);
dbTester.commit();
}
@Test
- public void return_empty_association() throws Exception {
+ public void return_empty_association() {
Association result = underTest.find(
builder()
.gateId(Long.toString(qGate.getId()))
}
@Test
- public void return_all_projects() throws Exception {
+ public void return_all_projects() {
OrganizationDto org = dbTester.organizations().insert();
ComponentDto associatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
ComponentDto unassociatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
}
@Test
- public void return_only_associated_project() throws Exception {
+ public void return_only_associated_project() {
OrganizationDto org = dbTester.organizations().insert();
ComponentDto associatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
insertProject(ComponentTesting.newPublicProjectDto(org));
}
@Test
- public void return_only_unassociated_project() throws Exception {
+ public void return_only_unassociated_project() {
OrganizationDto org = dbTester.organizations().insert();
ComponentDto associatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
ComponentDto unassociatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
}
@Test
- public void return_only_authorized_projects() throws Exception {
+ public void return_only_authorized_projects() {
UserDto user = dbTester.users().insertUser("a_login");
OrganizationDto organizationDto = dbTester.organizations().insert();
ComponentDto project1 = componentDbTester.insertComponent(ComponentTesting.newPrivateProjectDto(organizationDto));
}
@Test
- public void do_not_verify_permissions_if_user_is_root() throws Exception {
+ public void do_not_verify_permissions_if_user_is_root() {
OrganizationDto org = dbTester.organizations().insert();
ComponentDto project = componentDbTester.insertPrivateProject(org);
ProjectQgateAssociationQuery query = builder()
}
@Test
- public void fail_on_unknown_quality_gate() throws Exception {
+ public void fail_on_unknown_quality_gate() {
expectedException.expect(NotFoundException.class);
underTest.find(builder().gateId("123").build());
}
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
- private QualityGateUpdater underTest = new QualityGateUpdater(dbClient);
+ private QualityGateUpdater underTest = new QualityGateUpdater(dbClient, UuidFactoryFast.getInstance());
@Test
- public void create_quality_gate() throws Exception {
+ public void create_quality_gate() {
QualityGateDto result = underTest.create(dbSession, QGATE_NAME);
assertThat(result).isNotNull();
}
@Test
- public void fail_to_create_when_name_is_empty() throws Exception {
+ public void fail_to_create_when_name_is_empty() {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Name can't be empty");
}
@Test
- public void fail_to_create_when_name_already_exists() throws Exception {
- dbClient.qualityGateDao().insert(dbSession, new QualityGateDto().setName(QGATE_NAME));
+ public void fail_to_create_when_name_already_exists() {
+ dbClient.qualityGateDao().insert(dbSession, new QualityGateDto().setName(QGATE_NAME).setUuid(Uuids.createFast()));
dbSession.commit();
expectedException.expect(BadRequestException.class);
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
+import org.sonar.core.util.UuidFactoryFast;
import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
when(componentDao.selectOrFailById(eq(dbSession), anyLong())).thenReturn(
newPrivateProjectDto(OrganizationTesting.newOrganizationDto(), PROJECT_UUID).setId(1L).setDbKey(PROJECT_KEY));
- underTest = new QualityGates(dbClient, userSession, organizationProvider);
+ underTest = new QualityGates(dbClient, userSession, organizationProvider, UuidFactoryFast.getInstance());
userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_GATES, organizationProvider.get().getUuid());
}
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.core.util.Uuids;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
private QualityGateConditionDao gateConditionDao = dbClient.gateConditionDao();
private MetricDao metricDao = dbClient.metricDao();
private QualityGateConditionsUpdater qualityGateConditionsUpdater = new QualityGateConditionsUpdater(dbClient);
- private QualityGateUpdater qualityGateUpdater = new QualityGateUpdater(dbClient);
+ private QualityGateUpdater qualityGateUpdater = new QualityGateUpdater(dbClient, UuidFactoryFast.getInstance());
private QualityGateFinder qualityGateFinder = new QualityGateFinder(dbClient);
- private RegisterQualityGates underTest = new RegisterQualityGates(dbClient, qualityGateUpdater, qualityGateConditionsUpdater, qualityGateFinder, System2.INSTANCE);
+ private RegisterQualityGates underTest = new RegisterQualityGates(dbClient, qualityGateUpdater, qualityGateConditionsUpdater, qualityGateFinder,
+ UuidFactoryFast.getInstance(), System2.INSTANCE);
@Before
public void setup() {
@Test
public void upgrade_empty_quality_gate() {
- QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true);
+ QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true).setUuid(Uuids.createFast());
qualityGateDao.insert(dbSession, builtin);
dbSession.commit();
@Test
public void upgrade_should_remove_deleted_condition() {
- QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true);
+ QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true).setUuid(Uuids.createFast());
qualityGateDao.insert(dbSession, builtin);
createBuiltInConditions(builtin);
@Test
public void upgrade_should_add_missing_condition() {
- QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true);
+ QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true).setUuid(Uuids.createFast());
qualityGateDao.insert(dbSession, builtin);
List<QualityGateConditionDto> builtInConditions = createBuiltInConditions(builtin);
@Test
public void should_set_SonarWay_as_builtin_when_not_set() {
- QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(false);
+ QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(false).setUuid(Uuids.createFast());
qualityGateDao.insert(dbSession, builtin);
createBuiltInConditions(builtin);
@Test
public void should_not_update_builtin_quality_gate_if_already_uptodate() {
- QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true);
+ QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true).setUuid(Uuids.createFast());
qualityGateDao.insert(dbSession, builtin);
createBuiltInConditions(builtin);
@Test
public void ensure_only_one_built_in_quality_gate() {
String qualityGateName = "IncorrectQualityGate";
- QualityGateDto builtin = new QualityGateDto().setName(qualityGateName).setBuiltIn(true);
+ QualityGateDto builtin = new QualityGateDto().setName(qualityGateName).setBuiltIn(true).setUuid(Uuids.createFast());
qualityGateDao.insert(dbSession, builtin);
dbSession.commit();
@Test
public void ensure_only_that_builtin_is_set_as_default_when_no_default_quality_gate() {
- QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true);
+ QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true).setUuid(Uuids.createFast());
qualityGateDao.insert(dbSession, builtin);
dbSession.commit();
@Test
public void builtin_quality_gate_with_incorrect_metricId_should_not_throw_an_exception() {
- QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true);
+ QualityGateDto builtin = new QualityGateDto().setName(BUILT_IN_NAME).setBuiltIn(true).setUuid(Uuids.createFast());
qualityGateDao.insert(dbSession, builtin);
QualityGateConditionDto conditionDto = new QualityGateConditionDto()
.setMetricId(-1) // This Id does not exist
import org.junit.rules.ExpectedException;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
+import org.sonar.core.util.UuidFactoryFast;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
- private CreateAction underTest = new CreateAction(dbClient, userSession, new QualityGateUpdater(dbClient), defaultOrganizationProvider);
+ private CreateAction underTest = new CreateAction(dbClient, userSession, new QualityGateUpdater(dbClient, UuidFactoryFast.getInstance()), defaultOrganizationProvider);
private WsActionTester ws = new WsActionTester(underTest);
@Test
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
private TestDefaultOrganizationProvider organizationProvider = TestDefaultOrganizationProvider.from(db);
- private QualityGates qualityGates = new QualityGates(dbClient, userSession, organizationProvider);
+ private QualityGates qualityGates = new QualityGates(dbClient, userSession, organizationProvider, UuidFactoryFast.getInstance());
private WsActionTester ws;
private ComponentDto project;
private QualityGateDto gate;
}
private QualityGateDto insertQualityGate() {
- QualityGateDto gate = new QualityGateDto().setName("Custom");
+ QualityGateDto gate = new QualityGateDto().setName("Custom").setUuid(Uuids.createFast());
dbClient.qualityGateDao().insert(dbSession, gate);
dbSession.commit();
return gate;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
}
private QualityGateDto insertQualityGate(String name) {
- QualityGateDto qualityGate = dbClient.qualityGateDao().insert(dbSession, new QualityGateDto().setName(name));
+ QualityGateDto qualityGate = dbClient.qualityGateDao().insert(dbSession, new QualityGateDto().setName(name).setUuid(Uuids.createFast()));
db.commit();
return qualityGate;
}
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
}
private QualityGateDto insertQualityGate() {
- QualityGateDto gate = new QualityGateDto().setName("Custom");
+ QualityGateDto gate = new QualityGateDto().setName("Custom").setUuid(Uuids.createFast());
dbClient.qualityGateDao().insert(dbSession, gate);
dbSession.commit();
return gate;