private List<ActiveRuleChange> removeParent(DbSession dbSession, QProfileDto profile) { List<ActiveRuleChange> changes = new ArrayList<>(); if (profile.getParentKee() == null) { return changes; } profile.setParentKee(null); db.qualityProfileDao().update(dbSession, profile); List<OrgActiveRuleDto> activeRules = db.activeRuleDao().selectByProfile(dbSession, profile); Collection<Integer> ruleIds = activeRules.stream().map(ActiveRuleDto::getRuleId).collect(MoreCollectors.toArrayList()); RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleIds); for (OrgActiveRuleDto activeRule : activeRules) { if (ActiveRuleDto.INHERITED.equals(activeRule.getInheritance())) { changes.addAll(ruleActivator.deactivate(dbSession, context, activeRule.getRuleId(), true)); } else if (ActiveRuleDto.OVERRIDES.equals(activeRule.getInheritance())) { context.reset(activeRule.getRuleId()); activeRule.setInheritance(null); activeRule.setUpdatedAt(system2.now()); db.activeRuleDao().update(dbSession, activeRule); changes.add(new ActiveRuleChange(ActiveRuleChange.Type.UPDATED, activeRule, context.getRule().get()).setInheritance(null)); } } return changes; }
private List<ActiveRuleChange> setParent(DbSession dbSession, QProfileDto profile, QProfileDto parent) { checkRequest(parent.getLanguage().equals(profile.getLanguage()), "Cannot set the profile '%s' as the parent of profile '%s' since their languages differ ('%s' != '%s')", parent.getKee(), profile.getKee(), parent.getLanguage(), profile.getLanguage()); List<ActiveRuleChange> changes = new ArrayList<>(); if (parent.getKee().equals(profile.getParentKee())) { return changes; } checkRequest(!isDescendant(dbSession, profile, parent), "Descendant profile '%s' can not be selected as parent of '%s'", parent.getKee(), profile.getKee()); changes.addAll(removeParent(dbSession, profile)); // set new parent profile.setParentKee(parent.getKee()); db.qualityProfileDao().update(dbSession, profile); List<OrgActiveRuleDto> parentActiveRules = db.activeRuleDao().selectByProfile(dbSession, parent); Collection<Integer> ruleIds = parentActiveRules.stream().map(ActiveRuleDto::getRuleId).collect(MoreCollectors.toArrayList()); RuleActivationContext context = ruleActivator.createContextForUserProfile(dbSession, profile, ruleIds); for (ActiveRuleDto parentActiveRule : parentActiveRules) { try { RuleActivation activation = RuleActivation.create(parentActiveRule.getRuleId(), null, null); changes.addAll(ruleActivator.activate(dbSession, activation, context)); } catch (BadRequestException e) { // for example because rule status is REMOVED // TODO return errors } } return changes; }
@Test public void create_target_profile_with_same_parent_than_source_profile() { OrganizationDto organization = db.organizations().insert(); QProfileDto parent = db.qualityProfiles().insert(organization); QProfileDto source = db.qualityProfiles().insert(organization, p -> p.setParentKee(parent.getKee())); QProfileDto target = underTest.copyToName(db.getSession(), source, "foo"); assertThat(target.getLanguage()).isEqualTo(source.getLanguage()); assertThat(target.getName()).isEqualTo("foo"); assertThat(target.getParentKee()).isEqualTo(parent.getKee()); }
@Test public void selectDescendants_returns_descendants_in_any_order() { QProfileDto base1 = db.qualityProfiles().insert(db.getDefaultOrganization()); QProfileDto child1OfBase1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(base1.getKee())); QProfileDto child2OfBase1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(base1.getKee())); QProfileDto grandChildOfBase1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(child1OfBase1.getKee())); QProfileDto base2 = db.qualityProfiles().insert(db.getDefaultOrganization()); QProfileDto childOfBase2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(base2.getKee())); QProfileDto grandChildOfBase2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setParentKee(childOfBase2.getKee())); QProfileDto other = db.qualityProfiles().insert(db.getDefaultOrganization()); // descendants of a single base profile verifyDescendants(singleton(base1), asList(child1OfBase1, child2OfBase1, grandChildOfBase1)); verifyDescendants(singleton(child1OfBase1), asList(grandChildOfBase1)); verifyDescendants(singleton(child2OfBase1), emptyList()); verifyDescendants(singleton(grandChildOfBase1), emptyList()); // descendants of a multiple base profiles verifyDescendants(asList(base1, base2), asList(child1OfBase1, child2OfBase1, grandChildOfBase1, childOfBase2, grandChildOfBase2)); verifyDescendants(asList(base1, childOfBase2), asList(child1OfBase1, child2OfBase1, grandChildOfBase1, grandChildOfBase2)); verifyDescendants(asList(child1OfBase1, grandChildOfBase2), asList(grandChildOfBase1)); verifyDescendants(asList(other, base2), asList(childOfBase2, grandChildOfBase2)); }
private QProfileDto prepareTarget(DbSession dbSession, OrganizationDto organization, QProfileDto sourceProfile, String toName) { QProfileName toProfileName = new QProfileName(sourceProfile.getLanguage(), toName); verify(sourceProfile, toProfileName); QProfileDto toProfile = db.qualityProfileDao().selectByNameAndLanguage(dbSession, organization, toProfileName.getName(), toProfileName.getLanguage()); if (toProfile == null) { toProfile = factory.checkAndCreateCustom(dbSession, organization, toProfileName); toProfile.setParentKee(sourceProfile.getParentKee()); db.qualityProfileDao().update(dbSession, toProfile); dbSession.commit(); } return toProfile; }
@Test public void create_profile_with_same_parent_as_source_profile() { OrganizationDto organization = db.organizations().insert(); logInAsQProfileAdministrator(organization); QProfileDto parentProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE)); QProfileDto sourceProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE).setParentKee(parentProfile.getKee())); TestResponse response = tester.newRequest() .setMethod("POST") .setParam("fromKey", sourceProfile.getKee()) .setParam("toName", "target-name") .execute(); String generatedUuid = "1"; assertJson(response.getInput()).isSimilarTo("{" + " \"key\": \"" + generatedUuid + "\"," + " \"name\": \"target-name\"," + " \"language\": \"lang1\"," + " \"languageName\": \"Lang1\"," + " \"isDefault\": false," + " \"isInherited\": true" + "}"); QProfileDto loadedProfile = db.getDbClient().qualityProfileDao().selectByNameAndLanguage(db.getSession(), organization, "target-name", sourceProfile.getLanguage()); assertThat(loadedProfile.getKee()).isEqualTo(generatedUuid); assertThat(loadedProfile.getParentKee()).isEqualTo(parentProfile.getKee()); assertThat(backuper.backupedProfile.getKee()).isEqualTo(sourceProfile.getKee()); assertThat(backuper.restoredProfile.getOrganizationUuid()).isEqualTo(sourceProfile.getOrganizationUuid()); assertThat(backuper.restoredProfile.getLanguage()).isEqualTo(sourceProfile.getLanguage()); assertThat(backuper.restoredProfile.getName()).isEqualTo("target-name"); assertThat(backuper.restoredProfile.getKee()).isEqualTo(generatedUuid); assertThat(backuper.restoredProfile.getParentKee()).isEqualTo(parentProfile.getKee()); }
private QProfileDto createChildProfile(QProfileDto parent) { return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p .setLanguage(parent.getLanguage()) .setParentKee(parent.getKee()) .setName("Child of " + parent.getName())); }
private QProfileDto createChildProfile(QProfileDto parent) { return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p .setLanguage(parent.getLanguage()) .setParentKee(parent.getKee()) .setName("Child of " + parent.getName())); }
@Test public void notification_does_not_include_inherited_profiles_when_rule_is_added() { String language = newLanguageKey(); RuleDefinitionDto newRule = db.rules().insert(r -> r.setLanguage(language)); OrganizationDto organization = db.organizations().insert(); QProfileDto builtInQProfileDto = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(true).setLanguage(language)); QProfileDto childQProfileDto = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(false).setLanguage(language).setParentKee(builtInQProfileDto.getKee())); addPluginProfile(builtInQProfileDto, newRule); builtInQProfileRepositoryRule.initialize(); underTest.start(); ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); assertThat(updatedProfiles.keySet()) .extracting(QProfileName::getName, QProfileName::getLanguage) .containsExactlyInAnyOrder(tuple(builtInQProfileDto.getName(), builtInQProfileDto.getLanguage())); assertThat(updatedProfiles.values()) .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) .containsExactlyInAnyOrder(tuple(newRule.getId(), ACTIVATED)); }
@Test public void ancestor_profiles_are_updated() { // Parent profiles should be updated QProfileDto rootProfile = newQualityProfileDto().setKee("root"); QProfileDto parentProfile = newQualityProfileDto().setKee("parent").setParentKee(rootProfile.getKee()); // Current profile => should be updated QProfileDto currentProfile = newQualityProfileDto().setKee("current").setParentKee(parentProfile.getKee()); // Child of current profile => should not be updated QProfileDto childProfile = newQualityProfileDto().setKee("child").setParentKee(currentProfile.getKee()); qualityProfileDb.insert(rootProfile, parentProfile, currentProfile, childProfile); measureRepository.addRawMeasure(1, QUALITY_PROFILES_KEY, Measure.newMeasureBuilder().create(toJson(currentProfile.getKee()))); underTest.execute(new TestComputationStepContext()); assertQualityProfileIsUpdated(rootProfile); assertQualityProfileIsUpdated(parentProfile); assertQualityProfileIsUpdated(currentProfile); assertQualityProfileIsTheSame(childProfile); }
@Test public void notification_does_not_include_inherited_profiles_when_rule_is_deactivated() { String language = newLanguageKey(); RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage(language).setSeverity(Severity.MINOR)); OrganizationDto organization = db.organizations().insert(); QProfileDto builtInQProfileDto = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(true).setLanguage(language)); db.qualityProfiles().activateRule(builtInQProfileDto, rule); QProfileDto childQProfileDto = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(false).setLanguage(language).setParentKee(builtInQProfileDto.getKee())); qProfileRules.activateAndCommit(db.getSession(), childQProfileDto, singleton(RuleActivation.create(rule.getId()))); db.commit(); addPluginProfile(builtInQProfileDto); builtInQProfileRepositoryRule.initialize(); underTest.start(); ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); assertThat(updatedProfiles.keySet()) .extracting(QProfileName::getName, QProfileName::getLanguage) .containsExactlyInAnyOrder(tuple(builtInQProfileDto.getName(), builtInQProfileDto.getLanguage())); assertThat(updatedProfiles.values()) .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) .containsExactlyInAnyOrder(tuple(rule.getId(), DEACTIVATED)); }
public static QProfileDto from(OrgQProfileDto org, RulesProfileDto rules) { return new QProfileDto() .setIsBuiltIn(rules.isBuiltIn()) .setKee(org.getUuid()) .setParentKee(org.getParentUuid()) .setOrganizationUuid(org.getOrganizationUuid()) .setId(rules.getId()) .setRulesProfileUuid(rules.getKee()) .setLanguage(rules.getLanguage()) .setName(rules.getName()) .setRulesUpdatedAt(rules.getRulesUpdatedAt()) .setLastUsed(org.getLastUsed()) .setUserUpdatedAt(org.getUserUpdatedAt()); } }
@Test public void fail_when_profile_is_linked_to_unknown_parent() { QProfileDto currentProfile = newQualityProfileDto().setKee("current").setParentKee("unknown"); qualityProfileDb.insert(currentProfile); measureRepository.addRawMeasure(1, QUALITY_PROFILES_KEY, Measure.newMeasureBuilder().create(toJson(currentProfile.getKee()))); expectedException.expect(RowNotFoundException.class); underTest.execute(new TestComputationStepContext()); }
@Test public void notification_does_not_include_inherited_profiled_when_rule_is_changed() { String language = newLanguageKey(); RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage(language).setSeverity(Severity.MINOR)); OrganizationDto organization = db.organizations().insert(); QProfileDto builtInProfile = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(true).setLanguage(language)); db.qualityProfiles().activateRule(builtInProfile, rule, ar -> ar.setSeverity(Severity.MINOR)); QProfileDto childProfile = insertProfile(organization, orgQProfile -> orgQProfile.setIsBuiltIn(false).setLanguage(language).setParentKee(builtInProfile.getKee())); db.qualityProfiles().activateRule(childProfile, rule, ar -> ar.setInheritance(ActiveRuleDto.INHERITED).setSeverity(Severity.MINOR)); addPluginProfile(builtInProfile, rule); builtInQProfileRepositoryRule.initialize(); db.commit(); underTest.start(); ArgumentCaptor<Multimap> captor = ArgumentCaptor.forClass(Multimap.class); verify(builtInQualityProfilesNotification).onChange(captor.capture(), anyLong(), anyLong()); Multimap<QProfileName, ActiveRuleChange> updatedProfiles = captor.<Multimap<QProfileName, ActiveRuleChange>>getValue(); assertThat(updatedProfiles.keySet()) .extracting(QProfileName::getName, QProfileName::getLanguage) .containsExactlyInAnyOrder(tuple(builtInProfile.getName(), builtInProfile.getLanguage())); assertThat(updatedProfiles.values()) .extracting(value -> value.getActiveRule().getRuleId(), ActiveRuleChange::getType) .containsExactlyInAnyOrder(tuple(rule.getId(), UPDATED)); }
@Test public void example() { OrganizationDto organization = db.organizations().insert(); logInAsQProfileAdministrator(organization); QProfileDto parent = db.qualityProfiles().insert(organization, p -> p.setKee("AU-TpxcA-iU5OvuD2FL2")); QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setKee("old") .setLanguage("Java") .setParentKee(parent.getKee())); String profileUuid = profile.getRulesProfileUuid(); String response = tester.newRequest() .setMethod("POST") .setParam("fromKey", profile.getKee()) .setParam("toName", "My New Profile") .execute() .getInput(); assertJson(response).ignoreFields("key").isSimilarTo(getClass().getResource("copy-example.json")); }
@Test public void inheritance_parent_child() throws Exception { OrganizationDto organization = db.organizations().insert(); RuleDefinitionDto rule1 = db.rules().insert(); RuleDefinitionDto rule2 = db.rules().insert(); RuleDefinitionDto rule3 = db.rules().insert(); ruleIndexer.commitAndIndex(db.getSession(), asList(rule1.getId(), rule2.getId(), rule3.getId())); QProfileDto parent = db.qualityProfiles().insert(organization); db.qualityProfiles().activateRule(parent, rule1); db.qualityProfiles().activateRule(parent, rule2); long parentRules = 2; QProfileDto child = db.qualityProfiles().insert(organization, q -> q.setParentKee(parent.getKee())); db.qualityProfiles().activateRule(child, rule3); long childRules = 1; activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes()); InputStream response = ws.newRequest() .setMediaType(PROTOBUF) .setParam(PARAM_KEY, child.getKee()) .execute() .getInputStream(); InheritanceWsResponse result = InheritanceWsResponse.parseFrom(response); assertThat(result.getProfile().getKey()).isEqualTo(child.getKee()); assertThat(result.getProfile().getActiveRuleCount()).isEqualTo(childRules); assertThat(result.getAncestorsList()).extracting(InheritanceWsResponse.QualityProfile::getKey).containsExactly(parent.getKee()); assertThat(result.getAncestorsList()).extracting(InheritanceWsResponse.QualityProfile::getActiveRuleCount).containsExactly(parentRules); }
private void createProfiles() { db.qualityProfiles().insert(organization, p -> p.setKee("sonar-way-xoo1-12345").setLanguage(xoo1Key).setName("Sonar way")); QProfileDto parentXoo2 = db.qualityProfiles().insert(organization, p -> p.setKee("sonar-way-xoo2-23456").setLanguage(xoo2Key).setName("Sonar way")); db.qualityProfiles().insert(organization, p -> p.setKee("my-sonar-way-xoo2-34567").setLanguage(xoo2Key).setName("My Sonar way").setParentKee(parentXoo2.getKee())); }
@Test public void json_example() { Language cs = newLanguage("cs", "C#"); QProfileDto parentProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setKee("AU-TpxcA-iU5OvuD2FL1") .setName("Parent Company Profile") .setLanguage(cs.getKey())); QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p .setKee("AU-TpxcA-iU5OvuD2FL3") .setName("My Company Profile") .setLanguage(cs.getKey()) .setIsBuiltIn(false) .setRulesUpdatedAt("2016-12-22T19:10:03+0100") .setParentKee(parentProfile.getKee())); // Active rules range(0, 10) .mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(cs.getKey())).getDefinition()) .forEach(r -> db.qualityProfiles().activateRule(profile, r)); // Projects range(0, 7) .mapToObj(i -> db.components().insertPrivateProject()) .forEach(project -> db.qualityProfiles().associateWithProject(project, profile)); ws = new WsActionTester( new ShowAction(db.getDbClient(), new QProfileWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db)), new Languages(cs), ruleIndex)); String result = ws.newRequest().setParam(PARAM_KEY, profile.getKee()).execute().getInput(); assertJson(result).ignoreFields("rulesUpdatedAt", "lastUsed", "userUpdatedAt").isSimilarTo(ws.getDef().responseExampleAsString()); }
@Test public void fail_if_a_descendant_is_marked_as_default() { OrganizationDto organization = db.organizations().insert(); QProfileDto parentProfile = createProfile(organization); QProfileDto childProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE).setParentKee(parentProfile.getKee())); db.qualityProfiles().setAsDefault(childProfile); logInAsQProfileAdministrator(organization); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Profile '" + parentProfile.getName() + "' cannot be deleted because its descendant named '" + childProfile.getName() + "' is marked as default"); ws.newRequest() .setMethod("POST") .setParam(PARAM_KEY, parentProfile.getKee()) .execute(); }
@Before public void setUp() { defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); dbClient = db.getDbClient(); wsSupport = new QProfileWsSupport(dbClient, userSessionRule, defaultOrganizationProvider); organization = OrganizationTesting.newOrganizationDto(); db.organizations().insert(organization); underTest = new SetDefaultAction(LanguageTesting.newLanguages(XOO_1_KEY, XOO_2_KEY), dbClient, userSessionRule, wsSupport); String organizationUuid = organization.getUuid(); xoo1Profile = QualityProfileTesting.newQualityProfileDto() .setOrganizationUuid(organizationUuid) .setLanguage(XOO_1_KEY); xoo2Profile = QualityProfileTesting.newQualityProfileDto() .setOrganizationUuid(organizationUuid) .setLanguage(XOO_2_KEY); xoo2Profile2 = QualityProfileTesting.newQualityProfileDto() .setOrganizationUuid(organizationUuid) .setLanguage(XOO_2_KEY) .setParentKee(xoo2Profile.getKee()); dbClient.qualityProfileDao().insert(db.getSession(), xoo1Profile, xoo2Profile, xoo2Profile2); db.commit(); db.qualityProfiles().setAsDefault(xoo1Profile, xoo2Profile2); ws = new WsActionTester(underTest); }