Browse Source

SONAR-18856 Refactor properties and favorites

tags/10.1.0.73491
Lukasz Jarocki 1 year ago
parent
commit
eacb54feaa

+ 0
- 26
server/sonar-db-dao/src/it/java/org/sonar/db/property/PropertiesDaoIT.java View File

@@ -616,32 +616,6 @@ public class PropertiesDaoIT {
tuple("value", null));
}

@Test
public void selectByKeyAndUserUuidAndComponentQualifier() {
UserDto user1 = db.users().insertUser();
UserDto user2 = db.users().insertUser();
ComponentDto project1 = db.components().insertPrivateProject().getMainBranchComponent();
ComponentDto file1 = db.components().insertComponent(ComponentTesting.newFileDto(project1));
ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent();
db.properties().insertProperties(user1.getLogin(), project1.getKey(), project1.name(), project1.qualifier(),
newPropertyDto("key", "1", project1, user1));
db.properties().insertProperties(user1.getLogin(), project1.getKey(), project2.name(), project2.qualifier(),
newPropertyDto("key", "2", project2, user1));
db.properties().insertProperties(user1.getLogin(), null, file1.name(), null,
newPropertyDto("key", "3", file1, user1));
db.properties().insertProperties(user1.getLogin(), project1.getKey(), project1.name(), project1.qualifier(),
newPropertyDto("another key", "4", project1, user1));
db.properties().insertProperties(user2.getLogin(), project1.getKey(), project1.name(), project1.qualifier(),
newPropertyDto("key", "5", project1, user2));
db.properties().insertProperties(null, null, null, null, newGlobalPropertyDto("key", "global"));

assertThat(underTest.selectByKeyAndUserUuidAndComponentQualifier(db.getSession(), "key", user1.getUuid(), "TRK"))
.extracting(PropertyDto::getValue).containsExactlyInAnyOrder("1", "2");
assertThat(underTest.selectByKeyAndUserUuidAndComponentQualifier(db.getSession(), "key", user1.getUuid(), "FIL"))
.extracting(PropertyDto::getValue).containsExactlyInAnyOrder("3");
assertThat(underTest.selectByKeyAndUserUuidAndComponentQualifier(db.getSession(), "key", user2.getUuid(), "FIL")).isEmpty();
}

