diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-10-12 23:08:47 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-10-13 12:18:42 +0200 |
commit | 5975e1771500cef122160c35a648cd712b60a252 (patch) | |
tree | 6d3ba4074f10ab861a0fd8a4a8351040811d96c7 | |
parent | 1a169ae32047cf9da7bb43bfc7ce1765faebd3fc (diff) | |
download | sonarqube-5975e1771500cef122160c35a648cd712b60a252.tar.gz sonarqube-5975e1771500cef122160c35a648cd712b60a252.zip |
SONAR-8134 populate column group_roles.organization_uuid on upgrade
8 files changed, 193 insertions, 3 deletions
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1416_populate_organization_uuid_of_group_roles.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1416_populate_organization_uuid_of_group_roles.rb new file mode 100644 index 00000000000..a1b164fdd6c --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/1416_populate_organization_uuid_of_group_roles.rb @@ -0,0 +1,29 @@ +# +# SonarQube, open source software quality management tool. +# Copyright (C) 2008-2014 SonarSource +# mailto:contact AT sonarsource DOT com +# +# SonarQube 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. +# +# SonarQube 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. +# + +# +# SonarQube 6.2 +# +class PopulateOrganizationUuidOfGroupRoles < ActiveRecord::Migration + + def self.up + execute_java_migration('org.sonar.db.version.v62.PopulateOrganizationUuidOfGroupRoles') + end +end diff --git a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java index 098c8257c1e..a4bae4dded0 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java +++ b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java @@ -30,7 +30,7 @@ import org.sonar.db.MyBatis; public class DatabaseVersion { - public static final int LAST_VERSION = 1_415; + public static final int LAST_VERSION = 1_416; /** * The minimum supported version which can be upgraded. Lower diff --git a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java b/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java index 19ca38b34cf..615d7bd3b46 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java +++ b/sonar-db/src/main/java/org/sonar/db/version/MigrationStepModule.java @@ -172,6 +172,7 @@ import org.sonar.db.version.v62.MakeOrganizationUuidNotNullOnPermissionTemplates import org.sonar.db.version.v62.MakeOrganizationUuidNotNullOnUserRoles; import org.sonar.db.version.v62.MakeRootColumnNotNullOnTableUsers; import org.sonar.db.version.v62.PopulateIsRootColumnOnTableUsers; +import org.sonar.db.version.v62.PopulateOrganizationUuidOfGroupRoles; import org.sonar.db.version.v62.PopulateOrganizationUuidOfGroups; import org.sonar.db.version.v62.PopulateOrganizationUuidOfPermissionTemplates; import org.sonar.db.version.v62.PopulateOrganizationUuidOfUserRoles; @@ -370,7 +371,8 @@ public class MigrationStepModule extends Module { MakeOrganizationUuidNotNullOnUserRoles.class, PopulateOrganizationUuidOfPermissionTemplates.class, MakeOrganizationUuidNotNullOnPermissionTemplates.class, - AddOrganizationUuidToGroupRoles.class + AddOrganizationUuidToGroupRoles.class, + PopulateOrganizationUuidOfGroupRoles.class ); } } diff --git a/sonar-db/src/main/java/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRoles.java b/sonar-db/src/main/java/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRoles.java new file mode 100644 index 00000000000..05310620a30 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRoles.java @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.version.v62; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.version.BaseDataChange; +import org.sonar.db.version.MassUpdate; +import org.sonar.db.version.Select; + +import static com.google.common.base.Preconditions.checkState; + +public class PopulateOrganizationUuidOfGroupRoles extends BaseDataChange { + + private static final String INTERNAL_PROPERTY_DEFAULT_ORGANIZATION = "organization.default"; + + public PopulateOrganizationUuidOfGroupRoles(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + String organizationUuid = selectDefaultOrganizationUuid(context); + + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id from group_roles where organization_uuid is null"); + massUpdate.update("update group_roles set organization_uuid=? where id=?"); + massUpdate.rowPluralName("group_roles"); + massUpdate.execute((row, update) -> { + long id = row.getLong(1); + update.setString(1, organizationUuid); + update.setLong(2, id); + return true; + }); + } + + private static String selectDefaultOrganizationUuid(Context context) throws SQLException { + Select select = context.prepareSelect("select text_value from internal_properties where kee=?"); + select.setString(1, INTERNAL_PROPERTY_DEFAULT_ORGANIZATION); + String uuid = select.get(row -> row.getString(1)); + checkState(uuid != null, "Default organization uuid is missing"); + return uuid; + } +} diff --git a/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql b/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql index 86b85a6774e..2ec82e2deda 100644 --- a/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql +++ b/sonar-db/src/main/resources/org/sonar/db/version/rows-h2.sql @@ -504,6 +504,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1412'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1413'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1414'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1415'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1416'); INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, USER_LOCAL, CRYPTED_PASSWORD, SALT, IS_ROOT, CREATED_AT, UPDATED_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', true, 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', true, '1418215735482', '1418215735482'); ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2; diff --git a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java index acee005f4f7..5b3fffa9631 100644 --- a/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java +++ b/sonar-db/src/test/java/org/sonar/db/version/MigrationStepModuleTest.java @@ -29,6 +29,6 @@ public class MigrationStepModuleTest { public void verify_count_of_added_MigrationStep_types() { ComponentContainer container = new ComponentContainer(); new MigrationStepModule().configure(container); - assertThat(container.size()).isEqualTo(157); + assertThat(container.size()).isEqualTo(158); } } diff --git a/sonar-db/src/test/java/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRolesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRolesTest.java new file mode 100644 index 00000000000..a045faeb6a7 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRolesTest.java @@ -0,0 +1,76 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.version.v62; + +import java.sql.SQLException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; + +import static org.assertj.core.api.Assertions.assertThat; + +public class PopulateOrganizationUuidOfGroupRolesTest { + + private static final String TABLE_GROUP_ROLES = "group_roles"; + private static final String AN_ORG_UUID = "org1"; + + @Rule + public DbTester dbTester = DbTester.createForSchema(System2.INSTANCE, PopulateOrganizationUuidOfGroupRolesTest.class, "group_roles.sql"); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private PopulateOrganizationUuidOfGroupRoles underTest = new PopulateOrganizationUuidOfGroupRoles(dbTester.database()); + + @Test + public void execute_fails_with_ISE_if_default_organization_internal_property_is_not_set() throws SQLException { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Default organization uuid is missing"); + + underTest.execute(); + } + @Test + public void migration_populates_missing_organization_uuids() throws SQLException { + dbTester.executeInsert("group_roles", "group_id", "1", "role", "admin", "organization_uuid", null); + dbTester.executeInsert("group_roles", "group_id", "2", "role", "viewever", "organization_uuid", null); + dbTester.executeInsert("group_roles", "group_id", "3", "role", "viewever", "organization_uuid", AN_ORG_UUID); + insertDefaultOrganizationInternalProperty(AN_ORG_UUID); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable(TABLE_GROUP_ROLES)).isEqualTo(3); + assertThat(dbTester.countSql("select count(1) from group_roles where organization_uuid='" + AN_ORG_UUID + "'")).isEqualTo(3); + } + + @Test + public void migration_has_no_effect_on_empty_table() throws SQLException { + insertDefaultOrganizationInternalProperty(AN_ORG_UUID); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable(TABLE_GROUP_ROLES)).isEqualTo(0); + } + + private void insertDefaultOrganizationInternalProperty(String defaultOrganizationUuid) { + dbTester.executeInsert("internal_properties", "kee", "organization.default", "is_empty", false, "text_value", defaultOrganizationUuid); + } +} diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRolesTest/group_roles.sql b/sonar-db/src/test/resources/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRolesTest/group_roles.sql new file mode 100644 index 00000000000..775ab11911e --- /dev/null +++ b/sonar-db/src/test/resources/org/sonar/db/version/v62/PopulateOrganizationUuidOfGroupRolesTest/group_roles.sql @@ -0,0 +1,21 @@ +CREATE TABLE "GROUP_ROLES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "ORGANIZATION_UUID" VARCHAR(40), + "GROUP_ID" INTEGER, + "RESOURCE_ID" INTEGER, + "ROLE" VARCHAR(64) NOT NULL +); + +CREATE INDEX "GROUP_ROLES_RESOURCE" ON "GROUP_ROLES" ("RESOURCE_ID"); + +CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES" ("GROUP_ID", "RESOURCE_ID", "ROLE"); + +CREATE TABLE "INTERNAL_PROPERTIES" ( + "KEE" VARCHAR(50) NOT NULL PRIMARY KEY, + "IS_EMPTY" BOOLEAN NOT NULL, + "TEXT_VALUE" VARCHAR(4000), + "CLOB_VALUE" CLOB, + "CREATED_AT" BIGINT +); + +CREATE UNIQUE INDEX "UNIQ_INTERNAL_PROPERTIES" ON "INTERNAL_PROPERTIES" ("KEE"); |