From 99542044a382aa87d682f3544e9004b0d2a559d1 Mon Sep 17 00:00:00 2001 From: Pierre Date: Thu, 12 Aug 2021 14:47:56 +0200 Subject: [PATCH] SONAR-15142 add 'name' and 'key' in component context for Audit --- .../db/audit/model/ComponentNewValue.java | 17 ++--- .../org/sonar/db/component/ComponentDao.java | 2 +- .../java/org/sonar/db/project/ProjectDao.java | 4 +- .../java/org/sonar/db/purge/PurgeDao.java | 4 +- .../db/audit/model/ComponentNewValueTest.java | 20 +++++ .../java/org/sonar/db/purge/PurgeDaoTest.java | 76 ++++++++----------- .../sonar/db/purge/PurgeDaoWithAuditTest.java | 69 +++++++++++++++++ .../component/index/ComponentIndexerTest.java | 3 +- .../index/ProjectMeasuresIndexerTest.java | 2 +- .../index/PermissionIndexerTest.java | 25 +++++- .../component/ComponentCleanerService.java | 6 +- .../component/ws/SuggestionsActionTest.java | 2 +- 12 files changed, 159 insertions(+), 71 deletions(-) create mode 100644 server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoWithAuditTest.java diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ComponentNewValue.java b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ComponentNewValue.java index c9fdc9c52df..4de0e110055 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ComponentNewValue.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ComponentNewValue.java @@ -40,15 +40,10 @@ public class ComponentNewValue implements NewValue { private Boolean isEnabled; private String prefix; - - public ComponentNewValue(String componentUuid, String qualifier) { - this.componentUuid = componentUuid; - this.generateComponentPrefix(qualifier); - } - - public ComponentNewValue(String componentUuid, String name, String qualifier) { + public ComponentNewValue(String componentUuid, String name, String key, @Nullable String qualifier) { this.componentUuid = componentUuid; this.componentName = name; + this.key = key; this.generateComponentPrefix(qualifier); } @@ -58,7 +53,6 @@ public class ComponentNewValue implements NewValue { this.generateComponentPrefix(qualifier); } - public ComponentNewValue(String componentUuid, String name, boolean isPrivate, String qualifier) { this.componentUuid = componentUuid; this.componentName = name; @@ -66,7 +60,7 @@ public class ComponentNewValue implements NewValue { this.generateComponentPrefix(qualifier); } - public ComponentNewValue(String uuid, String name, String key, boolean enabled, String path, String qualifier) { + public ComponentNewValue(String uuid, String name, String key, boolean enabled, String path, @Nullable String qualifier) { this.componentUuid = uuid; this.componentName = name; this.isEnabled = enabled; @@ -75,10 +69,11 @@ public class ComponentNewValue implements NewValue { this.generateComponentPrefix(qualifier); } - public ComponentNewValue(String uuid, boolean isPrivate, String name, @Nullable String description, String qualifier) { + public ComponentNewValue(String uuid, boolean isPrivate, String name, String key, @Nullable String description, @Nullable String qualifier) { this.componentUuid = uuid; this.isPrivate = isPrivate; this.componentName = name; + this.key = key; this.description = description; this.generateComponentPrefix(qualifier); } @@ -132,7 +127,7 @@ public class ComponentNewValue implements NewValue { addField(sb, "\"rootComponentUuid\": ", this.rootComponentUuid, true); addField(sb, "\"" + this.prefix + "Name\": ", this.componentName, true); addField(sb, "\"description\": ", this.description, true); - addField(sb, "\"oldKey\": ", this.key, true); + addField(sb, "\"key\": ", this.key, true); addField(sb, "\"path\": ", this.path, true); addField(sb, "\"isPrivate\": ", ObjectUtils.toString(this.isPrivate), false); addField(sb, "\"isEnabled\": ", ObjectUtils.toString(this.isEnabled), false); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java index d6a758b551f..33418b8aa86 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java @@ -339,7 +339,7 @@ public class ComponentDao implements Dao { public void insert(DbSession session, ComponentDto item) { if (auditPersister != null) { - auditPersister.addComponent(session, new ComponentNewValue(item.uuid(), item.name(), item.qualifier()), item.qualifier()); + auditPersister.addComponent(session, new ComponentNewValue(item.uuid(), item.name(), item.getKey(), item.qualifier()), item.qualifier()); } mapper(session).insert(item); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java index b7fe807410c..189d8348469 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java @@ -48,7 +48,7 @@ public class ProjectDao implements Dao { public void insert(DbSession session, ProjectDto project, boolean track) { if (track && auditPersister != null) { - auditPersister.addComponent(session, new ComponentNewValue(project.getUuid(), project.getName(), project.getQualifier()), + auditPersister.addComponent(session, new ComponentNewValue(project.getUuid(), project.getName(), project.getKey(), project.getQualifier()), project.getQualifier()); } mapper(session).insert(project); @@ -117,7 +117,7 @@ public class ProjectDao implements Dao { public void update(DbSession session, ProjectDto project) { if (auditPersister != null) { auditPersister.updateComponent(session, new ComponentNewValue(project.getUuid(), project.isPrivate(), - project.getName(), project.getDescription(), project.getQualifier()), project.getQualifier()); + project.getName(), project.getKey(), project.getDescription(), project.getQualifier()), project.getQualifier()); } mapper(session).update(project); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java index 6a02b221547..cf36fb63216 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -188,7 +188,7 @@ public class PurgeDao implements Dao { deleteRootComponent(uuid, purgeMapper, purgeCommands); } - public void deleteProject(DbSession session, String uuid, String qualifier) { + public void deleteProject(DbSession session, String uuid, String qualifier, String name, String key) { PurgeProfiler profiler = new PurgeProfiler(); PurgeMapper purgeMapper = mapper(session); PurgeCommands purgeCommands = new PurgeCommands(session, profiler, system2); @@ -205,7 +205,7 @@ public class PurgeDao implements Dao { deleteRootComponent(uuid, purgeMapper, purgeCommands); if (auditPersister != null) { - auditPersister.deleteComponent(session, new ComponentNewValue(uuid, qualifier), qualifier); + auditPersister.deleteComponent(session, new ComponentNewValue(uuid, name, key, qualifier), qualifier); } logProfiling(profiler, start); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ComponentNewValueTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ComponentNewValueTest.java index fd86977875a..79b82bca00f 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ComponentNewValueTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ComponentNewValueTest.java @@ -53,6 +53,26 @@ public class ComponentNewValueTest { assertThat(newValue.toString()).contains("\"isPrivate\": true"); } + @Test + public void toString_project_uuid_and_name_and_key() { + ComponentNewValue newValue = new ComponentNewValue("uuid", "name", "key", "TRK"); + + assertThat(newValue.toString()).contains("\"projectUuid\": \"uuid\""); + assertThat(newValue.toString()).contains("\"projectName\": \"name\""); + assertThat(newValue.toString()).contains("\"key\": \"key\""); + } + + @Test + public void toString_project_uuid_and_name_and_key_and_isPrivate_and_description() { + ComponentNewValue newValue = new ComponentNewValue("uuid", true, "name", "key", "description", "TRK"); + + assertThat(newValue.toString()).contains("\"projectUuid\": \"uuid\""); + assertThat(newValue.toString()).contains("\"projectName\": \"name\""); + assertThat(newValue.toString()).contains("\"isPrivate\": true"); + assertThat(newValue.toString()).contains("\"key\": \"key\""); + assertThat(newValue.toString()).contains("\"description\": \"description\""); + } + @Test public void toString_addsProjectPrefix() { ComponentNewValue newValue = new ComponentNewValue("uuid", "name", "key", true, "path", "TRK"); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java index 1bf68c0ac00..efa49b31960 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java @@ -49,8 +49,6 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.alm.setting.AlmSettingDto; -import org.sonar.db.audit.AuditPersister; -import org.sonar.db.audit.model.ComponentNewValue; import org.sonar.db.ce.CeActivityDto; import org.sonar.db.ce.CeQueueDto; import org.sonar.db.ce.CeQueueDto.Status; @@ -92,7 +90,6 @@ import static java.util.Collections.singletonList; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; @@ -124,9 +121,7 @@ public class PurgeDaoTest { private final DbClient dbClient = db.getDbClient(); private final DbSession dbSession = db.getSession(); - private final AuditPersister auditPersister = mock(AuditPersister.class); private final PurgeDao underTest = db.getDbClient().purgeDao(); - private final PurgeDao underTestWithPersister = new PurgeDao(system2, auditPersister); @Test public void purge_failed_ce_tasks() { @@ -545,7 +540,7 @@ public class PurgeDaoTest { IssueDto otherIssue2 = db.issues().insert(rule, otherProject, otherFile); FileSourceDto otherFileSource = db.fileSources().insertFileSource(otherFile); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("components")).containsOnly(otherProject.uuid(), otherModule.uuid(), otherDirectory.uuid(), otherFile.uuid()); @@ -556,15 +551,6 @@ public class PurgeDaoTest { assertThat(uuidsIn("file_sources", "file_uuid")).containsOnly(otherFileSource.getFileUuid()); } - @Test - public void delete_project_and_persist() { - ComponentDto project = db.components().insertPrivateProject(); - - underTestWithPersister.deleteProject(dbSession, project.uuid(), project.qualifier()); - - verify(auditPersister).deleteComponent(any(DbSession.class), any(ComponentNewValue.class), anyString()); - } - @Test public void delete_application() { MetricDto metric = db.measures().insertMetric(); @@ -592,7 +578,7 @@ public class PurgeDaoTest { db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, appBranch.uuid()).get(), projectBranch); db.components().addProjectBranchToApplicationBranch(dbClient.branchDao().selectByUuid(dbSession, otherAppBranch.uuid()).get(), projectBranch); - underTest.deleteProject(dbSession, app.uuid(), app.qualifier()); + underTest.deleteProject(dbSession, app.uuid(), app.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("components")).containsOnly(project.uuid(), otherApp.uuid(), otherAppBranch.uuid()); @@ -657,7 +643,7 @@ public class PurgeDaoTest { WebhookDto webhookNotDeleted = db.webhooks().insertWebhook(projectNotToBeDeleted); WebhookDeliveryLiteDto webhookDeliveryNotDeleted = db.webhookDelivery().insert(webhookNotDeleted); - underTest.deleteProject(dbSession, project1.getUuid(), project1.getQualifier()); + underTest.deleteProject(dbSession, project1.getUuid(), project1.getQualifier(), project1.getName(), project1.getKey()); assertThat(uuidsIn("webhooks")).containsOnly(webhookNotDeleted.getUuid()); assertThat(uuidsIn("webhook_deliveries")).containsOnly(webhookDeliveryNotDeleted.getUuid()); @@ -680,7 +666,7 @@ public class PurgeDaoTest { CeActivityDto notDeletedActivity = insertCeActivity(anotherLivingProject); dbSession.commit(); - underTest.deleteProject(dbSession, projectToBeDeleted.uuid(), projectToBeDeleted.qualifier()); + underTest.deleteProject(dbSession, projectToBeDeleted.uuid(), projectToBeDeleted.qualifier(), projectToBeDeleted.name(), projectToBeDeleted.getKey()); dbSession.commit(); assertThat(uuidsOfTable("ce_activity")) @@ -707,13 +693,13 @@ public class PurgeDaoTest { insertCeTaskInput("non existing task"); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid()); assertThat(taskUuidsIn("ce_task_input")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid()); @@ -739,13 +725,13 @@ public class PurgeDaoTest { insertCeScannerContext("non existing task"); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid()); assertThat(taskUuidsIn("ce_scanner_context")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid()); @@ -771,13 +757,13 @@ public class PurgeDaoTest { insertCeTaskCharacteristics("non existing task", 5); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid()); assertThat(taskUuidsIn("ce_task_characteristics")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid()); @@ -803,13 +789,13 @@ public class PurgeDaoTest { insertCeTaskMessages("non existing task", 5); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid()); assertThat(taskUuidsIn("ce_task_message")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid()); @@ -829,7 +815,7 @@ public class PurgeDaoTest { assertThat(uuidsIn("user_dismissed_messages")).containsOnly(msg1.getUuid(), msg2.getUuid(), msg3.getUuid()); - underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier()); + underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("user_dismissed_messages")).containsOnly(msg3.getUuid()); @@ -847,7 +833,7 @@ public class PurgeDaoTest { dbClient.ceQueueDao().insert(dbSession, createCeQueue(anotherLivingProject, Status.PENDING)); dbSession.commit(); - underTest.deleteProject(dbSession, projectToBeDeleted.uuid(), projectToBeDeleted.qualifier()); + underTest.deleteProject(dbSession, projectToBeDeleted.uuid(), projectToBeDeleted.qualifier(), projectToBeDeleted.name(), projectToBeDeleted.getKey()); dbSession.commit(); assertThat(db.countRowsOfTable("ce_queue")).isEqualTo(1); @@ -873,13 +859,13 @@ public class PurgeDaoTest { insertCeTaskInput("non existing task"); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid()); assertThat(taskUuidsIn("ce_task_input")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid()); @@ -905,14 +891,14 @@ public class PurgeDaoTest { insertCeScannerContext("non existing task"); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid()); assertThat(taskUuidsIn("ce_scanner_context")) .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid()); @@ -938,14 +924,14 @@ public class PurgeDaoTest { insertCeTaskCharacteristics("non existing task", 5); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid()); assertThat(taskUuidsIn("ce_task_characteristics")) .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid()); @@ -971,14 +957,14 @@ public class PurgeDaoTest { insertCeTaskMessages("non existing task", 5); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid()); assertThat(taskUuidsIn("ce_task_message")) .containsOnly(projectTask.getUuid(), anotherBranchTask.getUuid(), anotherProjectTask.getUuid(), "non existing task"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid()); @@ -1019,14 +1005,14 @@ public class PurgeDaoTest { db.events().insertEventComponentChanges(anotherProjectEvent, anotherProjectAnalysis, randomChangeCategory(), referencedProjectB, null); // deleting referenced project does not delete any data - underTest.deleteProject(dbSession, referencedProjectA.uuid(), referencedProjectA.qualifier()); + underTest.deleteProject(dbSession, referencedProjectA.uuid(), referencedProjectA.qualifier(), project.name(), project.getKey()); assertThat(db.countRowsOfTable("event_component_changes")) .isEqualTo(7); assertThat(db.countRowsOfTable("events")) .isEqualTo(7); - underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier(), project.name(), project.getKey()); assertThat(uuidsIn("event_component_changes", "event_component_uuid")) .containsOnly(project.uuid(), anotherBranch.uuid(), anotherProject.uuid()); assertThat(db.countRowsOfTable("event_component_changes")) @@ -1034,7 +1020,7 @@ public class PurgeDaoTest { assertThat(uuidsIn("events")) .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid(), anotherBranchEvent.getUuid(), anotherProjectEvent.getUuid()); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); assertThat(uuidsIn("event_component_changes", "event_component_uuid")) .containsOnly(anotherBranch.uuid(), anotherProject.uuid()); assertThat(db.countRowsOfTable("event_component_changes")) @@ -1082,7 +1068,7 @@ public class PurgeDaoTest { assertThat(db.countRowsOfTable("issues")).isGreaterThan(issueCount); assertThat(db.countRowsOfTable("project_branches")).isGreaterThan(branchCount); - underTest.deleteProject(dbSession, projectToDelete.uuid(), projectToDelete.qualifier()); + underTest.deleteProject(dbSession, projectToDelete.uuid(), projectToDelete.qualifier(), projectToDelete.name(), projectToDelete.getKey()); dbSession.commit(); assertThat(db.countRowsOfTable("components")).isEqualTo(projectEntryCount); @@ -1101,7 +1087,7 @@ public class PurgeDaoTest { ComponentDto otherSubView = db.components().insertComponent(newSubPortfolio(otherView)); ComponentDto otherProjectCopy = db.components().insertComponent(newProjectCopy(project, otherSubView)); - underTest.deleteProject(dbSession, view.uuid(), view.qualifier()); + underTest.deleteProject(dbSession, view.uuid(), view.qualifier(), project.name(), project.getKey()); dbSession.commit(); assertThat(uuidsIn("components")) @@ -1353,7 +1339,7 @@ public class PurgeDaoTest { dbClient.webhookDeliveryDao().insert(dbSession, newDto().setComponentUuid(project.uuid()).setUuid("D1").setDurationMs(1000).setWebhookUuid("webhook-uuid")); dbClient.webhookDeliveryDao().insert(dbSession, newDto().setComponentUuid("P2").setUuid("D2").setDurationMs(1000).setWebhookUuid("webhook-uuid")); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); assertThat(selectAllDeliveryUuids(db, dbSession)).containsOnly("D2"); } @@ -1364,7 +1350,7 @@ public class PurgeDaoTest { dbClient.projectMappingsDao().put(dbSession, "a.key.type", "a.key", project.uuid()); dbClient.projectMappingsDao().put(dbSession, "a.key.type", "another.key", "D2"); - underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); assertThat(dbClient.projectMappingsDao().get(dbSession, "a.key.type", "a.key")).isEmpty(); assertThat(dbClient.projectMappingsDao().get(dbSession, "a.key.type", "another.key")).isNotEmpty(); @@ -1378,7 +1364,7 @@ public class PurgeDaoTest { db.almSettings().insertGitlabProjectAlmSetting(almSettingDto, project); db.almSettings().insertGitlabProjectAlmSetting(almSettingDto, otherProject); - underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier()); + underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey()); assertThat(dbClient.projectAlmSettingDao().selectByProject(dbSession, project)).isEmpty(); assertThat(dbClient.projectAlmSettingDao().selectByProject(dbSession, otherProject)).isNotEmpty(); @@ -1417,7 +1403,7 @@ public class PurgeDaoTest { db.measures().insertLiveMeasure(project2, metric); db.measures().insertLiveMeasure(module2, metric); - underTest.deleteProject(dbSession, project1.uuid(), project1.qualifier()); + underTest.deleteProject(dbSession, project1.uuid(), project1.qualifier(), project1.name(), project1.getKey()); assertThat(dbClient.liveMeasureDao().selectByComponentUuidsAndMetricUuids(dbSession, asList(project1.uuid(), module1.uuid()), asList(metric.getUuid()))).isEmpty(); assertThat(dbClient.liveMeasureDao().selectByComponentUuidsAndMetricUuids(dbSession, asList(project2.uuid(), module2.uuid()), asList(metric.getUuid()))).hasSize(2); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoWithAuditTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoWithAuditTest.java new file mode 100644 index 00000000000..4e7344ee683 --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoWithAuditTest.java @@ -0,0 +1,69 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 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.purge; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.junit.MockitoJUnitRunner; +import org.sonar.api.utils.System2; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.audit.AuditPersister; +import org.sonar.db.audit.model.ComponentNewValue; +import org.sonar.db.component.ComponentDto; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class PurgeDaoWithAuditTest { + + private final System2 system2 = mock(System2.class); + + @Rule + public DbTester db = DbTester.create(system2); + + @Captor + ArgumentCaptor newValueCaptor; + + private final DbSession dbSession = db.getSession(); + private final AuditPersister auditPersister = mock(AuditPersister.class); + private final PurgeDao underTestWithPersister = new PurgeDao(system2, auditPersister); + + @Test + public void delete_project_persist_audit_with_uuid_and_name() { + ComponentDto project = db.components().insertPrivateProject(); + + underTestWithPersister.deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); + + verify(auditPersister).deleteComponent(any(DbSession.class), newValueCaptor.capture(), eq(project.qualifier())); + ComponentNewValue componentNewValue = newValueCaptor.getValue(); + assertThat(componentNewValue) + .extracting(ComponentNewValue::getComponentUuid, ComponentNewValue::getComponentName, ComponentNewValue::getKey) + .containsExactly(project.uuid(), project.name(), project.getKey()); + } + +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java index d973d4ecabc..0ff178eb394 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/component/index/ComponentIndexerTest.java @@ -23,7 +23,6 @@ import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.resources.Qualifiers; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -208,7 +207,7 @@ public class ComponentIndexerTest { indexProject(project, PROJECT_CREATION); assertThatIndexHasSize(1); - db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), PROJECT); + db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), PROJECT, project.name(), project.getKey()); indexProject(project, PROJECT_DELETION); assertThatIndexHasSize(0); diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexerTest.java index ad817103a70..d0c7bb9f620 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexerTest.java @@ -235,7 +235,7 @@ public class ProjectMeasuresIndexerTest { indexProject(project, PROJECT_CREATION); assertThatIndexContainsOnly(project); - db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), Qualifiers.PROJECT); + db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), Qualifiers.PROJECT, project.name(), project.getKey()); IndexingResult result = indexProject(project, PROJECT_DELETION); assertThat(es.countDocuments(TYPE_PROJECT_MEASURES)).isZero(); diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java index 4c9eaacef72..20fb3bf8fb9 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java @@ -19,10 +19,10 @@ */ package org.sonar.server.permission.index; +import java.util.Collection; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.resources.Qualifiers; import org.sonar.api.utils.System2; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -45,7 +45,6 @@ import static org.sonar.api.web.UserRole.ADMIN; import static org.sonar.api.web.UserRole.USER; import static org.sonar.server.es.ProjectIndexer.Cause.PERMISSION_CHANGE; import static org.sonar.server.permission.index.IndexAuthorizationConstants.TYPE_AUTHORIZATION; -import java.util.Collection; public class PermissionIndexerTest { @@ -90,6 +89,26 @@ public class PermissionIndexerTest { verifyAuthorized(project, user2); } + @Test + public void deletion_resilience_will_deindex_projects() { + ComponentDto project1 = createUnindexedPublicProject(); + ComponentDto project2 = createUnindexedPublicProject(); + // UserDto user1 = db.users().insertUser(); + indexOnStartup(); + assertThat(es.countDocuments(INDEX_TYPE_FOO_AUTH)).isEqualTo(2); + + // Simulate a indexation issue + db.getDbClient().purgeDao().deleteProject(db.getSession(), project1.uuid(), PROJECT, project1.name(), project1.getKey()); + underTest.prepareForRecovery(db.getSession(), asList(project1.uuid()), ProjectIndexer.Cause.PROJECT_DELETION); + assertThat(db.countRowsOfTable(db.getSession(), "es_queue")).isEqualTo(1); + Collection esQueueDtos = db.getDbClient().esQueueDao().selectForRecovery(db.getSession(), Long.MAX_VALUE, 2); + + underTest.index(db.getSession(), esQueueDtos); + + assertThat(db.countRowsOfTable(db.getSession(), "es_queue")).isZero(); + assertThat(es.countDocuments(INDEX_TYPE_FOO_AUTH)).isEqualTo(1); + } + @Test public void indexOnStartup_grants_access_to_user() { ComponentDto project = createAndIndexPrivateProject(); @@ -295,7 +314,7 @@ public class PermissionIndexerTest { indexPermissions(project, ProjectIndexer.Cause.PROJECT_CREATION); verifyAuthorized(project, user); - db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), PROJECT); + db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), PROJECT, project.name(), project.getKey()); indexPermissions(project, ProjectIndexer.Cause.PROJECT_DELETION); verifyNotAuthorized(project, user); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentCleanerService.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentCleanerService.java index 669e360f4d1..3e26ecd902b 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentCleanerService.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentCleanerService.java @@ -66,20 +66,20 @@ public class ComponentCleanerService { } public void delete(DbSession dbSession, ProjectDto project) { - dbClient.purgeDao().deleteProject(dbSession, project.getUuid(), project.getQualifier()); + dbClient.purgeDao().deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey()); dbClient.userDao().cleanHomepage(dbSession, project); projectIndexers.commitAndIndexProjects(dbSession, singletonList(project), PROJECT_DELETION); } public void deleteApplication(DbSession dbSession, ProjectDto application) { - dbClient.purgeDao().deleteProject(dbSession, application.getUuid(), application.getQualifier()); + dbClient.purgeDao().deleteProject(dbSession, application.getUuid(), application.getQualifier(), application.getName(), application.getKey()); dbClient.userDao().cleanHomepage(dbSession, application); projectIndexers.commitAndIndexProjects(dbSession, singletonList(application), PROJECT_DELETION); } public void delete(DbSession dbSession, ComponentDto project) { checkArgument(!hasNotProjectScope(project) && !isNotDeletable(project) && project.getMainBranchProjectUuid() == null, "Only projects can be deleted"); - dbClient.purgeDao().deleteProject(dbSession, project.uuid(), project.qualifier()); + dbClient.purgeDao().deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey()); dbClient.userDao().cleanHomepage(dbSession, project); projectIndexers.commitAndIndexComponents(dbSession, singletonList(project), PROJECT_DELETION); } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SuggestionsActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SuggestionsActionTest.java index 740a89af63e..4fbd8b4bd84 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SuggestionsActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SuggestionsActionTest.java @@ -394,7 +394,7 @@ public class SuggestionsActionTest { componentIndexer.indexAll(); authorizationIndexerTester.allowOnlyAnyone(project); - db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), PROJECT); + db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), PROJECT, project.name(), project.getKey()); db.commit(); SuggestionsWsResponse response = ws.newRequest() -- 2.39.5