@Test
public void saveProperty_inserts_global_properties_when_they_do_not_exist_in_db() {
underTest.saveProperty(new PropertyDto().setKey("global.null").setValue(null));

+ 6
- 3
server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java View File

@@ -157,9 +157,12 @@ public class PropertiesDao implements Dao {
return getMapper(session).selectByKeyAndMatchingValue(key, value);
}

//TODO
public List<PropertyDto> selectByKeyAndUserUuidAndComponentQualifier(DbSession session, String key, String userUuid, String qualifier) {
return getMapper(session).selectByKeyAndUserUuidAndComponentQualifier(key, userUuid, qualifier);
public List<PropertyDto> selectPortfolioPropertyByKeyAndUserUuid(DbSession session, String key, String userUuid) {
return getMapper(session).selectPortfolioPropertyByKeyAndUserUuid(key, userUuid);
}

public List<PropertyDto> selectProjectPropertyByKeyAndUserUuid(DbSession session, String key, String userUuid) {
return getMapper(session).selectProjectPropertyByKeyAndUserUuid(key, userUuid);
}

/**

+ 2
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java View File

@@ -38,7 +38,8 @@ public interface PropertiesMapper {

List<PropertyDto> selectByKeysAndComponentUuids(@Param("keys") List<String> keys, @Param("componentUuids") List<String> componentUuids);

List<PropertyDto> selectByKeyAndUserUuidAndComponentQualifier(@Param("key") String key, @Param("userUuid") String userUuid, @Param("qualifier") String qualifier);
List<PropertyDto> selectPortfolioPropertyByKeyAndUserUuid(@Param("key") String key, @Param("userUuid") String userUuid);
List<PropertyDto> selectProjectPropertyByKeyAndUserUuid(@Param("key") String key, @Param("userUuid") String userUuid);

List<PropertyDto> selectByComponentUuids(@Param("componentUuids") List<String> componentUuids);


+ 15
- 2
server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml View File

@@ -131,15 +131,28 @@
and p.user_uuid is null
</select>

<select id="selectByKeyAndUserUuidAndComponentQualifier" parameterType="map" resultType="ScrapProperty">
<select id="selectPortfolioPropertyByKeyAndUserUuid" parameterType="map" resultType="ScrapProperty">
select
<include refid="columnsToScrapPropertyDto"/>
from
properties p
inner join components prj on prj.uuid=p.component_uuid and prj.qualifier = #{qualifier, jdbcType=VARCHAR}
inner join portfolio por on por.uuid=p.component_uuid
where
p.prop_key = #{key, jdbcType=VARCHAR}
and p.user_uuid = #{userUuid, jdbcType=VARCHAR}
and por.uuid is not null
</select>

<select id="selectProjectPropertyByKeyAndUserUuid" parameterType="map" resultType="ScrapProperty">
select
<include refid="columnsToScrapPropertyDto"/>
from
properties p
inner join projects prj on prj.uuid=p.component_uuid
where
p.prop_key = #{key, jdbcType=VARCHAR}
and p.user_uuid = #{userUuid, jdbcType=VARCHAR}
and prj.uuid is not null
</select>

<select id="selectByQuery" parameterType="map" resultType="ScrapProperty">

+ 8
- 1
server/sonar-server-common/src/main/java/org/sonar/server/favorite/FavoriteUpdater.java View File

@@ -21,6 +21,7 @@ package org.sonar.server.favorite;

import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.resources.Qualifiers;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
@@ -54,7 +55,13 @@ public class FavoriteUpdater {
.build(), dbSession);
checkArgument(existingFavoriteOnComponent.isEmpty(), "Component '%s' (uuid: %s) is already a favorite", entity.getKey(), entity.getUuid());

List<PropertyDto> existingFavorites = dbClient.propertiesDao().selectByKeyAndUserUuidAndComponentQualifier(dbSession, PROP_FAVORITE_KEY, userUuid, entity.getQualifier());
List<PropertyDto> existingFavorites;
if (entity.getQualifier().equals(Qualifiers.PROJECT)) {
existingFavorites = dbClient.propertiesDao().selectProjectPropertyByKeyAndUserUuid(dbSession, PROP_FAVORITE_KEY, userUuid);
} else {
existingFavorites = dbClient.propertiesDao().selectPortfolioPropertyByKeyAndUserUuid(dbSession, PROP_FAVORITE_KEY, userUuid);
}

if (existingFavorites.size() >= 100) {
checkArgument(!failIfTooManyFavorites, "You cannot have more than 100 favorites on components with qualifier '%s'", entity.getQualifier());
return;

+ 1
- 0
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java View File

@@ -186,6 +186,7 @@ public class ReportSubmitterIT {
underTest.submit(PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}", UTF_8));

ProjectDto createdProject = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), PROJECT_KEY).get();

assertThat(db.favorites().hasFavorite(createdProject, user.getUuid())).isTrue();
}


+ 10
- 11
server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/SetActionIT.java View File

@@ -811,8 +811,7 @@ public class SetActionIT {

@Test
public void fail_when_property_with_definition_when_component_qualifier_does_not_match() {
ComponentDto project = randomPublicOrPrivateProject();
ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(project));
ComponentDto portfolio = db.components().insertPrivatePortfolio();
definitions.addComponent(PropertyDefinition
.builder("my.key")
.name("foo")
@@ -823,11 +822,11 @@ public class SetActionIT {
.defaultValue("default")
.onQualifiers(Qualifiers.PROJECT)
.build());
i18n.put("qualifier." + file.qualifier(), "CptLabel");
logInAsProjectAdministrator(project);
i18n.put("qualifier." + portfolio.qualifier(), "CptLabel");
logInAsProjectAdministrator(portfolio);

assertThatThrownBy(() -> {
callForProjectSettingByKey("my.key", "My Value", file.getKey());
callForProjectSettingByKey("my.key", "My Value", portfolio.getKey());
})
.isInstanceOf(BadRequestException.class)
.hasMessage("Setting 'my.key' cannot be set on a CptLabel");
@@ -874,12 +873,12 @@ public class SetActionIT {
failForPropertyWithoutDefinitionOnUnsupportedComponent(view, projectCopy);
}

private void succeedForPropertyWithoutDefinitionAndValidComponent(ComponentDto project) {
logInAsProjectAdministrator(project);
private void succeedForPropertyWithoutDefinitionAndValidComponent(ComponentDto entity) {
logInAsProjectAdministrator(entity);

callForProjectSettingByKey("my.key", "My Value", project.getKey());
callForProjectSettingByKey("my.key", "My Value", entity.getKey());

assertComponentSetting("my.key", "My Value", project.uuid());
assertComponentSetting("my.key", "My Value", entity.uuid());
}

private void failForPropertyWithoutDefinitionOnUnsupportedComponent(ComponentDto root, ComponentDto component) {
@@ -889,8 +888,8 @@ public class SetActionIT {
assertThatThrownBy(() -> {
callForProjectSettingByKey("my.key", "My Value", component.getKey());
})
.isInstanceOf(BadRequestException.class)
.hasMessage("Setting 'my.key' cannot be set on a QualifierLabel");
.isInstanceOf(NotFoundException.class)
.hasMessage(String.format("Component key '%s' not found", component.getKey()));
}

@Test

+ 10
- 10
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentUpdater.java View File

@@ -151,10 +151,19 @@ public class ComponentUpdater {
dbClient.portfolioDao().insert(dbSession, portfolioDto);
}

handlePermissionTemplate(dbSession, componentDto, userUuid, userLogin);
permissionTemplateService.applyDefaultToNewComponent(dbSession, componentDto, userUuid);
addToFavourites(dbSession, projectDto, userUuid, userLogin, componentDto);
return new ComponentCreationData(componentDto, mainBranch, projectDto);
}

// TODO, when working on permissions, maybe we could remove the last argument from this method
private void addToFavourites(DbSession dbSession, @Nullable ProjectDto projectDto, @Nullable String userUuid, @Nullable String userLogin,
ComponentDto componentDto) {
if (projectDto != null && permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, componentDto)) {
favoriteUpdater.add(dbSession, projectDto, userUuid, userLogin, false);
}
}

private void checkKeyFormat(String qualifier, String key) {
checkRequest(isValidProjectKey(key), MALFORMED_KEY_ERROR, getQualifierToDisplay(qualifier), key, ALLOWED_CHARACTERS_MESSAGE);
}
@@ -237,15 +246,6 @@ public class ComponentUpdater {
return branch;
}

// TODO this is wrong, should probably be done for the project and not for the component. Component has the uuid of the branch!
private void handlePermissionTemplate(DbSession dbSession, ComponentDto componentDto, @Nullable String userUuid, @Nullable String userLogin) {
permissionTemplateService.applyDefaultToNewComponent(dbSession, componentDto, userUuid);
if (componentDto.qualifier().equals(PROJECT)
&& permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, componentDto)) {
favoriteUpdater.add(dbSession, toProject(componentDto), userUuid, userLogin, false);
}
}

private static ProjectDto toProject(ComponentDto componentDto) {
return new ProjectDto()
.setUuid(componentDto.uuid())

+ 2
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SetAction.java View File

@@ -53,6 +53,7 @@ import org.sonar.db.property.PropertyDto;
import org.sonar.scanner.protocol.GsonHelper;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.setting.SettingsChangeNotifier;
import org.sonar.server.setting.ws.SettingValidations.SettingData;
import org.sonar.server.user.UserSession;
@@ -323,7 +324,7 @@ public class SetAction implements SettingsWsAction {
return Optional.empty();
}
return Optional.of(dbClient.projectDao().selectEntityByKey(dbSession, componentKey)
.orElseThrow(() -> new IllegalArgumentException(format("Component '%s' not found", componentKey))));
.orElseThrow(() -> new NotFoundException(format("Component key '%s' not found", componentKey))));
}

private PropertyDto toProperty(SetRequest request, Optional<EntityDto> entity) {

Loading…
Cancel
Save