import org.sonar.server.rule.ws.ActiveRuleCompleter;
import org.sonar.server.rule.ws.RepositoriesAction;
import org.sonar.server.rule.ws.RuleMapper;
+import org.sonar.server.rule.ws.RuleQueryFactory;
import org.sonar.server.rule.ws.RulesWs;
import org.sonar.server.rule.ws.TagsAction;
import org.sonar.server.source.HtmlSourceDecorator;
RuleMapper.class,
ActiveRuleCompleter.class,
RepositoriesAction.class,
+ RuleQueryFactory.class,
org.sonar.server.rule.ws.AppAction.class,
// languages
package org.sonar.server.qualityprofile.ws;
import org.sonar.api.i18n.I18n;
-import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
-import org.sonar.api.rules.RuleType;
import org.sonar.api.server.ServerSide;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.db.DbClient;
import org.sonar.server.qualityprofile.BulkChangeResult;
import org.sonar.server.qualityprofile.QProfileService;
-import org.sonar.server.rule.RuleService;
-import org.sonar.server.rule.index.RuleQuery;
-import org.sonar.server.rule.ws.SearchAction;
+import org.sonar.server.rule.ws.RuleQueryFactory;
import org.sonar.server.user.UserSession;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TEMPLATE_KEY;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TYPES;
+import static org.sonar.server.rule.ws.SearchAction.defineRuleSearchParameters;
@ServerSide
public class BulkRuleActivationActions {
public static final String BULK_ACTIVATE_ACTION = "activate_rules";
public static final String BULK_DEACTIVATE_ACTION = "deactivate_rules";
- private final DbClient dbClient;
private final QProfileService profileService;
- private final RuleService ruleService;
+ private final RuleQueryFactory ruleQueryFactory;
private final I18n i18n;
private final UserSession userSession;
- public BulkRuleActivationActions(DbClient dbClient, QProfileService profileService, RuleService ruleService, I18n i18n, UserSession userSession) {
- this.dbClient = dbClient;
+ public BulkRuleActivationActions(QProfileService profileService, RuleQueryFactory ruleQueryFactory, I18n i18n, UserSession userSession) {
this.profileService = profileService;
- this.ruleService = ruleService;
+ this.ruleQueryFactory = ruleQueryFactory;
this.i18n = i18n;
this.userSession = userSession;
}
}
});
- SearchAction.defineRuleSearchParameters(activate);
+ defineRuleSearchParameters(activate);
defineProfileKeyParameter(activate);
activate.createParam(SEVERITY)
}
});
- SearchAction.defineRuleSearchParameters(deactivate);
+ defineRuleSearchParameters(deactivate);
defineProfileKeyParameter(deactivate);
}
private void bulkActivate(Request request, Response response) {
BulkChangeResult result = profileService.bulkActivate(
- createRuleQuery(ruleService.newRuleQuery(), request),
+ ruleQueryFactory.createRuleQuery(request),
request.mandatoryParam(PROFILE_KEY),
request.param(SEVERITY));
writeResponse(result, response);
}
private void bulkDeactivate(Request request, Response response) {
- // TODO filter on rule language
BulkChangeResult result = profileService.bulkDeactivate(
- createRuleQuery(ruleService.newRuleQuery(), request),
+ ruleQueryFactory.createRuleQuery(request),
request.mandatoryParam(PROFILE_KEY));
writeResponse(result, response);
}
- private static RuleQuery createRuleQuery(RuleQuery query, Request request) {
- query.setQueryText(request.param(Param.TEXT_QUERY));
- query.setSeverities(request.paramAsStrings(PARAM_SEVERITIES));
- query.setRepositories(request.paramAsStrings(PARAM_REPOSITORIES));
- query.setAvailableSince(request.hasParam(PARAM_AVAILABLE_SINCE) ? request.paramAsDate(PARAM_AVAILABLE_SINCE).getTime() : null);
- query.setStatuses(request.paramAsEnums(PARAM_STATUSES, RuleStatus.class));
- query.setLanguages(request.paramAsStrings(PARAM_LANGUAGES));
- query.setActivation(request.paramAsBoolean(PARAM_ACTIVATION));
- query.setQProfileKey(request.param(PARAM_QPROFILE));
- query.setTags(request.paramAsStrings(PARAM_TAGS));
- query.setInheritance(request.paramAsStrings(PARAM_INHERITANCE));
- query.setActiveSeverities(request.paramAsStrings(PARAM_ACTIVE_SEVERITIES));
- query.setIsTemplate(request.paramAsBoolean(PARAM_IS_TEMPLATE));
- query.setTemplateKey(request.param(PARAM_TEMPLATE_KEY));
- query.setTypes(request.paramAsEnums(PARAM_TYPES, RuleType.class));
- query.setKey(request.param(PARAM_RULE_KEY));
-
- String sortParam = request.param(Param.SORT);
- if (sortParam != null) {
- query.setSortField(sortParam);
- query.setAscendingSort(request.mandatoryParamAsBoolean(Param.ASCENDING));
- }
- return query;
- }
-
private void writeResponse(BulkChangeResult result, Response response) {
JsonWriter json = response.newJsonWriter().beginObject();
json.prop("succeeded", result.countSucceeded());
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.server.rule.ws;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Date;
+import javax.annotation.CheckForNull;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rules.RuleType;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.server.rule.index.RuleQuery;
+
+import static org.sonar.server.util.EnumUtils.toEnums;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TEMPLATE_KEY;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TYPES;
+
+@ServerSide
+public class RuleQueryFactory {
+
+ private final DbClient dbClient;
+
+ public RuleQueryFactory(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ /**
+ * Create a {@link RuleQuery} from a {@link Request}.
+ * When a profile key is set, the language of the profile is automatically set in the query
+ */
+ public RuleQuery createRuleQuery(Request request) {
+ RuleQuery ruleQuery = createRuleQuery(new RuleQuery(), request);
+
+ String qProfileKey = ruleQuery.getQProfileKey();
+ if (qProfileKey != null) {
+ QualityProfileDto qProfile = getProfileByKey(qProfileKey);
+ if (qProfile != null) {
+ ruleQuery.setLanguages(ImmutableList.of(qProfile.getLanguage()));
+ }
+ }
+ return ruleQuery;
+ }
+
+ private static RuleQuery createRuleQuery(RuleQuery query, Request request) {
+ query.setQueryText(request.param(WebService.Param.TEXT_QUERY));
+ query.setSeverities(request.paramAsStrings(PARAM_SEVERITIES));
+ query.setRepositories(request.paramAsStrings(PARAM_REPOSITORIES));
+ Date availableSince = request.paramAsDate(PARAM_AVAILABLE_SINCE);
+ query.setAvailableSince(availableSince != null ? availableSince.getTime() : null);
+ query.setStatuses(toEnums(request.paramAsStrings(PARAM_STATUSES), RuleStatus.class));
+ query.setLanguages(request.paramAsStrings(PARAM_LANGUAGES));
+ query.setActivation(request.paramAsBoolean(PARAM_ACTIVATION));
+ query.setQProfileKey(request.param(PARAM_QPROFILE));
+ query.setTags(request.paramAsStrings(PARAM_TAGS));
+ query.setInheritance(request.paramAsStrings(PARAM_INHERITANCE));
+ query.setActiveSeverities(request.paramAsStrings(PARAM_ACTIVE_SEVERITIES));
+ query.setIsTemplate(request.paramAsBoolean(PARAM_IS_TEMPLATE));
+ query.setTemplateKey(request.param(PARAM_TEMPLATE_KEY));
+ query.setTypes(toEnums(request.paramAsStrings(PARAM_TYPES), RuleType.class));
+ query.setKey(request.param(PARAM_RULE_KEY));
+
+ String sortParam = request.param(WebService.Param.SORT);
+ if (sortParam != null) {
+ query.setSortField(sortParam);
+ query.setAscendingSort(request.mandatoryParamAsBoolean(WebService.Param.ASCENDING));
+ }
+ return query;
+ }
+
+ @CheckForNull
+ private QualityProfileDto getProfileByKey(String key) {
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ return dbClient.qualityProfileDao().selectByKey(dbSession, key);
+ } finally {
+ dbSession.close();
+ }
+ }
+
+}
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.server.es.Facets;
import org.sonarqube.ws.client.rule.SearchWsRequest;
import static com.google.common.collect.FluentIterable.from;
-import static org.sonar.api.utils.DateUtils.parseDate;
import static org.sonar.server.rule.index.RuleIndex.ALL_STATUSES_EXCEPT_REMOVED;
import static org.sonar.server.rule.index.RuleIndex.FACET_ACTIVE_SEVERITIES;
import static org.sonar.server.rule.index.RuleIndex.FACET_LANGUAGES;
import static org.sonar.server.rule.index.RuleIndex.FACET_STATUSES;
import static org.sonar.server.rule.index.RuleIndex.FACET_TAGS;
import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES;
-import static org.sonar.server.util.EnumUtils.toEnums;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.rule.RulesWsParameters.OPTIONAL_FIELDS;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
private static final Collection<String> DEFAULT_FACETS = ImmutableSet.of(PARAM_LANGUAGES, PARAM_REPOSITORIES, "tags");
+ private final RuleQueryFactory ruleQueryFactory;
private final DbClient dbClient;
private final RuleIndex ruleIndex;
private final ActiveRuleCompleter activeRuleCompleter;
private final RuleMapper mapper;
- public SearchAction(RuleIndex ruleIndex, ActiveRuleCompleter activeRuleCompleter, DbClient dbClient, RuleMapper mapper) {
+ public SearchAction(RuleIndex ruleIndex, ActiveRuleCompleter activeRuleCompleter, RuleQueryFactory ruleQueryFactory, DbClient dbClient, RuleMapper mapper) {
this.ruleIndex = ruleIndex;
this.activeRuleCompleter = activeRuleCompleter;
+ this.ruleQueryFactory = ruleQueryFactory;
this.dbClient = dbClient;
this.mapper = mapper;
}
try {
SearchWsRequest searchWsRequest = toSearchWsRequest(request);
org.sonar.server.es.SearchOptions context = getQueryContext(searchWsRequest);
- RuleQuery query = doQuery(searchWsRequest);
+ RuleQuery query = ruleQueryFactory.createRuleQuery(request);
SearchResult searchResult = doSearch(dbSession, query, context);
- SearchResponse responseBuilder = buildResponse(dbSession, searchWsRequest, context, searchResult);
+ SearchResponse responseBuilder = buildResponse(dbSession, searchWsRequest, context, searchResult, query);
writeProtobuf(responseBuilder, request, response);
} finally {
dbClient.closeSession(dbSession);
}
}
- private SearchResponse buildResponse(DbSession dbSession, SearchWsRequest request, SearchOptions context, SearchResult result) {
+ private SearchResponse buildResponse(DbSession dbSession, SearchWsRequest request, SearchOptions context, SearchResult result, RuleQuery query) {
SearchResponse.Builder responseBuilder = SearchResponse.newBuilder();
writeStatistics(responseBuilder, result, context);
- doContextResponse(dbSession, request, result, responseBuilder);
+ doContextResponse(dbSession, request, result, responseBuilder, query);
if (!context.getFacets().isEmpty()) {
writeFacets(responseBuilder, request, context, result);
}
.setDefaultValue(true);
}
- private static RuleQuery createRuleQuery(RuleQuery query, SearchWsRequest request) {
- query.setQueryText(request.getQuery());
- query.setSeverities(request.getSeverities());
- query.setRepositories(request.getRepositories());
- query.setAvailableSince(request.getAvailableSince() != null ? parseDate(request.getAvailableSince()).getTime() : null);
- query.setStatuses(toEnums(request.getStatuses(), RuleStatus.class));
- query.setLanguages(request.getLanguages());
- query.setActivation(request.getActivation());
- query.setQProfileKey(request.getQProfile());
- query.setTags(request.getTags());
- query.setInheritance(request.getInheritance());
- query.setActiveSeverities(request.getActiveSeverities());
- query.setIsTemplate(request.getIsTemplate());
- query.setTemplateKey(request.getTemplateKey());
- query.setTypes(toEnums(request.getTypes(), RuleType.class));
- query.setKey(request.getRuleKey());
-
- String sortParam = request.getSort();
- if (sortParam != null) {
- query.setSortField(sortParam);
- query.setAscendingSort(request.getAsc());
- }
- return query;
- }
-
private void writeRules(SearchResponse.Builder response, SearchResult result, org.sonar.server.es.SearchOptions context) {
for (RuleDto rule : result.rules) {
response.addRules(mapper.toWsRule(rule, result, context.getFields()));
}
protected org.sonar.server.es.SearchOptions getQueryContext(SearchWsRequest request) {
- // TODO Get rid of this horrible hack: fields on request are not the same as fields for ES search ! 1/2
org.sonar.server.es.SearchOptions context = loadCommonContext(request);
org.sonar.server.es.SearchOptions searchQueryContext = new org.sonar.server.es.SearchOptions()
.setLimit(context.getLimit())
.setTotal(result.getTotal());
}
- protected RuleQuery doQuery(SearchWsRequest request) {
- RuleQuery plainQuery = createRuleQuery(new RuleQuery(), request);
-
- String qProfileKey = request.getQProfile();
- if (qProfileKey != null) {
- QualityProfileDto qProfile = activeRuleCompleter.loadProfile(qProfileKey);
- if (qProfile != null) {
- plainQuery.setLanguages(ImmutableList.of(qProfile.getLanguage()));
- }
- }
-
- return plainQuery;
- }
-
- protected void doContextResponse(DbSession dbSession, SearchWsRequest request, SearchResult result, SearchResponse.Builder response) {
- // TODO Get rid of this horrible hack: fields on request are not the same as fields for ES search ! 2/2
+ protected void doContextResponse(DbSession dbSession, SearchWsRequest request, SearchResult result, SearchResponse.Builder response, RuleQuery query) {
org.sonar.server.es.SearchOptions contextForResponse = loadCommonContext(request);
writeRules(response, result, contextForResponse);
if (contextForResponse.getFields().contains("actives")) {
- activeRuleCompleter.completeSearch(dbSession, doQuery(request), result.rules, response);
+ activeRuleCompleter.completeSearch(dbSession, query, result.rules, response);
}
}
}
}
- private enum TypeToString implements Function<RuleType, String> {
- INSTANCE;
-
- @Override
- public String apply(@Nonnull RuleType input) {
- return input.name();
- }
-
- }
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
public class QProfilesWsMediumTest {
@Test
public void bulk_activate_rule() throws Exception {
QualityProfileDto profile = createProfile("java");
- RuleDto rule0 = createRule(profile.getLanguage(), "toto");
- RuleDto rule1 = createRule(profile.getLanguage(), "tata");
- RuleDto rule2 = createRule(profile.getLanguage(), "hello");
- RuleDto rule3 = createRule(profile.getLanguage(), "world");
+ createRule(profile.getLanguage(), "toto");
+ createRule(profile.getLanguage(), "tata");
+ createRule(profile.getLanguage(), "hello");
+ createRule(profile.getLanguage(), "world");
session.commit();
ruIndexer.index();
WsTester.TestRequest request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
request.setParam(RuleActivationActions.PROFILE_KEY, profile.getKey());
request.setParam(PARAM_LANGUAGES, "java");
- WsTester.Result result = request.execute();
+ request.execute().assertJson(getClass(), "bulk_activate_rule.json");
session.clearCache();
// 2. Assert ActiveRule in DAO
public void bulk_activate_rule_not_all() throws Exception {
QualityProfileDto java = createProfile("java");
QualityProfileDto php = createProfile("php");
- RuleDto rule0 = createRule(java.getLanguage(), "toto");
- RuleDto rule1 = createRule(java.getLanguage(), "tata");
- RuleDto rule2 = createRule(php.getLanguage(), "hello");
- RuleDto rule3 = createRule(php.getLanguage(), "world");
+ createRule(java.getLanguage(), "toto");
+ createRule(java.getLanguage(), "tata");
+ createRule(php.getLanguage(), "hello");
+ createRule(php.getLanguage(), "world");
session.commit();
ruIndexer.index();
WsTester.TestRequest request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
request.setParam(RuleActivationActions.PROFILE_KEY, php.getKey());
request.setParam(PARAM_LANGUAGES, "php");
- WsTester.Result result = request.execute();
+ request.execute().assertJson(getClass(), "bulk_activate_rule_not_all.json");
session.clearCache();
// 2. Assert ActiveRule in DAO
@Test
public void bulk_activate_rule_by_query() throws Exception {
QualityProfileDto profile = createProfile("java");
- RuleDto rule0 = createRule(profile.getLanguage(), "toto");
- RuleDto rule1 = createRule(profile.getLanguage(), "tata");
- RuleDto rule2 = createRule(profile.getLanguage(), "hello");
- RuleDto rule3 = createRule(profile.getLanguage(), "world");
+ createRule(profile.getLanguage(), "toto");
+ createRule(profile.getLanguage(), "tata");
+ createRule(profile.getLanguage(), "hello");
+ createRule(profile.getLanguage(), "world");
session.commit();
ruIndexer.index();
WsTester.TestRequest request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
request.setParam(RuleActivationActions.PROFILE_KEY, profile.getKey());
request.setParam(WebService.Param.TEXT_QUERY, "php");
- WsTester.Result result = request.execute();
+ request.execute();
session.clearCache();
// 2. Assert ActiveRule in DAO
request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
request.setParam(RuleActivationActions.PROFILE_KEY, profile.getKey());
request.setParam(WebService.Param.TEXT_QUERY, "world");
- result = request.execute();
+ request.execute();
session.commit();
// 2. Assert ActiveRule in DAO
// 2. Assert ActiveRule with MINOR severity
assertThat(tester.get(ActiveRuleIndex.class).findByRule(rule0.getKey()).get(0).severity()).isEqualTo("MINOR");
+ }
+ @Test
+ public void does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile() throws Exception {
+ QualityProfileDto javaProfile = createProfile("java");
+ createRule(javaProfile.getLanguage(), "toto");
+ createRule(javaProfile.getLanguage(), "tata");
+ QualityProfileDto phpProfile = createProfile("php");
+ createRule(phpProfile.getLanguage(), "hello");
+ createRule(phpProfile.getLanguage(), "world");
+ session.commit();
+ ruIndexer.index();
+
+ // 1. Activate Rule
+ WsTester.TestRequest request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
+ request.setParam(RuleActivationActions.PROFILE_KEY, javaProfile.getKey());
+ request.setParam(PARAM_QPROFILE, javaProfile.getKey());
+ request.setParam("activation", "false");
+ request.execute().assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json");
+ session.clearCache();
+
+ // 2. Assert ActiveRule in DAO
+ assertThat(db.activeRuleDao().selectByProfileKey(session, javaProfile.getKey())).hasSize(2);
}
@Test
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.qualityprofile.QProfileExporters;
import org.sonar.server.qualityprofile.QProfileService;
-import org.sonar.server.rule.RuleService;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsTester;
@Before
public void setUp() {
QProfileService profileService = mock(QProfileService.class);
- RuleService ruleService = mock(RuleService.class);
I18n i18n = mock(I18n.class);
Languages languages = LanguageTesting.newLanguages(xoo1Key, xoo2Key);
controller = new WsTester(new QProfilesWs(
new RuleActivationActions(profileService),
- new BulkRuleActivationActions(null, profileService, ruleService, i18n, userSessionRule),
+ new BulkRuleActivationActions(profileService, null, i18n, userSessionRule),
new ProjectAssociationActions(null, null, null, languages, userSessionRule),
new CreateAction(null, null, null, languages, importers, userSessionRule),
new ImportersAction(importers),
new ExportAction(null, null, null, mock(QProfileExporters.class), languages),
new ExportersAction(),
new InheritanceAction(null, null, null, null, languages),
- new RenameAction(null, userSessionRule)
- )).controller(QProfilesWs.API_ENDPOINT);
+ new RenameAction(null, userSessionRule))).controller(QProfilesWs.API_ENDPOINT);
}
private ProfileImporter[] createImporters(Languages languages) {
assertThat(changelog).isNotNull();
assertThat(changelog.isPost()).isFalse();
assertThat(changelog.params()).hasSize(7).extracting("key").containsOnly(
- "profileKey", "profileName", "language", "since", "to", "p", "ps"
- );
+ "profileKey", "profileName", "language", "since", "to", "p", "ps");
assertThat(changelog.responseExampleAsString()).isNotEmpty();
}
assertThat(changeParent).isNotNull();
assertThat(changeParent.isPost()).isTrue();
assertThat(changeParent.params()).hasSize(5).extracting("key").containsOnly(
- "profileKey", "profileName", "language", "parentKey", "parentName"
- );
+ "profileKey", "profileName", "language", "parentKey", "parentName");
}
@Test
assertThat(compare.isPost()).isFalse();
assertThat(compare.isInternal()).isTrue();
assertThat(compare.params()).hasSize(2).extracting("key").containsOnly(
- "leftKey", "rightKey"
- );
+ "leftKey", "rightKey");
assertThat(compare.responseExampleAsString()).isNotEmpty();
}
assertThat(copy).isNotNull();
assertThat(copy.isPost()).isTrue();
assertThat(copy.params()).hasSize(2).extracting("key").containsOnly(
- "fromKey", "toName"
- );
+ "fromKey", "toName");
}
@Test
assertThat(delete).isNotNull();
assertThat(delete.isPost()).isTrue();
assertThat(delete.params()).hasSize(3).extracting("key").containsOnly(
- "profileKey", "language", "profileName"
- );
+ "profileKey", "language", "profileName");
}
@Test
assertThat(export).isNotNull();
assertThat(export.isPost()).isFalse();
assertThat(export.params()).hasSize(2).extracting("key").containsOnly(
- "language", "name"
- );
+ "language", "name");
}
@Test
assertThat(inheritance).isNotNull();
assertThat(inheritance.isPost()).isFalse();
assertThat(inheritance.params()).hasSize(3).extracting("key").containsOnly(
- "profileKey", "language", "profileName"
- );
+ "profileKey", "language", "profileName");
assertThat(inheritance.responseExampleAsString()).isNotEmpty();
}
assertThat(rename).isNotNull();
assertThat(rename.isPost()).isTrue();
assertThat(rename.params()).hasSize(2).extracting("key").containsOnly(
- "key", "name"
- );
+ "key", "name");
}
}
newDoc(RULE_KEY_1).setType(CODE_SMELL),
newDoc(RULE_KEY_2).setType(VULNERABILITY),
newDoc(RULE_KEY_3).setType(BUG),
- newDoc(RULE_KEY_4).setType(BUG)
- );
+ newDoc(RULE_KEY_4).setType(BUG));
// find all
RuleQuery query = new RuleQuery();
assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RULE_KEY_2);
query = new RuleQuery().setTypes(ImmutableSet.of(BUG));
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RULE_KEY_3,RULE_KEY_4);
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RULE_KEY_3, RULE_KEY_4);
// types in query => nothing
query = new RuleQuery().setQueryText("code smell bug vulnerability");
// 1. get all active rules
assertThat(index.search(new RuleQuery()
.setActivation(true), new SearchOptions()).getIds())
- .hasSize(3);
+ .hasSize(3);
// 2. get all inactive rules.
assertThat(index.search(new RuleQuery()
.setActivation(false), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_4);
+ .containsOnly(RULE_KEY_4);
// 3. get Inherited Rules on profile1
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY1)
.setInheritance(ImmutableSet.of(INHERITED.name())),
new SearchOptions()).getIds())
- .isEmpty();
+ .isEmpty();
// 4. get Inherited Rules on profile2
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY2)
.setInheritance(ImmutableSet.of(INHERITED.name())),
new SearchOptions()).getIds())
- .hasSize(2);
+ .hasSize(2);
// 5. get Overridden Rules on profile1
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY1)
.setInheritance(ImmutableSet.of(OVERRIDES.name())),
new SearchOptions()).getIds())
- .isEmpty();
+ .isEmpty();
// 6. get Overridden Rules on profile2
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY2)
.setInheritance(ImmutableSet.of(OVERRIDES.name())),
new SearchOptions()).getIds())
- .hasSize(1);
+ .hasSize(1);
// 7. get Inherited AND Overridden Rules on profile1
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY1)
.setInheritance(ImmutableSet.of(INHERITED.name(), OVERRIDES.name())),
new SearchOptions()).getIds())
- .isEmpty();
+ .isEmpty();
// 8. get Inherited AND Overridden Rules on profile2
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY2)
.setInheritance(ImmutableSet.of(INHERITED.name(), OVERRIDES.name())),
new SearchOptions()).getIds())
- .hasSize(3);
+ .hasSize(3);
}
@Test
// 2 Facet with a language filter
// -- lang facet should still have all language
- result = index.search(new RuleQuery().setLanguages(ImmutableList.of("cpp"))
- , new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
+ result = index.search(new RuleQuery().setLanguages(ImmutableList.of("cpp")), new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
assertThat(result.getIds()).hasSize(3);
assertThat(result.getFacets().getAll()).hasSize(3);
assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java", "cobol");
// -- repository for cpp & T2
result = index.search(new RuleQuery()
.setLanguages(ImmutableList.of("cpp"))
- .setTags(ImmutableList.of("T2"))
- , new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
+ .setTags(ImmutableList.of("T2")), new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
assertThat(result.getIds()).hasSize(1);
assertThat(result.getFacets().getAll()).hasSize(3);
assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java");
result = index.search(new RuleQuery()
.setLanguages(ImmutableList.of("cpp", "java"))
.setTags(ImmutableList.of("T2"))
- .setTypes(asList(BUG, CODE_SMELL))
- , new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS, FACET_TYPES)));
+ .setTypes(asList(BUG, CODE_SMELL)), new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS, FACET_TYPES)));
assertThat(result.getIds()).hasSize(2);
assertThat(result.getFacets().getAll()).hasSize(4);
assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java");
assertThat(index.searchAll(new RuleQuery().setQueryText("javascript:X001"))).hasSize(1);
}
+ @Test
+ public void search_all_keys_by_profile() {
+ indexRules(
+ newDoc(RULE_KEY_1),
+ newDoc(RULE_KEY_2),
+ newDoc(RULE_KEY_3));
+
+ indexActiveRules(
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)));
+
+ assertThat(tester.countDocuments(INDEX, TYPE_ACTIVE_RULE)).isEqualTo(3);
+
+ // 1. get all active rules.
+ assertThat(index.searchAll(new RuleQuery().setActivation(true))).containsOnly(RULE_KEY_1, RULE_KEY_2);
+
+ // 2. get all inactive rules.
+ assertThat(index.searchAll(new RuleQuery().setActivation(false))).containsOnly(RULE_KEY_3);
+
+ // 3. get all rules not active on profile
+ assertThat(index.searchAll(new RuleQuery().setActivation(false).setQProfileKey(QUALITY_PROFILE_KEY2))).containsOnly(RULE_KEY_2, RULE_KEY_3);
+
+ // 4. get all active rules on profile
+ assertThat(index.searchAll(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY2))).containsOnly(RULE_KEY_1);
+ }
+
private void indexRules(RuleDoc... rules) {
ruleIndexer.index(asList(rules).iterator());
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.server.rule.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.server.rule.index.RuleQuery;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.WsAction;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.rule.RuleStatus.DEPRECATED;
+import static org.sonar.api.rule.RuleStatus.READY;
+import static org.sonar.api.rule.Severity.CRITICAL;
+import static org.sonar.api.rule.Severity.MAJOR;
+import static org.sonar.api.rule.Severity.MINOR;
+import static org.sonar.api.rules.RuleType.BUG;
+import static org.sonar.api.rules.RuleType.CODE_SMELL;
+import static org.sonar.api.server.ws.WebService.Param.ASCENDING;
+import static org.sonar.api.server.ws.WebService.Param.SORT;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonar.db.qualityprofile.ActiveRuleDto.INHERITED;
+import static org.sonar.db.qualityprofile.ActiveRuleDto.OVERRIDES;
+import static org.sonar.server.rule.ws.SearchAction.defineRuleSearchParameters;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TEMPLATE_KEY;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TYPES;
+
+public class RuleQueryFactoryTest {
+
+ @Rule
+ public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+ DbClient dbClient = dbTester.getDbClient();
+
+ DbSession dbSession = dbTester.getSession();
+
+ RuleQueryFactory underTest = new RuleQueryFactory(dbClient);
+
+ FakeAction fakeAction = new FakeAction(underTest);
+
+ @Test
+ public void create_empty_query() throws Exception {
+ RuleQuery result = execute();
+
+ assertThat(result.getKey()).isNull();
+
+ assertThat(result.getActivation()).isNull();
+ assertThat(result.getActiveSeverities()).isNull();
+ assertThat(result.isAscendingSort()).isTrue();
+ assertThat(result.getAvailableSinceLong()).isNull();
+ assertThat(result.getInheritance()).isNull();
+ assertThat(result.isTemplate()).isNull();
+ assertThat(result.getLanguages()).isNull();
+ assertThat(result.getQueryText()).isNull();
+ assertThat(result.getQProfileKey()).isNull();
+ assertThat(result.getRepositories()).isNull();
+ assertThat(result.getRuleKey()).isNull();
+ assertThat(result.getSeverities()).isNull();
+ assertThat(result.getStatuses()).isEmpty();
+ assertThat(result.getTags()).isNull();
+ assertThat(result.templateKey()).isNull();
+ assertThat(result.getTypes()).isEmpty();
+
+ assertThat(result.getSortField()).isNull();
+ }
+
+ @Test
+ public void create_query() throws Exception {
+ RuleQuery result = execute(
+ PARAM_RULE_KEY, "ruleKey",
+
+ PARAM_ACTIVATION, "true",
+ PARAM_ACTIVE_SEVERITIES, "MINOR,MAJOR",
+ PARAM_AVAILABLE_SINCE, "2016-01-01",
+ PARAM_INHERITANCE, "INHERITED,OVERRIDES",
+ PARAM_IS_TEMPLATE, "true",
+ PARAM_LANGUAGES, "java,js",
+ TEXT_QUERY, "S001",
+ PARAM_QPROFILE, "sonar-way",
+ PARAM_REPOSITORIES, "pmd,checkstyle",
+ PARAM_SEVERITIES, "MINOR,CRITICAL",
+ PARAM_STATUSES, "DEPRECATED,READY",
+ PARAM_TAGS, "tag1,tag2",
+ PARAM_TEMPLATE_KEY, "architectural",
+ PARAM_TYPES, "CODE_SMELL,BUG",
+
+ SORT, "updatedAt",
+ ASCENDING, "false");
+
+ assertThat(result.getKey()).isEqualTo("ruleKey");
+
+ assertThat(result.getActivation()).isTrue();
+ assertThat(result.getActiveSeverities()).containsOnly(MINOR, MAJOR);
+ assertThat(result.isAscendingSort()).isFalse();
+ assertThat(result.getAvailableSinceLong()).isNotNull();
+ assertThat(result.getInheritance()).containsOnly(INHERITED, OVERRIDES);
+ assertThat(result.isTemplate()).isTrue();
+ assertThat(result.getLanguages()).containsOnly("java", "js");
+ assertThat(result.getQueryText()).isEqualTo("S001");
+ assertThat(result.getQProfileKey()).isEqualTo("sonar-way");
+ assertThat(result.getRepositories()).containsOnly("pmd", "checkstyle");
+ assertThat(result.getRuleKey()).isNull();
+ assertThat(result.getSeverities()).containsOnly(MINOR, CRITICAL);
+ assertThat(result.getStatuses()).containsOnly(DEPRECATED, READY);
+ assertThat(result.getTags()).containsOnly("tag1", "tag2");
+ assertThat(result.templateKey()).isEqualTo("architectural");
+ assertThat(result.getTypes()).containsOnly(BUG, CODE_SMELL);
+
+ assertThat(result.getSortField()).isEqualTo("updatedAt");
+ }
+
+ @Test
+ public void create_query_add_language_from_profile() throws Exception {
+ String profileKey = "sonar-way";
+ dbClient.qualityProfileDao().insert(dbSession, QualityProfileDto.createFor(profileKey).setName("Sonar Way").setLanguage("xoo"));
+ dbSession.commit();
+
+ RuleQuery result = execute(
+ PARAM_QPROFILE, profileKey,
+ PARAM_LANGUAGES, "java,js");
+
+ assertThat(result.getQProfileKey()).isEqualTo(profileKey);
+ assertThat(result.getLanguages()).containsOnly("xoo");
+ }
+
+ private RuleQuery execute(String... paramsKeyAndValue) {
+ WsActionTester ws = new WsActionTester(fakeAction);
+ TestRequest request = ws.newRequest();
+ for (int i = 0; i < paramsKeyAndValue.length; i += 2) {
+ request.setParam(paramsKeyAndValue[i], paramsKeyAndValue[i + 1]);
+ }
+ request.execute();
+ return fakeAction.getRuleQuery();
+ }
+
+ private static class FakeAction implements WsAction {
+
+ private final RuleQueryFactory ruleQueryFactory;
+ private RuleQuery ruleQuery;
+
+ private FakeAction(RuleQueryFactory ruleQueryFactory) {
+ this.ruleQueryFactory = ruleQueryFactory;
+ }
+
+ @Override
+ public void define(WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction("fake")
+ .setHandler(this);
+ defineRuleSearchParameters(action);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ ruleQuery = ruleQueryFactory.createRuleQuery(request);
+ }
+
+ RuleQuery getRuleQuery() {
+ return ruleQuery;
+ }
+ }
+}
--- /dev/null
+{
+ "succeeded": 4,
+ "failed": 0
+}
--- /dev/null
+{
+ "succeeded": 2,
+ "failed": 0
+}
--- /dev/null
+{
+ "succeeded": 2,
+ "failed": 0
+}
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;