From: lukasz-jarocki-sonarsource <77498856+lukasz-jarocki-sonarsource@users.noreply.github.com> Date: Fri, 23 Jul 2021 09:45:00 +0000 (+0200) Subject: SONAR-15154 add audit logs about projects, portfolios and apps X-Git-Tag: 9.1.0.47736~194 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e8f689cc1bfa3c58f7e8d65ef1131789dcd70b58;p=sonarqube.git SONAR-15154 add audit logs about projects, portfolios and apps --- diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java index dc9ab683f8d..af25cfd94c0 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java @@ -51,6 +51,8 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentUpdateDto; import static java.util.Optional.ofNullable; +import static org.sonar.api.resources.Qualifiers.PROJECT; +import static org.sonar.api.resources.Qualifiers.VIEW; import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER; import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT; import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR; @@ -106,7 +108,7 @@ public class PersistComponentsStep implements ComputationStep { .visit(treeRootHolder.getRoot()); disableRemainingComponents(dbSession, existingDtosByUuids.values()); - ensureConsistentVisibility(dbSession, projectUuid, isRootPrivate); + ensureConsistentVisibility(dbSession, projectUuid, isRootPrivate, treeRootHolder.getRoot().getType()); dbSession.commit(); } @@ -133,8 +135,15 @@ public class PersistComponentsStep implements ComputationStep { disabledComponentsHolder.setUuids(uuids); } - private void ensureConsistentVisibility(DbSession dbSession, String projectUuid, boolean isRootPrivate) { - dbClient.componentDao().setPrivateForRootComponentUuid(dbSession, projectUuid, isRootPrivate); + private void ensureConsistentVisibility(DbSession dbSession, String projectUuid, boolean isRootPrivate, + Component.Type type) { + String qualifier = null; + if (type == Component.Type.PROJECT) { + qualifier = PROJECT; + } else if (type == Component.Type.VIEW) { + qualifier = VIEW; + } + dbClient.componentDao().setPrivateForRootComponentUuid(dbSession, projectUuid, isRootPrivate, qualifier); } private static boolean isRootPrivate(Component root, Map existingDtosByUuids) { @@ -242,7 +251,7 @@ public class PersistComponentsStep implements ComputationStep { Optional update = compareForUpdate(existingComponent, componentDto); if (update.isPresent()) { ComponentUpdateDto updateDto = update.get(); - dbClient.componentDao().update(dbSession, updateDto); + dbClient.componentDao().update(dbSession, updateDto, componentDto.qualifier()); // update the fields in memory in order the PathAwareVisitor.Path // to be up-to-date @@ -268,7 +277,7 @@ public class PersistComponentsStep implements ComputationStep { ComponentDto res = createBase(project); res.setScope(Scopes.PROJECT); - res.setQualifier(Qualifiers.PROJECT); + res.setQualifier(PROJECT); res.setName(project.getName()); res.setLongName(res.name()); res.setDescription(project.getDescription()); @@ -346,7 +355,7 @@ public class PersistComponentsStep implements ComputationStep { ComponentDto res = createBase(projectView); res.setScope(Scopes.FILE); - res.setQualifier(Qualifiers.PROJECT); + res.setQualifier(PROJECT); res.setName(projectView.getName()); res.setLongName(res.name()); res.setCopyComponentUuid(projectView.getProjectViewAttributes().getProjectUuid()); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditPersister.java b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditPersister.java index abeb69ff0e1..3875dcbc61b 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditPersister.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditPersister.java @@ -23,6 +23,8 @@ import org.sonar.core.extension.PlatformLevel; import org.sonar.db.DbSession; import org.sonar.db.audit.model.NewValue; +import javax.annotation.Nullable; + @PlatformLevel(1) public interface AuditPersister { @@ -107,4 +109,19 @@ public interface AuditPersister { void deletePersonalAccessToken(DbSession dbSession, NewValue newValue); boolean isTrackedProperty(String propertyKey); + + void addComponent(DbSession dbSession, NewValue newValue, String qualifier); + + void deleteComponent(DbSession dbSession, NewValue newValue, @Nullable String qualifier); + + void updateComponent(DbSession dbSession, NewValue newValue, String qualifier); + + void setPrivateForComponentUuid(DbSession session, NewValue componentNewValue, @Nullable String qualifier); + + void updateComponentVisibility(DbSession session, NewValue projectNewValue, String qualifier); + + void componentKeyUpdate(DbSession session, NewValue componentKeyNewValue, String qualifier); + + void componentKeyBranchUpdate(DbSession session, NewValue componentKeyNewValue, String qualifier); + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ComponentKeyNewValue.java b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ComponentKeyNewValue.java new file mode 100644 index 00000000000..84a485ffc47 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ComponentKeyNewValue.java @@ -0,0 +1,56 @@ +/* + * 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.audit.model; + +public class ComponentKeyNewValue implements NewValue{ + + private final String componentUuid; + private final String oldKey; + private final String newKey; + + public ComponentKeyNewValue(String componentUuid, String oldKey, String newKey) { + this.componentUuid = componentUuid; + this.oldKey = oldKey; + this.newKey = newKey; + } + + public String getComponentUuid() { + return componentUuid; + } + + public String getOldKey() { + return oldKey; + } + + public String getNewKey() { + return newKey; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("{"); + addField(sb, "\"componentUuid\": ", this.getComponentUuid(), true); + addField(sb, "\"oldKey\": ", this.getOldKey(), true); + addField(sb, "\"newKey\": ", this.getNewKey(), true); + endString(sb); + return sb.toString(); + } + +} 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 new file mode 100644 index 00000000000..e40c970e3a7 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ComponentNewValue.java @@ -0,0 +1,135 @@ +/* + * 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.audit.model; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.apache.commons.lang.ObjectUtils; + +import static org.sonar.api.resources.Qualifiers.APP; +import static org.sonar.api.resources.Qualifiers.PROJECT; +import static org.sonar.api.resources.Qualifiers.VIEW; + +public class ComponentNewValue implements NewValue { + + private String componentUuid; + private String componentName; + @Nullable + private String description; + private String rootComponentUuid; + private String path; + private String key; + private Boolean isPrivate; + 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) { + this.componentUuid = componentUuid; + this.componentName = name; + this.generateComponentPrefix(qualifier); + } + + public ComponentNewValue(String rootComponentUuid, boolean isPrivate, @Nullable String qualifier) { + this.rootComponentUuid = rootComponentUuid; + this.isPrivate = isPrivate; + this.generateComponentPrefix(qualifier); + } + + public ComponentNewValue(String uuid, String name, String key, boolean enabled, String path, String qualifier) { + this.componentUuid = uuid; + this.componentName = name; + this.isEnabled = enabled; + this.path = path; + this.key = key; + this.generateComponentPrefix(qualifier); + } + + public ComponentNewValue(String uuid, boolean isPrivate, String name, @Nullable String description, String qualifier) { + this.componentUuid = uuid; + this.isPrivate = isPrivate; + this.componentName = name; + this.description = description; + this.generateComponentPrefix(qualifier); + } + + public String getComponentUuid() { + return componentUuid; + } + + public String getComponentName() { + return componentName; + } + + @CheckForNull + public String getDescription() { + return description; + } + + public String getKey() { + return key; + } + + public boolean isPrivate() { + return isPrivate; + } + + private void generateComponentPrefix(String qualifier) { + if (qualifier == null) { + this.prefix = "component"; + return ; + } + switch (qualifier) { + case VIEW: + this.prefix = "portfolio"; + break; + case APP: + this.prefix = "application"; + break; + case PROJECT: + this.prefix = "project"; + break; + default: + this.prefix = "component"; + break; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("{"); + addField(sb, "\"" + this.prefix + "Uuid\": ", this.componentUuid, true); + 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, "\"path\": ", this.path, true); + addField(sb, "\"isPrivate\": ", ObjectUtils.toString(this.isPrivate), false); + addField(sb, "\"isEnabled\": ", ObjectUtils.toString(this.isEnabled), false); + endString(sb); + return sb.toString(); + } + +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ProjectNewValue.java b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ProjectNewValue.java new file mode 100644 index 00000000000..e10b52dd27e --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/ProjectNewValue.java @@ -0,0 +1,74 @@ +/* + * 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.audit.model; + +import org.apache.commons.lang.ObjectUtils; + +public class ProjectNewValue implements NewValue{ + + private final String uuid; + private String name; + private String description; + private Boolean isPrivate; + + public ProjectNewValue(String uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public ProjectNewValue(String uuid, boolean isPrivate) { + this.uuid = uuid; + this.isPrivate = isPrivate; + } + + public ProjectNewValue(String uuid, boolean isPrivate, String name, String description) { + this.uuid = uuid; + this.isPrivate = isPrivate; + this.name = name; + this.description = description; + } + + public String getUuid() { + return uuid; + } + + public String getDescription() { + return description; + } + + public boolean isPrivate() { + return isPrivate; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("{"); + addField(sb, "\"projectUuid\": ", this.uuid, true); + addField(sb, "\"description\": ", this.description, true); + addField(sb, "\"name\": ", this.name, true); + addField(sb, "\"isPrivate\": ", ObjectUtils.toString(this.isPrivate), false); + endString(sb); + return sb.toString(); + } +} 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 7a1b2b8ecaa..4d18a0194d8 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 @@ -38,6 +38,8 @@ import org.sonar.api.resources.Scopes; import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.RowNotFoundException; +import org.sonar.db.audit.AuditPersister; +import org.sonar.db.audit.model.ComponentNewValue; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Collections.emptyList; @@ -51,6 +53,16 @@ import static org.sonar.db.component.ComponentDto.generateBranchKey; import static org.sonar.db.component.ComponentDto.generatePullRequestKey; public class ComponentDao implements Dao { + private AuditPersister auditPersister; + + public ComponentDao() { + //intentionally empty + } + + public ComponentDao(AuditPersister auditPersister) { + this.auditPersister = auditPersister; + } + private static List selectByQueryImpl(DbSession session, ComponentQuery query, int offset, int limit) { if (query.hasEmptySetOfComponents()) { return emptyList(); @@ -326,6 +338,9 @@ 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()); + } mapper(session).insert(item); } @@ -341,7 +356,11 @@ public class ComponentDao implements Dao { insert(session, Stream.concat(Stream.of(item), Arrays.stream(others))); } - public void update(DbSession session, ComponentUpdateDto component) { + public void update(DbSession session, ComponentUpdateDto component, String qualifier) { + if (auditPersister != null) { + auditPersister.updateComponent(session, new ComponentNewValue(component.getUuid(), component.getBName(), + component.getBKey(), component.isBEnabled(), component.getBPath(), qualifier), qualifier); + } mapper(session).update(component); } @@ -357,11 +376,17 @@ public class ComponentDao implements Dao { mapper(session).resetBChangedForRootComponentUuid(projectUuid); } - public void setPrivateForRootComponentUuid(DbSession session, String projectUuid, boolean isPrivate) { + public void setPrivateForRootComponentUuid(DbSession session, String projectUuid, boolean isPrivate, @Nullable String qualifier) { + if(auditPersister != null) { + auditPersister.setPrivateForComponentUuid(session, new ComponentNewValue(projectUuid, isPrivate, qualifier), qualifier); + } mapper(session).setPrivateForRootComponentUuid(projectUuid, isPrivate); } - public void delete(DbSession session, String componentUuid) { + public void delete(DbSession session, String componentUuid, String qualifier) { + if (auditPersister != null) { + auditPersister.deleteComponent(session, new ComponentNewValue(componentUuid, qualifier), qualifier); + } mapper(session).delete(componentUuid); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java index 26b7abae577..f528fd015ae 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java @@ -38,6 +38,8 @@ import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; import org.sonar.db.Dao; import org.sonar.db.DbSession; +import org.sonar.db.audit.AuditPersister; +import org.sonar.db.audit.model.ComponentKeyNewValue; import static org.sonar.core.component.ComponentKeys.checkProjectKey; import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR; @@ -50,6 +52,15 @@ import static org.sonar.db.component.ComponentDto.generateBranchKey; */ public class ComponentKeyUpdaterDao implements Dao { + private AuditPersister auditPersister; + + public ComponentKeyUpdaterDao() { + } + + public ComponentKeyUpdaterDao(AuditPersister auditPersister) { + this.auditPersister = auditPersister; + } + public void updateKey(DbSession dbSession, String projectUuid, String newKey) { ComponentKeyUpdaterMapper mapper = dbSession.getMapper(ComponentKeyUpdaterMapper.class); checkExistentKey(mapper, newKey); @@ -70,7 +81,7 @@ public class ComponentKeyUpdaterDao implements Dao { // and then proceed with the batch UPDATE at once runBatchUpdateForAllResources(resources, projectOldKey, newKey, mapper, (resource, oldKey) -> { - }); + }, dbSession); } public void updateApplicationBranchKey(DbSession dbSession, String appBranchUuid, String appKey, String newBranchName) { @@ -84,6 +95,10 @@ public class ComponentKeyUpdaterDao implements Dao { appBranch.setKey(newAppBranchKey); mapper.updateComponent(appBranch); + if(auditPersister != null) { + auditPersister.componentKeyBranchUpdate(dbSession, new ComponentKeyNewValue(appBranchUuid, appBranchOldKey, newAppBranchKey), Qualifiers.APP); + } + String oldAppBranchFragment = appBranchOldKey.replace(BRANCH_KEY_SEPARATOR, ""); String newAppBranchFragment = appKey + newBranchName; for (ResourceDto appBranchResource : mapper.selectProjectResources(appBranchUuid)) { @@ -157,7 +172,7 @@ public class ComponentKeyUpdaterDao implements Dao { if (rekeyedResourceFilter.test(rekeyedResource)) { rekeyedResources.add(rekeyedResource); } - }); + }, session); } return rekeyedResources; } @@ -174,8 +189,8 @@ public class ComponentKeyUpdaterDao implements Dao { return key; } - private static void runBatchUpdateForAllResources(Collection resources, String oldKey, String newKey, ComponentKeyUpdaterMapper mapper, - @Nullable BiConsumer consumer) { + private void runBatchUpdateForAllResources(Collection resources, String oldKey, String newKey, ComponentKeyUpdaterMapper mapper, + @Nullable BiConsumer consumer, DbSession dbSession) { for (ResourceDto resource : resources) { String oldResourceKey = resource.getKey(); String newResourceKey = newKey + oldResourceKey.substring(oldKey.length()); @@ -187,6 +202,10 @@ public class ComponentKeyUpdaterDao implements Dao { } mapper.updateComponent(resource); if (resource.getScope().equals(Scopes.PROJECT) && (resource.getQualifier().equals(Qualifiers.PROJECT) || resource.getQualifier().equals(Qualifiers.APP))) { + if(auditPersister != null) { + auditPersister.componentKeyUpdate(dbSession, + new ComponentKeyNewValue(resource.getUuid(), oldResourceKey, newResourceKey), resource.getQualifier()); + } mapper.updateProject(oldResourceKey, newResourceKey); } 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 796c61b99e4..02c397dc41d 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 @@ -26,16 +26,32 @@ import java.util.Set; import org.sonar.api.utils.System2; import org.sonar.db.Dao; import org.sonar.db.DbSession; +import org.sonar.db.audit.AuditPersister; +import org.sonar.db.audit.model.ComponentNewValue; public class ProjectDao implements Dao { private final System2 system2; + private AuditPersister auditPersister; public ProjectDao(System2 system2) { this.system2 = system2; } - public void insert(DbSession session, ProjectDto item) { - mapper(session).insert(item); + public ProjectDao(System2 system2, AuditPersister auditPersister) { + this.system2 = system2; + this.auditPersister = auditPersister; + } + + public void insert(DbSession session, ProjectDto project) { + this.insert(session, project, false); + } + + public void insert(DbSession session, ProjectDto project, boolean track) { + if (track && auditPersister != null) { + auditPersister.addComponent(session, new ComponentNewValue(project.getUuid(), project.getName(), project.getQualifier()), + project.getQualifier()); + } + mapper(session).insert(project); } public Optional selectProjectByKey(DbSession session, String key) { @@ -87,11 +103,10 @@ public class ProjectDao implements Dao { return mapper(session).selectByUuids(uuids); } - public void updateKey(DbSession session, String uuid, String newKey) { - mapper(session).updateKey(uuid, newKey, system2.now()); - } - - public void updateVisibility(DbSession session, String uuid, boolean isPrivate) { + public void updateVisibility(DbSession session, String uuid, boolean isPrivate, String qualifier) { + if (auditPersister != null) { + auditPersister.updateComponentVisibility(session, new ComponentNewValue(uuid, isPrivate, qualifier), qualifier); + } mapper(session).updateVisibility(uuid, isPrivate, system2.now()); } @@ -100,6 +115,11 @@ 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()); + } + 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 45bf942973a..ac746986d51 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 @@ -35,6 +35,8 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.Dao; import org.sonar.db.DbSession; +import org.sonar.db.audit.AuditPersister; +import org.sonar.db.audit.model.ComponentNewValue; import org.sonar.db.component.BranchMapper; import org.sonar.db.component.ComponentDto; @@ -50,11 +52,17 @@ public class PurgeDao implements Dao { private static final String SCOPE_PROJECT = "PRJ"; private final System2 system2; + private AuditPersister auditPersister; public PurgeDao(System2 system2) { this.system2 = system2; } + public PurgeDao(System2 system2, AuditPersister auditPersister) { + this.system2 = system2; + this.auditPersister = auditPersister; + } + public void purge(DbSession session, PurgeConfiguration conf, PurgeListener listener, PurgeProfiler profiler) { PurgeMapper mapper = session.getMapper(PurgeMapper.class); PurgeCommands commands = new PurgeCommands(session, mapper, profiler, system2); @@ -178,7 +186,7 @@ public class PurgeDao implements Dao { deleteRootComponent(uuid, purgeMapper, purgeCommands); } - public void deleteProject(DbSession session, String uuid) { + public void deleteProject(DbSession session, String uuid, String qualifier) { PurgeProfiler profiler = new PurgeProfiler(); PurgeMapper purgeMapper = mapper(session); PurgeCommands purgeCommands = new PurgeCommands(session, profiler, system2); @@ -190,6 +198,10 @@ public class PurgeDao implements Dao { deleteRootComponent(uuid, purgeMapper, purgeCommands); + if (auditPersister != null) { + auditPersister.deleteComponent(session, new ComponentNewValue(uuid, qualifier), qualifier); + } + logProfiling(profiler, start); } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/alm/setting/ProjectAlmSettingDaoWithPersisterTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/alm/setting/ProjectAlmSettingDaoWithPersisterTest.java index 5aa197847be..25d3ce811ea 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/alm/setting/ProjectAlmSettingDaoWithPersisterTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/alm/setting/ProjectAlmSettingDaoWithPersisterTest.java @@ -69,7 +69,7 @@ public class ProjectAlmSettingDaoWithPersisterTest { .extracting(DevOpsPlatformSettingNewValue::getDevOpsPlatformSettingUuid, DevOpsPlatformSettingNewValue::getKey, DevOpsPlatformSettingNewValue::getProjectUuid, DevOpsPlatformSettingNewValue::getProjectName) .containsExactly(githubAlmSetting.getUuid(), githubAlmSetting.getKey(), project.getUuid(), project.getName()); - assertThat(newValue.toString()).doesNotContain("url"); + assertThat(newValue.toString()).doesNotContain("\"url\""); AlmSettingDto anotherGithubAlmSetting = db.almSettings().insertGitHubAlmSetting(); system2.setNow(A_DATE_LATER); @@ -87,7 +87,7 @@ public class ProjectAlmSettingDaoWithPersisterTest { .containsExactly(anotherGithubAlmSetting.getUuid(), anotherGithubAlmSetting.getKey(), project.getUuid(), project.getName(), newProjectAlmSettingDto.getAlmRepo(), newProjectAlmSettingDto.getAlmSlug(), newProjectAlmSettingDto.getSummaryCommentEnabled(), newProjectAlmSettingDto.getMonorepo()); - assertThat(newValue.toString()).doesNotContain("url"); + assertThat(newValue.toString()).doesNotContain("\"url\""); } @Test diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ComponentKeyNewValueTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ComponentKeyNewValueTest.java new file mode 100644 index 00000000000..564ebaa49a0 --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ComponentKeyNewValueTest.java @@ -0,0 +1,39 @@ +/* + * 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.audit.model; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ComponentKeyNewValueTest { + + @Test + public void toString_generatesValidJson() throws ParseException { + ComponentKeyNewValue newValue = new ComponentKeyNewValue("uuid", "a", "b"); + + JSONObject jsonObject = (JSONObject) new JSONParser().parse(newValue.toString()); + + assertThat(jsonObject.size()).isEqualTo(3); + } +} 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 new file mode 100644 index 00000000000..8e952796fa0 --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ComponentNewValueTest.java @@ -0,0 +1,61 @@ +/* + * 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.audit.model; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ComponentNewValueTest { + + @Test + public void toString_generatesValidJson() throws ParseException { + ComponentNewValue newValue = new ComponentNewValue("uuid", "name", "key", true, "path", "qualifier"); + + JSONObject jsonObject = (JSONObject) new JSONParser().parse(newValue.toString()); + + assertThat(jsonObject.size()).isEqualTo(5); + } + + @Test + public void toString_addsPortfolioPrefix() { + ComponentNewValue newValue = new ComponentNewValue("uuid", "name", "key", true, "path", "VW"); + + assertThat(newValue.toString()).contains("portfolioUuid"); + } + + @Test + public void toString_addsProjectPrefix() { + ComponentNewValue newValue = new ComponentNewValue("uuid", "name", "key", true, "path", "TRK"); + + assertThat(newValue.toString()).contains("projectUuid"); + } + + @Test + public void toString_addsApplicationPrefix() { + ComponentNewValue newValue = new ComponentNewValue("uuid", "name", "key", true, "path", "APP"); + + assertThat(newValue.toString()).contains("applicationUuid"); + } + +} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ProjectNewValueTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ProjectNewValueTest.java new file mode 100644 index 00000000000..45735b4ae3d --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/model/ProjectNewValueTest.java @@ -0,0 +1,40 @@ +/* + * 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.audit.model; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ProjectNewValueTest { + + @Test + public void toString_generatesValidJson() throws ParseException { + ProjectNewValue newValue = new ProjectNewValue("uuid", true, "name", "description"); + + JSONObject jsonObject = (JSONObject) new JSONParser().parse(newValue.toString()); + + assertThat(jsonObject.size()).isEqualTo(4); + } + +} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java index 83c3124d05d..ee252a2de80 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java @@ -23,25 +23,11 @@ import com.google.common.collect.ImmutableMap; import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; -import javax.annotation.Nullable; import org.assertj.core.api.ListAssert; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; @@ -49,6 +35,8 @@ import org.sonar.api.utils.System2; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.RowNotFoundException; +import org.sonar.db.audit.AuditPersister; +import org.sonar.db.audit.model.ComponentNewValue; import org.sonar.db.issue.IssueDto; import org.sonar.db.metric.MetricDto; import org.sonar.db.project.ProjectDto; @@ -68,6 +56,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.api.Assertions.tuple; +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.sonar.api.issue.Issue.STATUS_CLOSED; import static org.sonar.api.issue.Issue.STATUS_CONFIRMED; import static org.sonar.api.issue.Issue.STATUS_OPEN; @@ -89,6 +81,21 @@ import static org.sonar.db.component.ComponentTesting.newSubView; import static org.sonar.db.component.ComponentTesting.newView; import static org.sonar.db.component.ComponentTreeQuery.Strategy.CHILDREN; import static org.sonar.db.component.ComponentTreeQuery.Strategy.LEAVES; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; @RunWith(DataProviderRunner.class) public class ComponentDaoTest { @@ -106,9 +113,12 @@ public class ComponentDaoTest { @Rule public DbTester db = DbTester.create(system2); + private final AuditPersister auditPersister = mock(AuditPersister.class); + private final Random random = new Random(); private final DbSession dbSession = db.getSession(); private final ComponentDao underTest = new ComponentDao(); + private final ComponentDao underTestWithAuditPersister = new ComponentDao(auditPersister); private static ComponentTreeQuery.Builder newTreeQuery(String baseUuid) { return ComponentTreeQuery.builder() @@ -323,15 +333,15 @@ public class ComponentDaoTest { assertThat(underTest.selectByKeysAndBranches(db.getSession(), ImmutableMap.of( projectBranch.getKey(), projectBranch.getBranch(), applicationBranch.getKey(), applicationBranch.getBranch()))) - .extracting(ComponentDto::getKey, ComponentDto::getBranch) - .containsExactlyInAnyOrder( - tuple(projectBranch.getKey(), "my_branch"), - tuple(applicationBranch.getKey(), "my_branch")); + .extracting(ComponentDto::getKey, ComponentDto::getBranch) + .containsExactlyInAnyOrder( + tuple(projectBranch.getKey(), "my_branch"), + tuple(applicationBranch.getKey(), "my_branch")); assertThat(underTest.selectByKeysAndBranches(db.getSession(), ImmutableMap.of( projectBranch.getKey(), "unknown", "unknown", projectBranch.getBranch()))) - .extracting(ComponentDto::getDbKey) - .isEmpty(); + .extracting(ComponentDto::getDbKey) + .isEmpty(); assertThat(underTest.selectByKeysAndBranches(db.getSession(), Collections.emptyMap())).isEmpty(); } @@ -1229,7 +1239,7 @@ public class ComponentDaoTest { .setBModuleUuidPath("moduleUuidPath") .setBName("name") .setBPath("path") - .setBQualifier("qualifier")); + .setBQualifier("qualifier"), "qualifier"); dbSession.commit(); Map row = selectBColumnsForUuid("U1"); @@ -1306,7 +1316,7 @@ public class ComponentDaoTest { ComponentDto project1 = db.components().insertPrivateProject(t -> t.setDbKey("PROJECT_1")); db.components().insertPrivateProject(t -> t.setDbKey("PROJECT_2")); - underTest.delete(dbSession, project1.uuid()); + underTest.delete(dbSession, project1.uuid(), null); dbSession.commit(); assertThat(underTest.selectByKey(dbSession, "PROJECT_1")).isEmpty(); @@ -1773,7 +1783,7 @@ public class ComponentDaoTest { db.components().insertComponent(newPrivateProjectDto().setRootUuid(uuid1).setProjectUuid("foo").setPrivate(false)).uuid(), }; - underTest.setPrivateForRootComponentUuid(db.getSession(), uuid1, true); + underTest.setPrivateForRootComponentUuid(db.getSession(), uuid1, true, null); assertThat(privateFlagOfUuid(uuids[0])).isTrue(); assertThat(privateFlagOfUuid(uuids[1])).isTrue(); @@ -1781,7 +1791,7 @@ public class ComponentDaoTest { assertThat(privateFlagOfUuid(uuids[3])).isFalse(); assertThat(privateFlagOfUuid(uuids[4])).isFalse(); - underTest.setPrivateForRootComponentUuid(db.getSession(), uuid1, false); + underTest.setPrivateForRootComponentUuid(db.getSession(), uuid1, false, null); assertThat(privateFlagOfUuid(uuids[0])).isFalse(); assertThat(privateFlagOfUuid(uuids[1])).isFalse(); @@ -1789,7 +1799,7 @@ public class ComponentDaoTest { assertThat(privateFlagOfUuid(uuids[3])).isFalse(); assertThat(privateFlagOfUuid(uuids[4])).isFalse(); - underTest.setPrivateForRootComponentUuid(db.getSession(), uuid2, false); + underTest.setPrivateForRootComponentUuid(db.getSession(), uuid2, false, null); assertThat(privateFlagOfUuid(uuids[0])).isFalse(); assertThat(privateFlagOfUuid(uuids[1])).isFalse(); @@ -1797,7 +1807,7 @@ public class ComponentDaoTest { assertThat(privateFlagOfUuid(uuids[3])).isFalse(); assertThat(privateFlagOfUuid(uuids[4])).isFalse(); - underTest.setPrivateForRootComponentUuid(db.getSession(), uuid2, true); + underTest.setPrivateForRootComponentUuid(db.getSession(), uuid2, true, null); assertThat(privateFlagOfUuid(uuids[0])).isFalse(); assertThat(privateFlagOfUuid(uuids[1])).isFalse(); @@ -1883,6 +1893,43 @@ public class ComponentDaoTest { assertThat(result).isEmpty(); } + @Test + public void delete_auditPersisterIsCalled() { + underTestWithAuditPersister.delete(dbSession, "anyUuid", APP); + + verify(auditPersister, Mockito.times(1)) + .deleteComponent(any(DbSession.class), any(ComponentNewValue.class), anyString()); + } + + @Test + public void setPrivateForRootComponentUuid_auditPersisterIsCalled() { + underTestWithAuditPersister.setPrivateForRootComponentUuid(dbSession, "anyUuid", false, APP); + + verify(auditPersister, Mockito.times(1)) + .setPrivateForComponentUuid(any(DbSession.class), any(ComponentNewValue.class), anyString()); + } + + @Test + public void update_auditPersisterIsCalled() { + ComponentUpdateDto app = new ComponentUpdateDto(); + app.setBQualifier(APP); + + underTestWithAuditPersister.update(dbSession, app, APP); + + verify(auditPersister, Mockito.times(1)) + .updateComponent(any(DbSession.class), any(ComponentNewValue.class), anyString()); + } + + @Test + public void insert_auditPersisterIsCalled() { + ComponentDto app = ComponentTesting.newApplication(); + + underTestWithAuditPersister.insert(dbSession, app); + + verify(auditPersister, Mockito.times(1)) + .addComponent(any(DbSession.class), any(ComponentNewValue.class), anyString()); + } + private boolean privateFlagOfUuid(String uuid) { return underTest.selectByUuid(db.getSession(), uuid).get().isPrivate(); } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java index cbc62eff9b0..eae4e6960f5 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java @@ -33,11 +33,18 @@ import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; +import org.sonar.db.audit.AuditPersister; +import org.sonar.db.audit.model.ComponentKeyNewValue; import org.sonar.db.component.ComponentKeyUpdaterDao.RekeyedResource; import static com.google.common.collect.Lists.newArrayList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR; import static org.sonar.db.component.ComponentDto.generateBranchKey; @@ -54,9 +61,11 @@ public class ComponentKeyUpdaterDaoTest { @Rule public DbTester db = DbTester.create(System2.INSTANCE); + private AuditPersister auditPersister = mock(AuditPersister.class); private DbClient dbClient = db.getDbClient(); private DbSession dbSession = db.getSession(); private ComponentKeyUpdaterDao underTest = db.getDbClient().componentKeyUpdaterDao(); + private ComponentKeyUpdaterDao underTestWithAuditPersister = new ComponentKeyUpdaterDao(auditPersister); @Test public void updateKey_changes_the_key_of_tree_of_components() { @@ -142,6 +151,18 @@ public class ComponentKeyUpdaterDaoTest { underTest.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getDbKey(), "newName"); } + @Test + public void updateApplicationBranchKey_callsAuditPersister() { + ComponentDto app = db.components().insertPublicProject(); + ComponentDto appBranch = db.components().insertProjectBranch(app); + db.components().insertProjectBranch(app, b -> b.setKey("newName")); + + underTestWithAuditPersister.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getDbKey(), "newName2"); + + verify(auditPersister, times(1)) + .componentKeyBranchUpdate(any(DbSession.class), any(ComponentKeyNewValue.class), anyString()); + } + @Test public void updateKey_updates_branches_too() { ComponentDto project = db.components().insertPublicProject(); @@ -304,7 +325,7 @@ public class ComponentKeyUpdaterDaoTest { db.components().insertComponent(newModuleDto(project).setDbKey("my_project:module")); db.components().insertComponent(newModuleDto(project).setDbKey("my_project:inactive_module").setEnabled(false)); - Set rekeyedResources = underTest.bulkUpdateKey(dbSession, "A", "my_", "your_", doNotReturnAnyRekeyedResource()); + Set rekeyedResources = underTestWithAuditPersister.bulkUpdateKey(dbSession, "A", "my_", "your_", doNotReturnAnyRekeyedResource()); List result = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, "your_project"); assertThat(result) @@ -478,6 +499,30 @@ public class ComponentKeyUpdaterDaoTest { assertThat(computeNewKey("my_project", "my_", "$()_")).isEqualTo("$()_project"); } + @Test + public void updateKey_callsAuditPersister() { + db.components().insertComponent(newPrivateProjectDto("A").setDbKey("my_project")); + + underTestWithAuditPersister.updateKey(dbSession, "A", "your_project"); + + verify(auditPersister, times(1)) + .componentKeyUpdate(any(DbSession.class), any(ComponentKeyNewValue.class), anyString()); + } + + @Test + public void bulkUpdate_callsAuditPersister() { + ComponentDto project = db.components().insertComponent(newPrivateProjectDto("A").setDbKey("project")); + db.components().insertComponent(newModuleDto(project).setDbKey("project:enabled-module")); + db.components().insertComponent(newModuleDto(project).setDbKey("project:disabled-module").setEnabled(false)); + + thrown.expect(IllegalArgumentException.class); + + underTest.simulateBulkUpdateKey(dbSession, "A", "project", "project?"); + + verify(auditPersister, times(1)) + .componentKeyUpdate(any(DbSession.class), any(ComponentKeyNewValue.class), anyString()); + } + private Predicate doNotReturnAnyRekeyedResource() { return a -> false; } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java index 73e21debb12..1714a261613 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java @@ -378,7 +378,7 @@ public class IssueDaoTest { } // disable component and test again => not returned anymore - db.getDbClient().componentDao().update(db.getSession(), ComponentUpdateDto.copyFrom(component).setBEnabled(false).setBChanged(true)); + db.getDbClient().componentDao().update(db.getSession(), ComponentUpdateDto.copyFrom(component).setBEnabled(false).setBChanged(true), component.qualifier()); db.getDbClient().componentDao().applyBChangesForRootComponentUuid(db.getSession(), projectUuid); db.commit(); assertThat(db.getDbClient().componentDao().selectByUuid(db.getSession(), component.uuid()).get().isEnabled()) diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/project/ProjectDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/project/ProjectDaoTest.java index e89b99f3571..9ebae98075c 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/project/ProjectDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/project/ProjectDaoTest.java @@ -25,15 +25,22 @@ import java.util.HashSet; import java.util.List; import java.util.Optional; import javax.annotation.Nullable; + import org.junit.Rule; import org.junit.Test; import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.resources.Qualifiers; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; +import org.sonar.db.audit.AuditPersister; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; public class ProjectDaoTest { @@ -42,7 +49,10 @@ public class ProjectDaoTest { @Rule public DbTester db = DbTester.create(system2); + private final AuditPersister auditPersister = mock(AuditPersister.class); + private final ProjectDao projectDao = new ProjectDao(system2); + private final ProjectDao projectDaoWithAuditPersister = new ProjectDao(system2, auditPersister); @Test public void should_insert_and_select_by_uuid() { @@ -138,8 +148,8 @@ public class ProjectDaoTest { assertProject(projectsByUuids.get(0), "projectName_p1", "projectKee_o1_p1", "uuid_o1_p1", "desc_p1", "tag1,tag2", true); assertProject(projectsByUuids.get(1), "projectName_p2", "projectKee_o1_p2", "uuid_o1_p2", "desc_p2", "tag1,tag2", false); - projectDao.updateVisibility(db.getSession(), dto1.getUuid(), false); - projectDao.updateVisibility(db.getSession(), dto2.getUuid(), true); + projectDao.updateVisibility(db.getSession(), dto1.getUuid(), false, Qualifiers.PROJECT); + projectDao.updateVisibility(db.getSession(), dto2.getUuid(), true, Qualifiers.PROJECT); projectsByUuids = projectDao.selectByUuids(db.getSession(), new HashSet<>(Arrays.asList("uuid_o1_p1", "uuid_o1_p2"))); assertThat(projectsByUuids).hasSize(2); @@ -177,6 +187,42 @@ public class ProjectDaoTest { assertThat(projectsByUuids).isEmpty(); } + @Test + public void insert_withoutTrack_shouldNotCallAuditPersister() { + ProjectDto dto1 = createProject("o1", "p1"); + + projectDaoWithAuditPersister.insert(db.getSession(), dto1, false); + + verifyNoInteractions(auditPersister); + } + + @Test + public void insert_withTrack_shouldCallAuditPersister() { + ProjectDto dto1 = createProject("o1", "p1"); + + projectDaoWithAuditPersister.insert(db.getSession(), dto1, true); + + verify(auditPersister, times(1)).addComponent(any(), any(), any()); + } + + @Test + public void updateVisibility_shouldCallAuditPersister() { + ProjectDto dto1 = createProject("o1", "p1"); + + projectDaoWithAuditPersister.updateVisibility(db.getSession(), dto1.getUuid(), false, Qualifiers.PROJECT); + + verify(auditPersister, times(1)).updateComponentVisibility(any(), any(), any()); + } + + @Test + public void update_shouldCallAuditPersister() { + ProjectDto dto1 = createProject("o1", "p1"); + + projectDaoWithAuditPersister.update(db.getSession(), dto1); + + verify(auditPersister, times(1)).updateComponent(any(), any(), any()); + } + private void assertProject(ProjectDto dto, String name, String kee, String uuid, String desc, @Nullable String tags, boolean isPrivate) { assertThat(dto).extracting("name", "kee", "key","uuid", "description", "tagsString", "private") .containsExactly(name, kee, kee, uuid, desc, tags, isPrivate); 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 89ae1e1c96d..375d425eecf 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 @@ -48,6 +48,8 @@ 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; @@ -88,6 +90,8 @@ import static java.util.Collections.emptySet; 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; @@ -119,7 +123,9 @@ 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() { @@ -531,7 +537,7 @@ public class PurgeDaoTest { IssueDto otherIssue2 = db.issues().insert(rule, otherProject, otherFile); FileSourceDto otherFileSource = db.fileSources().insertFileSource(otherFile); - underTest.deleteProject(dbSession, project.uuid()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("components")).containsOnly(otherProject.uuid(), otherModule.uuid(), otherDirectory.uuid(), otherFile.uuid()); @@ -542,6 +548,15 @@ 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(); @@ -569,7 +584,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()); + underTest.deleteProject(dbSession, app.uuid(), app.qualifier()); dbSession.commit(); assertThat(uuidsIn("components")).containsOnly(project.uuid(), otherApp.uuid(), otherAppBranch.uuid()); @@ -629,7 +644,7 @@ public class PurgeDaoTest { WebhookDto webhookNotDeleted = db.webhooks().insertWebhook(projectNotToBeDeleted); WebhookDeliveryLiteDto webhookDeliveryNotDeleted = db.webhookDelivery().insert(webhookNotDeleted); - underTest.deleteProject(dbSession, project1.getUuid()); + underTest.deleteProject(dbSession, project1.getUuid(), project1.getQualifier()); assertThat(uuidsIn("webhooks")).containsOnly(webhookNotDeleted.getUuid()); assertThat(uuidsIn("webhook_deliveries")).containsOnly(webhookDeliveryNotDeleted.getUuid()); @@ -652,7 +667,7 @@ public class PurgeDaoTest { CeActivityDto notDeletedActivity = insertCeActivity(anotherLivingProject); dbSession.commit(); - underTest.deleteProject(dbSession, projectToBeDeleted.uuid()); + underTest.deleteProject(dbSession, projectToBeDeleted.uuid(), projectToBeDeleted.qualifier()); dbSession.commit(); assertThat(uuidsOfTable("ce_activity")) @@ -679,13 +694,13 @@ public class PurgeDaoTest { insertCeTaskInput("non existing task"); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); 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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid()); @@ -711,13 +726,13 @@ public class PurgeDaoTest { insertCeScannerContext("non existing task"); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); 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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid()); @@ -743,13 +758,13 @@ public class PurgeDaoTest { insertCeTaskCharacteristics("non existing task", 5); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); 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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid()); @@ -775,13 +790,13 @@ public class PurgeDaoTest { insertCeTaskMessages("non existing task", 5); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); 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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("ce_activity")).containsOnly(anotherProjectTask.getUuid()); @@ -801,7 +816,7 @@ public class PurgeDaoTest { assertThat(uuidsIn("user_dismissed_messages")).containsOnly(msg1.getUuid(), msg2.getUuid(), msg3.getUuid()); - underTest.deleteProject(dbSession, project.getUuid()); + underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier()); dbSession.commit(); assertThat(uuidsIn("user_dismissed_messages")).containsOnly(msg3.getUuid()); @@ -819,7 +834,7 @@ public class PurgeDaoTest { dbClient.ceQueueDao().insert(dbSession, createCeQueue(anotherLivingProject, Status.PENDING)); dbSession.commit(); - underTest.deleteProject(dbSession, projectToBeDeleted.uuid()); + underTest.deleteProject(dbSession, projectToBeDeleted.uuid(), projectToBeDeleted.qualifier()); dbSession.commit(); assertThat(db.countRowsOfTable("ce_queue")).isEqualTo(1); @@ -845,13 +860,13 @@ public class PurgeDaoTest { insertCeTaskInput("non existing task"); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); 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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid()); @@ -877,14 +892,14 @@ public class PurgeDaoTest { insertCeScannerContext("non existing task"); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); 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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid()); @@ -910,14 +925,14 @@ public class PurgeDaoTest { insertCeTaskCharacteristics("non existing task", 5); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); 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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid()); @@ -943,14 +958,14 @@ public class PurgeDaoTest { insertCeTaskMessages("non existing task", 5); dbSession.commit(); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); 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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); dbSession.commit(); assertThat(uuidsIn("ce_queue")).containsOnly(anotherProjectTask.getUuid()); @@ -991,14 +1006,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()); + underTest.deleteProject(dbSession, referencedProjectA.uuid(), referencedProjectA.qualifier()); assertThat(db.countRowsOfTable("event_component_changes")) .isEqualTo(7); assertThat(db.countRowsOfTable("events")) .isEqualTo(7); - underTest.deleteProject(dbSession, branch.uuid()); + underTest.deleteProject(dbSession, branch.uuid(), branch.qualifier()); assertThat(uuidsIn("event_component_changes", "event_component_uuid")) .containsOnly(project.uuid(), anotherBranch.uuid(), anotherProject.uuid()); assertThat(db.countRowsOfTable("event_component_changes")) @@ -1006,7 +1021,7 @@ public class PurgeDaoTest { assertThat(uuidsIn("events")) .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid(), anotherBranchEvent.getUuid(), anotherProjectEvent.getUuid()); - underTest.deleteProject(dbSession, project.uuid()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); assertThat(uuidsIn("event_component_changes", "event_component_uuid")) .containsOnly(anotherBranch.uuid(), anotherProject.uuid()); assertThat(db.countRowsOfTable("event_component_changes")) @@ -1044,7 +1059,7 @@ public class PurgeDaoTest { assertThat(db.countRowsOfTable("issues")).isGreaterThan(issueCount); assertThat(db.countRowsOfTable("project_branches")).isGreaterThan(branchCount); - underTest.deleteProject(dbSession, projectToDelete.uuid()); + underTest.deleteProject(dbSession, projectToDelete.uuid(), projectToDelete.qualifier()); dbSession.commit(); assertThat(db.countRowsOfTable("components")).isEqualTo(projectEntryCount); @@ -1062,7 +1077,7 @@ public class PurgeDaoTest { ComponentDto otherSubView = db.components().insertComponent(newSubView(otherView)); ComponentDto otherProjectCopy = db.components().insertComponent(newProjectCopy(project, otherSubView)); - underTest.deleteProject(dbSession, view.uuid()); + underTest.deleteProject(dbSession, view.uuid(), view.qualifier()); dbSession.commit(); assertThat(uuidsIn("components")) @@ -1314,7 +1329,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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); assertThat(selectAllDeliveryUuids(db, dbSession)).containsOnly("D2"); } @@ -1325,7 +1340,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()); + underTest.deleteProject(dbSession, project.uuid(), project.qualifier()); assertThat(dbClient.projectMappingsDao().get(dbSession, "a.key.type", "a.key")).isEmpty(); assertThat(dbClient.projectMappingsDao().get(dbSession, "a.key.type", "another.key")).isNotEmpty(); @@ -1339,7 +1354,7 @@ public class PurgeDaoTest { db.almSettings().insertGitlabProjectAlmSetting(almSettingDto, project); db.almSettings().insertGitlabProjectAlmSetting(almSettingDto, otherProject); - underTest.deleteProject(dbSession, project.getUuid()); + underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier()); assertThat(dbClient.projectAlmSettingDao().selectByProject(dbSession, project)).isEmpty(); assertThat(dbClient.projectAlmSettingDao().selectByProject(dbSession, otherProject)).isNotEmpty(); @@ -1378,7 +1393,7 @@ public class PurgeDaoTest { db.measures().insertLiveMeasure(project2, metric); db.measures().insertLiveMeasure(module2, metric); - underTest.deleteProject(dbSession, project1.uuid()); + underTest.deleteProject(dbSession, project1.uuid(), project1.qualifier()); 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-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 93345f875d9..c4bd1e54ab9 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 @@ -19,12 +19,11 @@ */ package org.sonar.server.component.index; -import java.util.Arrays; -import java.util.Collection; 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; @@ -46,6 +45,8 @@ import static org.sonar.server.component.index.ComponentIndexDefinition.TYPE_COM import static org.sonar.server.es.ProjectIndexer.Cause.PROJECT_CREATION; import static org.sonar.server.es.ProjectIndexer.Cause.PROJECT_DELETION; import static org.sonar.server.es.newindex.DefaultIndexSettingsElement.SORTABLE_ANALYZER; +import java.util.Arrays; +import java.util.Collection; public class ComponentIndexerTest { @@ -206,7 +207,7 @@ public class ComponentIndexerTest { indexProject(project, PROJECT_CREATION); assertThatIndexHasSize(1); - db.getDbClient().componentDao().delete(db.getSession(), project.uuid()); + db.getDbClient().componentDao().delete(db.getSession(), project.uuid(), Qualifiers.PROJECT); indexProject(project, PROJECT_DELETION); assertThatIndexHasSize(0); @@ -245,7 +246,7 @@ public class ComponentIndexerTest { private void updateDb(ComponentDto component) { ComponentUpdateDto updateComponent = ComponentUpdateDto.copyFrom(component); updateComponent.setBChanged(true); - dbClient.componentDao().update(dbSession, updateComponent); + dbClient.componentDao().update(dbSession, updateComponent, component.qualifier()); dbClient.componentDao().applyBChangesForRootComponentUuid(dbSession, component.getRootUuid()); dbSession.commit(); } 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 0fd7899f316..ad817103a70 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()); + db.getDbClient().purgeDao().deleteProject(db.getSession(), project.uuid(), Qualifiers.PROJECT); 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 76028e096d9..77de29c71fd 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; @@ -44,6 +44,7 @@ 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 { @@ -97,7 +98,7 @@ public class PermissionIndexerTest { assertThat(es.countDocuments(INDEX_TYPE_FOO_AUTH)).isEqualTo(2); // Simulate a indexation issue - db.getDbClient().componentDao().delete(db.getSession(), project1.uuid()); + db.getDbClient().componentDao().delete(db.getSession(), project1.uuid(), Qualifiers.PROJECT); 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); @@ -313,7 +314,7 @@ public class PermissionIndexerTest { indexPermissions(project, ProjectIndexer.Cause.PROJECT_CREATION); verifyAuthorized(project, user); - db.getDbClient().componentDao().delete(db.getSession(), project.uuid()); + db.getDbClient().componentDao().delete(db.getSession(), project.uuid(), Qualifiers.PROJECT); 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 3608e3685b2..669e360f4d1 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()); + dbClient.purgeDao().deleteProject(dbSession, project.getUuid(), project.getQualifier()); 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()); + dbClient.purgeDao().deleteProject(dbSession, application.getUuid(), application.getQualifier()); 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()); + dbClient.purgeDao().deleteProject(dbSession, project.uuid(), project.qualifier()); dbClient.userDao().cleanHomepage(dbSession, project); projectIndexers.commitAndIndexComponents(dbSession, singletonList(project), PROJECT_DELETION); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java index 97a1335980e..72634b9b377 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java @@ -130,10 +130,10 @@ public class UpdateVisibilityAction implements ProjectsWsAction { private void setPrivateForRootComponentUuid(DbSession dbSession, ComponentDto component, boolean isPrivate) { String uuid = component.uuid(); - dbClient.componentDao().setPrivateForRootComponentUuid(dbSession, uuid, isPrivate); + dbClient.componentDao().setPrivateForRootComponentUuid(dbSession, uuid, isPrivate, component.qualifier()); if (component.qualifier().equals(Qualifiers.PROJECT) || component.qualifier().equals(Qualifiers.APP)) { - dbClient.projectDao().updateVisibility(dbSession, uuid, isPrivate); + dbClient.projectDao().updateVisibility(dbSession, uuid, isPrivate, component.qualifier()); } ComponentMapper mapper = dbSession.getMapper(ComponentMapper.class); 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 da71abf575a..3531eeed00a 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 @@ -19,10 +19,6 @@ */ package org.sonar.server.component.ws; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javax.annotation.Nullable; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -76,6 +72,10 @@ import static org.sonar.server.component.ws.SuggestionsAction.PARAM_QUERY; import static org.sonar.server.component.ws.SuggestionsAction.PARAM_RECENTLY_BROWSED; import static org.sonar.server.component.ws.SuggestionsAction.SHORT_INPUT_WARNING; import static org.sonar.test.JsonAssert.assertJson; +import javax.annotation.Nullable; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class SuggestionsActionTest { private static final String[] SUGGESTION_QUALIFIERS = Stream.of(SuggestionCategory.values()) @@ -394,7 +394,7 @@ public class SuggestionsActionTest { componentIndexer.indexAll(); authorizationIndexerTester.allowOnlyAnyone(project); - db.getDbClient().componentDao().delete(db.getSession(), project.uuid()); + db.getDbClient().componentDao().delete(db.getSession(), project.uuid(), PROJECT); db.commit(); SuggestionsWsResponse response = ws.newRequest()