diff options
author | Jacek <jacek.poreda@sonarsource.com> | 2020-12-22 13:03:08 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-12-23 20:10:14 +0000 |
commit | 3f789f5fad5957680fdeb3d4c5592b61bc48df1c (patch) | |
tree | e7a2fb56e1323bf1afcace75b5a4f449535d929f /server/sonar-db-migration | |
parent | a0ee873fb078986f9794213cd844f2f73499ceda (diff) | |
download | sonarqube-3f789f5fad5957680fdeb3d4c5592b61bc48df1c.tar.gz sonarqube-3f789f5fad5957680fdeb3d4c5592b61bc48df1c.zip |
SONAR-14297 Make migration app xml->db re-entrant in case failure
Diffstat (limited to 'server/sonar-db-migration')
2 files changed, 48 insertions, 1 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v86/MigrateApplicationDefinitionsFromXmlToDb.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v86/MigrateApplicationDefinitionsFromXmlToDb.java index 62257488f0f..7dff6036a36 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v86/MigrateApplicationDefinitionsFromXmlToDb.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v86/MigrateApplicationDefinitionsFromXmlToDb.java @@ -74,6 +74,7 @@ public class MigrateApplicationDefinitionsFromXmlToDb extends DataChange { static final int TEXT_VALUE_MAX_LENGTH = 4000; private static final String SELECT_APPLICATION_UUID_BY_KEY = "select uuid from projects where kee = ? and qualifier = 'APP'"; private static final String SELECT_PROJECTS_BY_KEYS = "select kee,uuid from projects where kee in (%s) and qualifier = 'TRK'"; + private static final String SELECT_PROJECTS_BY_APP = "select project_uuid from app_projects where application_uuid = ?"; private static final String UPDATE_INTERNAL_PROP_TEXT_VALUE = "update internal_properties set text_value = ?, clob_value = NULL where kee = ?"; private static final String UPDATE_INTERNAL_PROP_CLOB_VALUE = "update internal_properties set clob_value = ?, text_value = NULL where kee = ?"; private static final String VIEWS_DEF_KEY = "views.def"; @@ -126,13 +127,19 @@ public class MigrateApplicationDefinitionsFromXmlToDb extends DataChange { return; } + List<String> alreadyAddedProjects = context.prepareSelect(SELECT_PROJECTS_BY_APP).setString(1, applicationUuid) + .list(r -> r.getString(1)); + String queryParam = projects.stream().map(uuid -> "'" + uuid + "'").collect(Collectors.joining(",")); Map<String, String> projectUuidsByKeys = context.prepareSelect(format(SELECT_PROJECTS_BY_KEYS, queryParam)) .list(r -> new AbstractMap.SimpleEntry<>(r.getString(1), r.getString(2))) .stream() + .filter(project -> !alreadyAddedProjects.contains(project.getValue())) .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); - insertApplicationProjects(context, app, applicationUuid, projectUuidsByKeys, now); + if (!projectUuidsByKeys.isEmpty()) { + insertApplicationProjects(context, app, applicationUuid, projectUuidsByKeys, now); + } if (!app.getApplicationBranches().isEmpty()) { insertApplicationBranchesProjects(context, app, applicationUuid, projectUuidsByKeys, now); } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v86/MigrateApplicationDefinitionsFromXmlToDbTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v86/MigrateApplicationDefinitionsFromXmlToDbTest.java index 856943d0644..04d30fd5478 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v86/MigrateApplicationDefinitionsFromXmlToDbTest.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v86/MigrateApplicationDefinitionsFromXmlToDbTest.java @@ -434,6 +434,41 @@ public class MigrateApplicationDefinitionsFromXmlToDbTest { } @Test + public void migration_is_resilient() throws SQLException { + setupProjectsAndApps(); + insertViewsDefInternalProperty(COMPLEX_XML_BEFORE); + + // first attempt + underTest.execute(); + + // xml stays the same (stopped during migration) + updateViewsDefInternalProperty(COMPLEX_XML_BEFORE); + + // second attempt should not fail + underTest.execute(); + + assertThat(db.select("select uuid from projects")) + .extracting(r -> r.get("UUID")) + .containsExactlyInAnyOrder(PROJECT_1_UUID, PROJECT_2_UUID, APP_1_UUID, APP_2_UUID); + assertThat(db.select("select application_uuid, project_uuid from app_projects")) + .extracting(r -> r.get("APPLICATION_UUID"), r -> r.get("PROJECT_UUID")) + .containsExactlyInAnyOrder( + tuple(APP_1_UUID, PROJECT_1_UUID), + tuple(APP_1_UUID, PROJECT_2_UUID), + tuple(APP_2_UUID, PROJECT_1_UUID), + tuple(APP_2_UUID, PROJECT_2_UUID)); + assertThat(db.select("select application_uuid, project_uuid, application_branch_uuid, project_branch_uuid from app_branch_project_branch")) + .extracting(r -> r.get("APPLICATION_UUID"), r -> r.get("PROJECT_UUID"), r -> r.get("APPLICATION_BRANCH_UUID"), r -> r.get("PROJECT_BRANCH_UUID")) + .containsExactlyInAnyOrder( + tuple(APP_1_UUID, PROJECT_1_UUID, APP_1_BRANCH_1_UUID, PROJECT_1_BRANCH_1_UUID), + tuple(APP_1_UUID, PROJECT_2_UUID, APP_1_BRANCH_1_UUID, PROJECT_2_BRANCH_1_UUID), + tuple(APP_1_UUID, PROJECT_1_UUID, APP_1_BRANCH_2_UUID, PROJECT_1_BRANCH_2_UUID), + tuple(APP_1_UUID, PROJECT_2_UUID, APP_1_BRANCH_2_UUID, PROJECT_2_BRANCH_1_UUID), + tuple(APP_2_UUID, PROJECT_1_UUID, APP_2_BRANCH_1_UUID, PROJECT_1_BRANCH_1_UUID), + tuple(APP_2_UUID, PROJECT_2_UUID, APP_2_BRANCH_1_UUID, PROJECT_2_BRANCH_1_UUID)); + } + + @Test public void migrates_applications_without_application_branches_to_new_tables() throws SQLException { setupFullProject1(); setupProject2(); @@ -681,6 +716,11 @@ public class MigrateApplicationDefinitionsFromXmlToDbTest { "created_at", system2.now()); } + private void updateViewsDefInternalProperty(@Nullable String xml) { + db.executeUpdateSql("update internal_properties set text_value = ? where kee = 'views.def'", + xml); + } + private void insertProject(String uuid, String key, String qualifier) { db.executeInsert("PROJECTS", "UUID", uuid, |