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;
.visit(treeRootHolder.getRoot());
disableRemainingComponents(dbSession, existingDtosByUuids.values());
- ensureConsistentVisibility(dbSession, projectUuid, isRootPrivate);
+ ensureConsistentVisibility(dbSession, projectUuid, isRootPrivate, treeRootHolder.getRoot().getType());
dbSession.commit();
}
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<String, ComponentDto> existingDtosByUuids) {
Optional<ComponentUpdateDto> 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
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());
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());
import org.sonar.db.DbSession;
import org.sonar.db.audit.model.NewValue;
+import javax.annotation.Nullable;
+
@PlatformLevel(1)
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);
+
}
--- /dev/null
+/*
+ * 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();
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
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;
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<ComponentDto> selectByQueryImpl(DbSession session, ComponentQuery query, int offset, int limit) {
if (query.hasEmptySetOfComponents()) {
return emptyList();
}
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);
}
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);
}
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);
}
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;
*/
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);
// 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) {
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)) {
if (rekeyedResourceFilter.test(rekeyedResource)) {
rekeyedResources.add(rekeyedResource);
}
- });
+ }, session);
}
return rekeyedResources;
}
return key;
}
- private static void runBatchUpdateForAllResources(Collection<ResourceDto> resources, String oldKey, String newKey, ComponentKeyUpdaterMapper mapper,
- @Nullable BiConsumer<ResourceDto, String> consumer) {
+ private void runBatchUpdateForAllResources(Collection<ResourceDto> resources, String oldKey, String newKey, ComponentKeyUpdaterMapper mapper,
+ @Nullable BiConsumer<ResourceDto, String> consumer, DbSession dbSession) {
for (ResourceDto resource : resources) {
String oldResourceKey = resource.getKey();
String newResourceKey = newKey + oldResourceKey.substring(oldKey.length());
}
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);
}
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<ProjectDto> selectProjectByKey(DbSession session, String key) {
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());
}
}
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);
}
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;
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);
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);
deleteRootComponent(uuid, purgeMapper, purgeCommands);
+ if (auditPersister != null) {
+ auditPersister.deleteComponent(session, new ComponentNewValue(uuid, qualifier), qualifier);
+ }
+
logProfiling(profiler, start);
}
.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);
.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
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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");
+ }
+
+}
--- /dev/null
+/*
+ * 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);
+ }
+
+}
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;
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;
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;
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 {
@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()
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();
}
.setBModuleUuidPath("moduleUuidPath")
.setBName("name")
.setBPath("path")
- .setBQualifier("qualifier"));
+ .setBQualifier("qualifier"), "qualifier");
dbSession.commit();
Map<String, Object> row = selectBColumnsForUuid("U1");
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();
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();
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();
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();
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();
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();
}
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;
@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() {
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();
db.components().insertComponent(newModuleDto(project).setDbKey("my_project:module"));
db.components().insertComponent(newModuleDto(project).setDbKey("my_project:inactive_module").setEnabled(false));
- Set<RekeyedResource> rekeyedResources = underTest.bulkUpdateKey(dbSession, "A", "my_", "your_", doNotReturnAnyRekeyedResource());
+ Set<RekeyedResource> rekeyedResources = underTestWithAuditPersister.bulkUpdateKey(dbSession, "A", "my_", "your_", doNotReturnAnyRekeyedResource());
List<ComponentDto> result = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, "your_project");
assertThat(result)
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<RekeyedResource> doNotReturnAnyRekeyedResource() {
return a -> false;
}
}
// 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())
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 {
@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() {
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);
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);
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;
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;
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() {
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());
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();
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());
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());
CeActivityDto notDeletedActivity = insertCeActivity(anotherLivingProject);
dbSession.commit();
- underTest.deleteProject(dbSession, projectToBeDeleted.uuid());
+ underTest.deleteProject(dbSession, projectToBeDeleted.uuid(), projectToBeDeleted.qualifier());
dbSession.commit();
assertThat(uuidsOfTable("ce_activity"))
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());
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());
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());
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());
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());
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);
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());
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());
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());
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());
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"))
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"))
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);
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"))
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");
}
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();
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();
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);
*/
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;
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 {
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);
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();
}
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();
*/
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;
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 {
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<EsQueueDto> esQueueDtos = db.getDbClient().esQueueDao().selectForRecovery(db.getSession(), Long.MAX_VALUE, 2);
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);
}
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);
}
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);
*/
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;
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())
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()