@@ -34,6 +34,7 @@ import org.sonar.api.utils.TempFolder; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
@ServerSide | |||
public class QProfileCopier { | |||
@@ -42,12 +43,14 @@ public class QProfileCopier { | |||
private final QProfileFactory factory; | |||
private final QProfileBackuper backuper; | |||
private final TempFolder temp; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
public QProfileCopier(DbClient db, QProfileFactory factory, QProfileBackuper backuper, TempFolder temp) { | |||
public QProfileCopier(DbClient db, QProfileFactory factory, QProfileBackuper backuper, TempFolder temp, DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this.db = db; | |||
this.factory = factory; | |||
this.backuper = backuper; | |||
this.temp = temp; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
} | |||
public QualityProfileDto copyToName(String fromProfileKey, String toName) { | |||
@@ -72,7 +75,7 @@ public class QProfileCopier { | |||
if (toProfile == null) { | |||
// Do not delegate creation to QProfileBackuper because we need to keep | |||
// the parent-child association, if exists. | |||
toProfile = factory.create(dbSession, toProfileName); | |||
toProfile = factory.create(dbSession, defaultOrganizationProvider.get().getUuid(), toProfileName); | |||
toProfile.setParentKee(fromProfile.getParentKee()); | |||
db.qualityProfileDao().update(dbSession, toProfile); | |||
dbSession.commit(); |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.server.qualityprofile; | |||
import com.google.common.base.Preconditions; | |||
import com.google.common.collect.Lists; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
@@ -35,7 +36,6 @@ import org.sonar.db.qualityprofile.ActiveRuleDto; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.DEACTIVATED; | |||
import static org.sonar.server.ws.WsUtils.checkFound; | |||
@@ -47,30 +47,30 @@ import static org.sonar.server.ws.WsUtils.checkRequest; | |||
public class QProfileFactory { | |||
private final DbClient db; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
public QProfileFactory(DbClient db, DefaultOrganizationProvider defaultOrganizationProvider) { | |||
public QProfileFactory(DbClient db) { | |||
this.db = db; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
} | |||
// ------------- CREATION | |||
QualityProfileDto getOrCreate(DbSession dbSession, QProfileName name) { | |||
QualityProfileDto getOrCreate(DbSession dbSession, String organizationUuid, QProfileName name) { | |||
Preconditions.checkArgument(StringUtils.isNotEmpty(organizationUuid), "Organization is required, when creating a quality profile."); | |||
QualityProfileDto profile = db.qualityProfileDao().selectByNameAndLanguage(name.getName(), name.getLanguage(), dbSession); | |||
if (profile == null) { | |||
profile = doCreate(dbSession, name); | |||
profile = doCreate(dbSession, organizationUuid, name); | |||
} | |||
return profile; | |||
} | |||
public QualityProfileDto create(DbSession dbSession, QProfileName name) { | |||
public QualityProfileDto create(DbSession dbSession, String organizationUuid, QProfileName name) { | |||
Preconditions.checkArgument(StringUtils.isNotEmpty(organizationUuid), "Organization is required, when creating a quality profile."); | |||
QualityProfileDto dto = db.qualityProfileDao().selectByNameAndLanguage(name.getName(), name.getLanguage(), dbSession); | |||
checkRequest(dto == null, "Quality profile already exists: %s", name); | |||
return doCreate(dbSession, name); | |||
return doCreate(dbSession, organizationUuid, name); | |||
} | |||
private QualityProfileDto doCreate(DbSession dbSession, QProfileName name) { | |||
private QualityProfileDto doCreate(DbSession dbSession, String organizationUuid, QProfileName name) { | |||
if (StringUtils.isEmpty(name.getName())) { | |||
throw BadRequestException.create("quality_profiles.profile_name_cant_be_blank"); | |||
} | |||
@@ -79,7 +79,7 @@ public class QProfileFactory { | |||
String key = Slug.slugify(String.format("%s %s %s", name.getLanguage(), name.getName(), RandomStringUtils.randomNumeric(5))); | |||
QualityProfileDto dto = QualityProfileDto.createFor(key) | |||
.setName(name.getName()) | |||
.setOrganizationUuid(defaultOrganizationProvider.get().getUuid()) | |||
.setOrganizationUuid(organizationUuid) | |||
.setLanguage(name.getLanguage()) | |||
.setRulesUpdatedAtAsDate(now); | |||
if (db.qualityProfileDao().selectByKey(dbSession, dto.getKey()) == null) { |
@@ -43,6 +43,7 @@ import org.sonar.db.qualityprofile.ActiveRuleKey; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
@@ -54,19 +55,22 @@ public class QProfileReset { | |||
private final QProfileFactory factory; | |||
private final RuleActivator activator; | |||
private final ActiveRuleIndexer activeRuleIndexer; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
private final ProfileDefinition[] definitions; | |||
public QProfileReset(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer, QProfileFactory factory, | |||
ProfileDefinition[] definitions) { | |||
public QProfileReset(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer, QProfileFactory factory, DefaultOrganizationProvider defaultOrganizationProvider, | |||
ProfileDefinition... definitions) { | |||
this.db = db; | |||
this.activator = activator; | |||
this.activeRuleIndexer = activeRuleIndexer; | |||
this.factory = factory; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
this.definitions = definitions; | |||
} | |||
public QProfileReset(DbClient db, RuleActivator activator, QProfileFactory factory, ActiveRuleIndexer activeRuleIndexer) { | |||
this(db, activator, activeRuleIndexer, factory, new ProfileDefinition[0]); | |||
public QProfileReset(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer, QProfileFactory factory, | |||
DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this(db, activator, activeRuleIndexer, factory, defaultOrganizationProvider, new ProfileDefinition[0]); | |||
} | |||
/** | |||
@@ -79,7 +83,7 @@ public class QProfileReset { | |||
ListMultimap<QProfileName, RulesProfile> profilesByName = loadDefinitionsGroupedByName(language); | |||
for (Map.Entry<QProfileName, Collection<RulesProfile>> entry : profilesByName.asMap().entrySet()) { | |||
QProfileName profileName = entry.getKey(); | |||
QualityProfileDto profile = factory.getOrCreate(dbSession, profileName); | |||
QualityProfileDto profile = factory.getOrCreate(dbSession, defaultOrganizationProvider.get().getUuid(), profileName); | |||
List<RuleActivation> activations = Lists.newArrayList(); | |||
for (RulesProfile def : entry.getValue()) { | |||
for (ActiveRule activeRule : def.getActiveRules()) { | |||
@@ -110,7 +114,7 @@ public class QProfileReset { | |||
BulkChangeResult reset(QProfileName profileName, Collection<RuleActivation> activations) { | |||
DbSession dbSession = db.openSession(false); | |||
try { | |||
QualityProfileDto profile = factory.getOrCreate(dbSession, profileName); | |||
QualityProfileDto profile = factory.getOrCreate(dbSession, defaultOrganizationProvider.get().getUuid(), profileName); | |||
return doReset(dbSession, profile, activations); | |||
} finally { | |||
dbSession.close(); |
@@ -46,6 +46,7 @@ import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.loadedtemplate.LoadedTemplateDto; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; | |||
/** | |||
@@ -63,24 +64,27 @@ public class RegisterQualityProfiles { | |||
private final RuleActivator ruleActivator; | |||
private final Languages languages; | |||
private final ActiveRuleIndexer activeRuleIndexer; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
/** | |||
* To be kept when no ProfileDefinition are injected | |||
*/ | |||
public RegisterQualityProfiles(DbClient dbClient, | |||
QProfileFactory profileFactory, RuleActivator ruleActivator, Languages languages, ActiveRuleIndexer activeRuleIndexer) { | |||
this(dbClient, profileFactory, ruleActivator, Collections.emptyList(), languages, activeRuleIndexer); | |||
QProfileFactory profileFactory, RuleActivator ruleActivator, Languages languages, ActiveRuleIndexer activeRuleIndexer, | |||
DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this(dbClient, profileFactory, ruleActivator, Collections.emptyList(), languages, activeRuleIndexer, defaultOrganizationProvider); | |||
} | |||
public RegisterQualityProfiles(DbClient dbClient, | |||
QProfileFactory profileFactory, RuleActivator ruleActivator, | |||
List<ProfileDefinition> definitions, Languages languages, ActiveRuleIndexer activeRuleIndexer) { | |||
List<ProfileDefinition> definitions, Languages languages, ActiveRuleIndexer activeRuleIndexer, DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this.dbClient = dbClient; | |||
this.profileFactory = profileFactory; | |||
this.ruleActivator = ruleActivator; | |||
this.definitions = definitions; | |||
this.languages = languages; | |||
this.activeRuleIndexer = activeRuleIndexer; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
} | |||
public void start() { | |||
@@ -141,7 +145,7 @@ public class RegisterQualityProfiles { | |||
if (profileDto != null) { | |||
changes.addAll(profileFactory.delete(session, profileDto.getKey(), true)); | |||
} | |||
profileFactory.create(session, name); | |||
profileFactory.create(session, defaultOrganizationProvider.get().getUuid(), name); | |||
for (RulesProfile profile : profiles) { | |||
for (org.sonar.api.rules.ActiveRule activeRule : profile.getActiveRules()) { | |||
RuleKey ruleKey = RuleKey.of(activeRule.getRepositoryKey(), activeRule.getRuleKey()); |
@@ -58,7 +58,7 @@ public class CreateAction implements QProfileWsAction { | |||
private final ActiveRuleIndexer activeRuleIndexer; | |||
public CreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, Languages languages, | |||
QProfileWsSupport qProfileWsSupport, ActiveRuleIndexer activeRuleIndexer, ProfileImporter[] importers) { | |||
QProfileWsSupport qProfileWsSupport, ActiveRuleIndexer activeRuleIndexer, ProfileImporter... importers) { | |||
this.dbClient = dbClient; | |||
this.profileFactory = profileFactory; | |||
this.exporters = exporters; | |||
@@ -83,12 +83,8 @@ public class CreateAction implements QProfileWsAction { | |||
.setResponseExample(getClass().getResource("example-create.json")) | |||
.setHandler(this); | |||
create | |||
.createParam(PARAM_ORGANIZATION) | |||
.setDescription("Organization key") | |||
.setRequired(false) | |||
.setInternal(true) | |||
.setExampleValue("my-org") | |||
qProfileWsSupport | |||
.createOrganizationParam(create) | |||
.setSince("6.4"); | |||
create.createParam(PARAM_PROFILE_NAME) | |||
@@ -121,7 +117,8 @@ public class CreateAction implements QProfileWsAction { | |||
private CreateWsResponse doHandle(DbSession dbSession, CreateRequest createRequest, Request request) { | |||
QProfileResult result = new QProfileResult(); | |||
QualityProfileDto profile = profileFactory.create(dbSession, QProfileName.createFor(createRequest.getLanguage(), createRequest.getProfileName())); | |||
QualityProfileDto profile = profileFactory.create(dbSession, qProfileWsSupport.getOrganizationUuidByKey(createRequest.getOrganizationKey()), | |||
QProfileName.createFor(createRequest.getLanguage(), createRequest.getProfileName())); | |||
result.setProfile(profile); | |||
for (ProfileImporter importer : importers) { | |||
String importerKey = importer.getKey(); | |||
@@ -137,6 +134,7 @@ public class CreateAction implements QProfileWsAction { | |||
private static CreateRequest toRequest(Request request) { | |||
CreateRequest.Builder builder = CreateRequest.builder() | |||
.setOrganizationKey(request.param(PARAM_ORGANIZATION)) | |||
.setLanguage(request.mandatoryParam(PARAM_LANGUAGE)) | |||
.setProfileName(request.mandatoryParam(PARAM_PROFILE_NAME)); | |||
return builder.build(); | |||
@@ -145,6 +143,7 @@ public class CreateAction implements QProfileWsAction { | |||
private CreateWsResponse buildResponse(QProfileResult result) { | |||
String language = result.profile().getLanguage(); | |||
CreateWsResponse.QualityProfile.Builder builder = CreateWsResponse.QualityProfile.newBuilder() | |||
.setOrganization(qProfileWsSupport.getOrganizationKey(result.profile())) | |||
.setKey(result.profile().getKey()) | |||
.setName(result.profile().getName()) | |||
.setLanguage(language) |
@@ -19,26 +19,79 @@ | |||
*/ | |||
package org.sonar.server.qualityprofile.ws; | |||
import java.util.Optional; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.api.server.ws.WebService.NewAction; | |||
import org.sonar.api.server.ws.WebService.NewParam; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonar.server.ws.WsUtils; | |||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; | |||
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION; | |||
@ServerSide | |||
public class QProfileWsSupport { | |||
private final DbClient dbClient; | |||
private final UserSession userSession; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
public QProfileWsSupport(UserSession userSession, DefaultOrganizationProvider defaultOrganizationProvider) { | |||
public QProfileWsSupport(DbClient dbClient, UserSession userSession, DefaultOrganizationProvider defaultOrganizationProvider) { | |||
this.dbClient = dbClient; | |||
this.userSession = userSession; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
} | |||
public String getOrganizationKey(QualityProfileDto profile) { | |||
return getOrganizationKeyByUuid(profile.getOrganizationUuid()); | |||
} | |||
public String getOrganizationUuidByKey(String organizationKey) { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
return getOrganizationByKey(dbSession, organizationKey) | |||
.getUuid(); | |||
} | |||
} | |||
public OrganizationDto getOrganizationByKey(DbSession dbSession, @Nullable String organizationKey) { | |||
String organizationOrDefaultKey = Optional.ofNullable(organizationKey) | |||
.orElseGet(defaultOrganizationProvider.get()::getKey); | |||
return WsUtils.checkFoundWithOptional( | |||
dbClient.organizationDao().selectByKey(dbSession, organizationOrDefaultKey), | |||
"No organizationDto with key '%s'", organizationOrDefaultKey); | |||
} | |||
public String getOrganizationKeyByUuid(String organizationUuid) { | |||
return getOrganizationByUuid(organizationUuid) | |||
.orElseThrow(() -> new IllegalStateException(String.format("Requested the key for non-existing organization uuid '%s'.", organizationUuid))) | |||
.getKey(); | |||
} | |||
private Optional<OrganizationDto> getOrganizationByUuid(String organizationUuid) { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
return dbClient.organizationDao() | |||
.selectByUuid(dbSession, organizationUuid); | |||
} | |||
} | |||
public void checkQProfileAdminPermission() { | |||
userSession | |||
.checkLoggedIn() | |||
.checkPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganizationProvider.get().getUuid()); | |||
} | |||
public NewParam createOrganizationParam(NewAction create) { | |||
return create | |||
.createParam(PARAM_ORGANIZATION) | |||
.setDescription("Organization key") | |||
.setRequired(false) | |||
.setInternal(true) | |||
.setExampleValue("my-org"); | |||
} | |||
} |
@@ -30,13 +30,14 @@ import org.sonar.api.server.rule.RuleParamType; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.RowNotFoundException; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.organization.OrganizationTesting; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.db.rule.RuleDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.db.rule.RuleTesting; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.qualityprofile.index.ActiveRuleIndex; | |||
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; | |||
import org.sonar.server.rule.index.RuleIndex; | |||
import org.sonar.server.rule.index.RuleIndexer; | |||
@@ -59,12 +60,12 @@ public class QProfileFactoryMediumTest { | |||
@Rule | |||
public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); | |||
DbClient db; | |||
DbSession dbSession; | |||
ActiveRuleIndex activeRuleIndex; | |||
ActiveRuleIndexer activeRuleIndexer; | |||
RuleIndexer ruleIndexer; | |||
QProfileFactory factory; | |||
private DbClient db; | |||
private DbSession dbSession; | |||
private ActiveRuleIndexer activeRuleIndexer; | |||
private RuleIndexer ruleIndexer; | |||
private QProfileFactory factory; | |||
private OrganizationDto organization = OrganizationTesting.newOrganizationDto(); | |||
@Before | |||
public void before() { | |||
@@ -72,7 +73,6 @@ public class QProfileFactoryMediumTest { | |||
db = tester.get(DbClient.class); | |||
dbSession = db.openSession(false); | |||
factory = tester.get(QProfileFactory.class); | |||
activeRuleIndex = tester.get(ActiveRuleIndex.class); | |||
activeRuleIndexer = tester.get(ActiveRuleIndexer.class); | |||
ruleIndexer = tester.get(RuleIndexer.class); | |||
} | |||
@@ -84,62 +84,63 @@ public class QProfileFactoryMediumTest { | |||
@Test | |||
public void create() { | |||
QualityProfileDto dto = factory.create(dbSession, new QProfileName("xoo", "P1")); | |||
String uuid = organization.getUuid(); | |||
QualityProfileDto writtenDto = factory.create(dbSession, uuid, new QProfileName("xoo", "P1")); | |||
dbSession.commit(); | |||
dbSession.clearCache(); | |||
assertThat(dto.getKey()).startsWith("xoo-p1-"); | |||
assertThat(dto.getName()).isEqualTo("P1"); | |||
assertThat(dto.getLanguage()).isEqualTo("xoo"); | |||
assertThat(dto.getId()).isNotNull(); | |||
assertThat(writtenDto.getOrganizationUuid()).isEqualTo(uuid); | |||
assertThat(writtenDto.getKey()).startsWith("xoo-p1-"); | |||
assertThat(writtenDto.getName()).isEqualTo("P1"); | |||
assertThat(writtenDto.getLanguage()).isEqualTo("xoo"); | |||
assertThat(writtenDto.getId()).isNotNull(); | |||
// reload the dto | |||
dto = db.qualityProfileDao().selectByNameAndLanguage("P1", "xoo", dbSession); | |||
assertThat(dto.getLanguage()).isEqualTo("xoo"); | |||
assertThat(dto.getName()).isEqualTo("P1"); | |||
assertThat(dto.getKey()).startsWith("xoo-p1"); | |||
assertThat(dto.getId()).isNotNull(); | |||
assertThat(dto.getParentKee()).isNull(); | |||
QualityProfileDto readDto = db.qualityProfileDao().selectByNameAndLanguage("P1", "xoo", dbSession); | |||
assertThat(readDto.getOrganizationUuid()).isEqualTo(uuid); | |||
assertThat(readDto.getName()).isEqualTo("P1"); | |||
assertThat(readDto.getKey()).startsWith("xoo-p1"); | |||
assertThat(readDto.getLanguage()).isEqualTo("xoo"); | |||
assertThat(readDto.getId()).isNotNull(); | |||
assertThat(readDto.getParentKee()).isNull(); | |||
assertThat(db.qualityProfileDao().selectAll(dbSession)).hasSize(1); | |||
} | |||
@Test | |||
public void fail_to_create_if_name_empty() { | |||
public void fail_to_create_if_name_null() { | |||
QProfileName name = new QProfileName("xoo", null); | |||
try { | |||
factory.create(dbSession, name); | |||
fail(); | |||
} catch (BadRequestException e) { | |||
assertThat(e).hasMessage("quality_profiles.profile_name_cant_be_blank"); | |||
} | |||
String organizationUuid = organization.getUuid(); | |||
name = new QProfileName("xoo", ""); | |||
try { | |||
factory.create(dbSession, name); | |||
fail(); | |||
} catch (BadRequestException e) { | |||
assertThat(e).hasMessage("quality_profiles.profile_name_cant_be_blank"); | |||
} | |||
expectBadRequestException("quality_profiles.profile_name_cant_be_blank"); | |||
factory.create(dbSession, organizationUuid, name); | |||
} | |||
@Test | |||
public void fail_to_create_if_name_empty() { | |||
QProfileName name = new QProfileName("xoo", ""); | |||
expectBadRequestException("quality_profiles.profile_name_cant_be_blank"); | |||
factory.create(dbSession, organization.getUuid(), name); | |||
} | |||
@Test | |||
public void fail_to_create_if_already_exists() { | |||
QProfileName name = new QProfileName("xoo", "P1"); | |||
factory.create(dbSession, name); | |||
factory.create(dbSession, organization.getUuid(), name); | |||
dbSession.commit(); | |||
dbSession.clearCache(); | |||
try { | |||
factory.create(dbSession, name); | |||
fail(); | |||
} catch (BadRequestException e) { | |||
assertThat(e).hasMessage("Quality profile already exists: {lang=xoo, name=P1}"); | |||
} | |||
expectBadRequestException("Quality profile already exists: {lang=xoo, name=P1}"); | |||
factory.create(dbSession, organization.getUuid(), name); | |||
} | |||
@Test | |||
public void rename() { | |||
QualityProfileDto dto = factory.create(dbSession, new QProfileName("xoo", "P1")); | |||
QualityProfileDto dto = factory.create(dbSession, organization.getUuid(), new QProfileName("xoo", "P1")); | |||
dbSession.commit(); | |||
dbSession.clearCache(); | |||
String key = dto.getKey(); | |||
@@ -148,13 +149,14 @@ public class QProfileFactoryMediumTest { | |||
dbSession.clearCache(); | |||
QualityProfileDto reloaded = db.qualityProfileDao().selectByKey(dbSession, dto.getKee()); | |||
assertThat(reloaded.getOrganizationUuid()).isEqualTo(organization.getUuid()); | |||
assertThat(reloaded.getKey()).isEqualTo(key); | |||
assertThat(reloaded.getName()).isEqualTo("the new name"); | |||
} | |||
@Test | |||
public void ignore_renaming_if_same_name() { | |||
QualityProfileDto dto = factory.create(dbSession, new QProfileName("xoo", "P1")); | |||
QualityProfileDto dto = factory.create(dbSession, organization.getUuid(), new QProfileName("xoo", "P1")); | |||
dbSession.commit(); | |||
dbSession.clearCache(); | |||
String key = dto.getKey(); | |||
@@ -163,23 +165,21 @@ public class QProfileFactoryMediumTest { | |||
dbSession.clearCache(); | |||
QualityProfileDto reloaded = db.qualityProfileDao().selectByKey(dbSession, dto.getKee()); | |||
assertThat(reloaded.getOrganizationUuid()).isEqualTo(organization.getUuid()); | |||
assertThat(reloaded.getKey()).isEqualTo(key); | |||
assertThat(reloaded.getName()).isEqualTo("P1"); | |||
} | |||
@Test | |||
public void fail_if_blank_renaming() { | |||
QualityProfileDto dto = factory.create(dbSession, new QProfileName("xoo", "P1")); | |||
QualityProfileDto dto = factory.create(dbSession, organization.getUuid(), new QProfileName("xoo", "P1")); | |||
dbSession.commit(); | |||
dbSession.clearCache(); | |||
String key = dto.getKey(); | |||
try { | |||
factory.rename(key, " "); | |||
fail(); | |||
} catch (BadRequestException e) { | |||
assertThat(e).hasMessage("Name must be set"); | |||
} | |||
expectBadRequestException("Name must be set"); | |||
factory.rename(key, " "); | |||
} | |||
@Test | |||
@@ -192,23 +192,20 @@ public class QProfileFactoryMediumTest { | |||
@Test | |||
public void fail_renaming_if_name_already_exists() { | |||
QualityProfileDto p1 = factory.create(dbSession, new QProfileName("xoo", "P1")); | |||
QualityProfileDto p2 = factory.create(dbSession, new QProfileName("xoo", "P2")); | |||
QualityProfileDto p1 = factory.create(dbSession, organization.getUuid(), new QProfileName("xoo", "P1")); | |||
QualityProfileDto p2 = factory.create(dbSession, organization.getUuid(), new QProfileName("xoo", "P2")); | |||
dbSession.commit(); | |||
dbSession.clearCache(); | |||
try { | |||
factory.rename(p1.getKey(), "P2"); | |||
fail(); | |||
} catch (BadRequestException e) { | |||
assertThat(e).hasMessage("Quality profile already exists: P2"); | |||
} | |||
expectBadRequestException("Quality profile already exists: P2"); | |||
factory.rename(p1.getKey(), "P2"); | |||
} | |||
@Test | |||
public void delete() { | |||
initRules(); | |||
db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP1("org-123")); | |||
db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP1(organization.getUuid())); | |||
tester.get(RuleActivator.class).activate(dbSession, new RuleActivation(RuleTesting.XOO_X1), XOO_P1_KEY); | |||
dbSession.commit(); | |||
dbSession.clearCache(); | |||
@@ -338,4 +335,9 @@ public class QProfileFactoryMediumTest { | |||
dbSession.clearCache(); | |||
ruleIndexer.index(); | |||
} | |||
private void expectBadRequestException(String message) { | |||
thrown.expect(BadRequestException.class); | |||
thrown.expectMessage(message); | |||
} | |||
} |
@@ -29,8 +29,6 @@ import org.sonar.db.DbTester; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.db.qualityprofile.QualityProfileTesting; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -42,9 +40,8 @@ public class QProfileFactoryTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester); | |||
private DbSession dbSession = dbTester.getSession(); | |||
private QProfileFactory underTest = new QProfileFactory(dbTester.getDbClient(), defaultOrganizationProvider); | |||
private QProfileFactory underTest = new QProfileFactory(dbTester.getDbClient()); | |||
@Before | |||
public void setUp() throws Exception { |
@@ -26,6 +26,7 @@ import org.junit.rules.ExpectedException; | |||
import org.junit.runner.RunWith; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
@@ -46,6 +47,9 @@ public class CopyActionTest { | |||
private static final String DEFAULT_ORG_UUID = "U1"; | |||
@Rule | |||
public DbTester db = DbTester.create(); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@@ -64,7 +68,7 @@ public class CopyActionTest { | |||
tester = new WsTester(new QProfilesWs( | |||
mock(RuleActivationActions.class), | |||
mock(BulkRuleActivationActions.class), | |||
new CopyAction(qProfileCopier, LanguageTesting.newLanguages("xoo"), new QProfileWsSupport(userSessionRule, defaultOrganizationProvider)))); | |||
new CopyAction(qProfileCopier, LanguageTesting.newLanguages("xoo"), new QProfileWsSupport(db.getDbClient(), userSessionRule, defaultOrganizationProvider)))); | |||
} | |||
@Test |
@@ -24,6 +24,7 @@ import java.io.IOException; | |||
import java.io.Reader; | |||
import java.util.Collections; | |||
import java.util.Map; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
@@ -36,6 +37,7 @@ import org.sonar.api.utils.ValidationMessages; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.db.rule.RuleDto; | |||
import org.sonar.db.rule.RuleTesting; | |||
@@ -95,12 +97,18 @@ public class CreateActionTest { | |||
private QProfileExporters qProfileExporters = new QProfileExporters(dbClient, null, | |||
new RuleActivator(mock(System2.class), dbClient, ruleIndex, new RuleActivatorContextFactory(dbClient), null, activeRuleIndexer, userSession), | |||
profileImporters); | |||
private OrganizationDto organization; | |||
private CreateAction underTest = new CreateAction(dbClient, new QProfileFactory(dbClient, defaultOrganizationProvider), qProfileExporters, | |||
newLanguages(XOO_LANGUAGE), new QProfileWsSupport(userSession, defaultOrganizationProvider), | |||
private CreateAction underTest = new CreateAction(dbClient, new QProfileFactory(dbClient), qProfileExporters, | |||
newLanguages(XOO_LANGUAGE), new QProfileWsSupport(dbClient, userSession, defaultOrganizationProvider), | |||
activeRuleIndexer, profileImporters); | |||
private WsActionTester wsTester = new WsActionTester(underTest); | |||
@Before | |||
public void before() { | |||
organization = dbTester.organizations().insert(); | |||
} | |||
@Test | |||
public void create_profile() { | |||
logInAsQProfileAdministrator(); | |||
@@ -146,6 +154,23 @@ public class CreateActionTest { | |||
assertThat(profile.getWarnings().getWarningsList()).containsOnly("a warning"); | |||
} | |||
@Test | |||
public void create_profile_for_specific_organization() { | |||
logInAsQProfileAdministrator(); | |||
String orgKey = organization.getKey(); | |||
TestRequest request = wsTester.newRequest() | |||
.setMediaType(MediaTypes.PROTOBUF) | |||
.setParam("organization", orgKey) | |||
.setParam("name", "Profile with messages") | |||
.setParam("language", XOO_LANGUAGE) | |||
.setParam("backup_with_messages", "<xml/>"); | |||
assertThat(executeRequest(request).getProfile().getOrganization()) | |||
.isEqualTo(orgKey); | |||
} | |||
@Test | |||
public void fail_if_import_generate_error() { | |||
logInAsQProfileAdministrator(); | |||
@@ -182,11 +207,16 @@ public class CreateActionTest { | |||
private CreateWsResponse executeRequest(String name, String language, Map<String, String> xmls) { | |||
TestRequest request = wsTester.newRequest() | |||
.setMediaType(MediaTypes.PROTOBUF) | |||
.setParam("organization", organization.getKey()) | |||
.setParam("name", name) | |||
.setParam("language", language); | |||
for (Map.Entry<String, String> entry : xmls.entrySet()) { | |||
request.setParam("backup_" + entry.getKey(), entry.getValue()); | |||
} | |||
return executeRequest(request); | |||
} | |||
private CreateWsResponse executeRequest(TestRequest request) { | |||
try { | |||
return parseFrom(request.execute().getInputStream()); | |||
} catch (IOException e) { |
@@ -77,8 +77,8 @@ public class DeleteActionTest { | |||
tester = new WsTester(new QProfilesWs( | |||
mock(RuleActivationActions.class), | |||
mock(BulkRuleActivationActions.class), | |||
new DeleteAction(new Languages(xoo1, xoo2), new QProfileFactory(dbClient, defaultOrganizationProvider), dbClient, | |||
new QProfileWsSupport(userSessionRule, defaultOrganizationProvider)))); | |||
new DeleteAction(new Languages(xoo1, xoo2), new QProfileFactory(dbClient), dbClient, | |||
new QProfileWsSupport(dbClient, userSessionRule, defaultOrganizationProvider)))); | |||
} | |||
@After |
@@ -29,8 +29,6 @@ import org.sonar.db.DbTester; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.db.qualityprofile.QualityProfileTesting; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||
import org.sonar.server.qualityprofile.QProfileFactory; | |||
import org.sonar.server.qualityprofile.QProfileRef; | |||
@@ -45,9 +43,7 @@ public class QProfileFactoryTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester); | |||
private QProfileFactory underTest = new QProfileFactory(dbTester.getDbClient(), defaultOrganizationProvider); | |||
private QProfileFactory underTest = new QProfileFactory(dbTester.getDbClient()); | |||
@Before | |||
public void setUp() throws Exception { |
@@ -31,6 +31,7 @@ import org.sonar.api.resources.Languages; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.ValidationMessages; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.server.language.LanguageTesting; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||
@@ -46,12 +47,14 @@ import static org.mockito.Mockito.mock; | |||
public class QProfilesWsTest { | |||
@Rule | |||
public UserSessionRule userSessionRule = UserSessionRule.standalone(); | |||
@Rule | |||
public DbTester db = DbTester.create(); | |||
private WebService.Controller controller; | |||
private String xoo1Key = "xoo1"; | |||
private String xoo2Key = "xoo2"; | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("ORG1"); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(userSessionRule, defaultOrganizationProvider); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSessionRule, defaultOrganizationProvider); | |||
@Before | |||
public void setUp() { |
@@ -55,7 +55,7 @@ public class RenameActionTest { | |||
private String xoo2Key = "xoo2"; | |||
private WsTester tester; | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("ORG1"); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(userSessionRule, defaultOrganizationProvider); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSessionRule, defaultOrganizationProvider); | |||
@Before | |||
public void setUp() { | |||
@@ -64,7 +64,7 @@ public class RenameActionTest { | |||
tester = new WsTester(new QProfilesWs( | |||
mock(RuleActivationActions.class), | |||
mock(BulkRuleActivationActions.class), | |||
new RenameAction(new QProfileFactory(dbClient, defaultOrganizationProvider), wsSupport))); | |||
new RenameAction(new QProfileFactory(dbClient), wsSupport))); | |||
} | |||
@Test |
@@ -27,6 +27,7 @@ import org.junit.rules.ExpectedException; | |||
import org.junit.runner.RunWith; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
@@ -48,6 +49,9 @@ import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_ | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class RestoreActionTest { | |||
@Rule | |||
public DbTester db = DbTester.create(); | |||
@Rule | |||
public UserSessionRule userSessionRule = UserSessionRule.standalone(); | |||
@@ -59,7 +63,7 @@ public class RestoreActionTest { | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("ORG1"); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(userSessionRule, defaultOrganizationProvider); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSessionRule, defaultOrganizationProvider); | |||
private WsTester tester; | |||
@Before |
@@ -23,6 +23,7 @@ import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.resources.Languages; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.exceptions.UnauthorizedException; | |||
import org.sonar.server.language.LanguageTesting; | |||
@@ -39,6 +40,8 @@ import static org.mockito.Mockito.verify; | |||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; | |||
public class RestoreBuiltInActionTest { | |||
@Rule | |||
public DbTester db = DbTester.create(); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@@ -49,7 +52,7 @@ public class RestoreBuiltInActionTest { | |||
private QProfileReset reset = mock(QProfileReset.class); | |||
private Languages languages = LanguageTesting.newLanguages("xoo"); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("ORG1"); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(userSession, defaultOrganizationProvider); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider); | |||
private WsActionTester tester = new WsActionTester(new RestoreBuiltInAction(reset, languages, wsSupport)); | |||
@@ -97,7 +97,7 @@ public class SearchActionTest { | |||
new SearchDataLoader( | |||
languages, | |||
new QProfileLookup(dbClient), | |||
new QProfileFactory(dbClient, defaultOrganizationProvider), | |||
new QProfileFactory(dbClient), | |||
dbClient, | |||
new ComponentFinder(dbClient), activeRuleIndex), | |||
languages)); |
@@ -24,7 +24,6 @@ import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
@@ -48,7 +47,7 @@ public class SetDefaultActionTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
public DbTester db = DbTester.create(); | |||
@Rule | |||
public UserSessionRule userSessionRule = UserSessionRule.standalone(); | |||
@@ -56,8 +55,8 @@ public class SetDefaultActionTest { | |||
private String xoo2Key = "xoo2"; | |||
private WsTester tester; | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(userSessionRule, defaultOrganizationProvider); | |||
private DbClient dbClient = db.getDbClient(); | |||
private QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSessionRule, defaultOrganizationProvider); | |||
@Before | |||
public void setUp() { | |||
@@ -66,7 +65,7 @@ public class SetDefaultActionTest { | |||
tester = new WsTester(new QProfilesWs( | |||
mock(RuleActivationActions.class), | |||
mock(BulkRuleActivationActions.class), | |||
new SetDefaultAction(LanguageTesting.newLanguages(xoo1Key, xoo2Key), new QProfileLookup(dbClient), new QProfileFactory(dbClient, defaultOrganizationProvider), wsSupport))); | |||
new SetDefaultAction(LanguageTesting.newLanguages(xoo1Key, xoo2Key), new QProfileLookup(dbClient), new QProfileFactory(dbClient), wsSupport))); | |||
} | |||
@Test |
@@ -29,10 +29,12 @@ public class CreateRequest { | |||
private final String profileName; | |||
private final String language; | |||
private final String organizationKey; | |||
private CreateRequest(Builder builder) { | |||
this.profileName = builder.profileName; | |||
this.language = builder.language; | |||
this.organizationKey = builder.organizationKey; | |||
} | |||
public String getLanguage() { | |||
@@ -43,6 +45,10 @@ public class CreateRequest { | |||
return profileName; | |||
} | |||
public String getOrganizationKey() { | |||
return organizationKey; | |||
} | |||
public static Builder builder() { | |||
return new Builder(); | |||
} | |||
@@ -50,6 +56,7 @@ public class CreateRequest { | |||
public static class Builder { | |||
private String language; | |||
private String profileName; | |||
private String organizationKey; | |||
private Builder() { | |||
// enforce factory method use | |||
@@ -65,9 +72,15 @@ public class CreateRequest { | |||
return this; | |||
} | |||
public Builder setOrganizationKey(@Nullable String organizationKey) { | |||
this.organizationKey = organizationKey; | |||
return this; | |||
} | |||
public CreateRequest build() { | |||
checkArgument(language != null && !language.isEmpty(), "Language is mandatory and must not be empty."); | |||
checkArgument(profileName != null && !profileName.isEmpty(), "Profile name is mandatory and must not be empty."); | |||
checkArgument(organizationKey == null || !organizationKey.isEmpty(), "Organization key may be either null or not empty. Empty organization key is invalid."); | |||
return new CreateRequest(this); | |||
} | |||
} |
@@ -43,6 +43,7 @@ message SearchWsResponse { | |||
optional string rulesUpdatedAt = 11; | |||
optional string lastUsed = 13; | |||
optional string userUpdatedAt = 14; | |||
optional string organization = 15; | |||
} | |||
} | |||
@@ -59,6 +60,7 @@ message CreateWsResponse { | |||
optional bool isDefault = 6; | |||
optional Infos infos = 7; | |||
optional Warnings warnings = 8; | |||
optional string organization = 9; | |||
message Infos { | |||
repeated string infos = 1; |