A new elasticsearch type “ruleExtension” is added to the rules index. It stores either system tags, or tags for one, specific organization.
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.RowNotFoundException;
+import org.sonar.db.organization.OrganizationDto;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
return Optional.fromNullable(mapper(session).selectDefinitionByKey(key));
}
+ public java.util.Optional<RuleMetadataDto> selectMetadataByKey(DbSession session, RuleKey key, OrganizationDto organization) {
+ return java.util.Optional.ofNullable(mapper(session).selectMetadataByKey(key, organization.getUuid()));
+ }
+
public RuleDto selectOrFailByKey(DbSession session, String organizationUuid, RuleKey key) {
RuleDto rule = mapper(session).selectByKey(organizationUuid, key);
if (rule == null) {
mapper(session).insertDefinition(dto);
}
+ public void insert(DbSession session, RuleMetadataDto dto) {
+ mapper(session).insertMetadata(dto);
+ }
+
public void update(DbSession session, RuleDefinitionDto dto) {
mapper(session).updateDefinition(dto);
}
RuleDefinitionDto selectDefinitionByKey(RuleKey ruleKey);
+ RuleMetadataDto selectMetadataByKey(@Param("ruleKey") RuleKey ruleKey, @Param("organizationUuid") String organizationUuid);
+
List<RuleDto> selectByKeys(@Param("organizationUuid") String organizationUuid, @Param("ruleKeys") List<RuleKey> keys);
List<RuleDefinitionDto> selectDefinitionByKeys(@Param("ruleKeys") List<RuleKey> keys);
and r.plugin_rule_key=#{rule,jdbcType=VARCHAR}
</select>
+ <select id="selectMetadataByKey" parameterType="map" resultType="org.sonar.db.rule.RuleMetadataDto">
+ select
+ rm.rule_id as "ruleId",
+ rm.organization_uuid as "organizationUuid",
+ rm.note_data as "noteData",
+ rm.note_user_login as "noteUserLogin",
+ rm.note_created_at as "noteCreatedAt",
+ rm.note_updated_at as "noteUpdatedAt",
+ rm.remediation_function as "remediationFunction",
+ rm.remediation_gap_mult as "remediationGapMultiplier",
+ rm.remediation_base_effort as "remediationBaseEffort",
+ rm.tags as "tagsField",
+ rm.created_at as "createdAt",
+ rm.updated_at as "updatedAt"
+ from
+ rules_metadata rm
+ inner join rules r on rm.rule_id = r.id
+ where
+ r.plugin_name=#{ruleKey.repository,jdbcType=VARCHAR}
+ and r.plugin_rule_key=#{ruleKey.rule,jdbcType=VARCHAR}
+ and rm.organization_uuid = #{organizationUuid,jdbcType=VARCHAR}
+ </select>
+
<select id="selectByKeys" parameterType="map" resultType="Rule">
select
<include refid="selectJoinedTablesColumns"/>
private QualityProfileDto profile1 = QualityProfileDto.createFor("qp1").setOrganizationUuid(organization.getUuid()).setName("QProfile1");
private QualityProfileDto profile2 = QualityProfileDto.createFor("qp2").setOrganizationUuid(organization.getUuid()).setName("QProfile2");
- private RuleDefinitionDto rule1 = RuleTesting.newDto(RuleTesting.XOO_X1).getDefinition();
- private RuleDefinitionDto rule2 = RuleTesting.newDto(RuleTesting.XOO_X2).getDefinition();
- private RuleDefinitionDto rule3 = RuleTesting.newDto(RuleTesting.XOO_X3).getDefinition();
+ private RuleDefinitionDto rule1 = RuleTesting.newRule(RuleTesting.XOO_X1);
+ private RuleDefinitionDto rule2 = RuleTesting.newRule(RuleTesting.XOO_X2);
+ private RuleDefinitionDto rule3 = RuleTesting.newRule(RuleTesting.XOO_X3);
private RuleParamDto rule1Param1;
private RuleParamDto rule1Param2;
@Test
public void select_by_profile_ignore_removed_rules() throws Exception {
- RuleDefinitionDto removedRule = RuleTesting.newDto(RuleKey.of("removed", "rule")).setStatus(RuleStatus.REMOVED).getDefinition();
+ RuleDefinitionDto removedRule = RuleTesting.newRule(RuleKey.of("removed", "rule")).setStatus(RuleStatus.REMOVED);
dbTester.rules().insert(removedRule);
ActiveRuleDto activeRule = createFor(profile1, removedRule).setSeverity(BLOCKER);
underTest.insert(dbTester.getSession(), activeRule);
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
+import static org.sonar.db.rule.RuleTesting.newRule;
import static org.sonar.db.rule.RuleTesting.newRuleDto;
public class RuleDbTester {
}
public RuleDefinitionDto insert() {
- return insert(RuleTesting.newRule());
+ return insert(newRule());
}
public RuleDefinitionDto insert(RuleKey key) {
- return insert(RuleTesting.newRule(key));
+ return insert(newRule(key));
}
- public RuleDefinitionDto insert(Consumer<RuleDefinitionDto> populater) {
- RuleDefinitionDto rule = RuleTesting.newRule();
- populater.accept(rule);
+ @SafeVarargs
+ public final RuleDefinitionDto insert(Consumer<RuleDefinitionDto>... populaters) {
+ RuleDefinitionDto rule = newRule();
+ Arrays.asList(populaters).forEach(populater -> populater.accept(rule));
return insert(rule);
}
public RuleDefinitionDto insert(RuleKey key, Consumer<RuleDefinitionDto> populater) {
- RuleDefinitionDto rule = RuleTesting.newRule(key);
+ RuleDefinitionDto rule = newRule(key);
populater.accept(rule);
return insert(rule);
}
return rule;
}
- public RuleMetadataDto insertOrUpdateMetadata(RuleDefinitionDto rule, OrganizationDto organization) {
- return insertOrUpdateMetadata(rule, organization, r -> {});
- }
-
- public RuleMetadataDto insertOrUpdateMetadata(RuleDefinitionDto rule, OrganizationDto organization, Consumer<RuleMetadataDto> populater) {
+ @SafeVarargs
+ public final RuleMetadataDto insertOrUpdateMetadata(RuleDefinitionDto rule, OrganizationDto organization, Consumer<RuleMetadataDto>... populaters) {
RuleMetadataDto dto = RuleTesting.newRuleMetadata(rule, organization);
- populater.accept(dto);
+ Arrays.asList(populaters).forEach(populater -> populater.accept(dto));
return insertOrUpdateMetadata(dto);
}
}
public RuleDto insertRule(RuleDto ruleDto) {
- RuleDao ruleDao = db.getDbClient().ruleDao();
- ruleDao.insert(db.getSession(), ruleDto.getDefinition());
- db.commit();
+ insert(ruleDto.getDefinition());
RuleMetadataDto metadata = ruleDto.getMetadata();
if (metadata.getOrganizationUuid() != null) {
- ruleDao.insertOrUpdate(db.getSession(), metadata.setRuleId(ruleDto.getId()));
+ db.getDbClient().ruleDao().insertOrUpdate(db.getSession(), metadata.setRuleId(ruleDto.getId()));
db.commit();
}
return ruleDto;
});
}
- public RuleDto insertRule(OrganizationDto organization, Consumer<RuleDto>... populaters) {
+ @SafeVarargs
+ public final RuleDto insertRule(OrganizationDto organization, Consumer<RuleDto>... populaters) {
RuleDto ruleDto = newRuleDto(organization);
Arrays.asList(populaters).forEach(populater -> populater.accept(ruleDto));
return insertRule(ruleDto);
import com.google.common.collect.ImmutableSet;
import java.util.Date;
+import java.util.function.Consumer;
import javax.annotation.Nullable;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.db.rule.RuleDto.Format;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.ImmutableSet.copyOf;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
.setIsTemplate(true);
}
+ /**
+ * @deprecated use {@link #newCustomRule(RuleDefinitionDto)}
+ */
+ @Deprecated
public static RuleDto newCustomRule(RuleDto templateRule) {
checkNotNull(templateRule.getId(), "The template rule need to be persisted before creating this custom rule.");
return newDto(RuleKey.of(templateRule.getRepositoryKey(), templateRule.getRuleKey() + "_" + System.currentTimeMillis()))
.setType(templateRule.getType());
}
+ public static RuleDefinitionDto newCustomRule(RuleDefinitionDto templateRule) {
+ checkNotNull(templateRule.getId(), "The template rule need to be persisted before creating this custom rule.");
+ return newRule(RuleKey.of(templateRule.getRepositoryKey(), templateRule.getRuleKey() + "_" + System.currentTimeMillis()))
+ .setLanguage(templateRule.getLanguage())
+ .setTemplateId(templateRule.getId())
+ .setType(templateRule.getType());
+ }
+
public static RuleKey randomRuleKey() {
return RuleKey.of("repo_" + randomAlphanumeric(3), "rule_" + randomAlphanumeric(3));
}
+
+ public static Consumer<RuleDefinitionDto> setRepositoryKey(String repositoryKey) {
+ return rule -> rule.setRepositoryKey(repositoryKey);
+ }
+
+ public static Consumer<RuleDefinitionDto> setCreatedAt(long createdAt) {
+ return rule -> rule.setCreatedAt(createdAt);
+ }
+
+ public static Consumer<RuleDefinitionDto> setUpdatedAt(long updatedtAt) {
+ return rule -> rule.setUpdatedAt(updatedtAt);
+ }
+
+ public static Consumer<RuleDefinitionDto> setRuleKey(String ruleKey) {
+ return rule -> rule.setRuleKey(ruleKey);
+ }
+
+ public static Consumer<RuleDefinitionDto> setName(String name) {
+ return rule -> rule.setName(name);
+ }
+
+ public static Consumer<RuleDefinitionDto> setLanguage(String language) {
+ return rule -> rule.setLanguage(language);
+ }
+
+ public static Consumer<RuleDefinitionDto> setSeverity(String severity) {
+ return rule -> rule.setSeverity(severity);
+ }
+
+ public static Consumer<RuleDefinitionDto> setStatus(RuleStatus status) {
+ return rule -> rule.setStatus(status);
+ }
+
+ public static Consumer<RuleDefinitionDto> setType(RuleType type) {
+ return rule -> rule.setType(type);
+ }
+
+ public static Consumer<RuleDefinitionDto> setIsTemplate(boolean isTemplate) {
+ return rule -> rule.setIsTemplate(isTemplate);
+ }
+
+ public static Consumer<RuleDefinitionDto> setTemplateId(@Nullable Integer templateId) {
+ return rule -> rule.setTemplateId(templateId);
+ }
+
+ public static Consumer<RuleDefinitionDto> setSystemTags(String... tags) {
+ return rule -> rule.setSystemTags(copyOf(tags));
+ }
+
+ public static Consumer<RuleMetadataDto> setOrganizationUuid(String organizationUuid) {
+ return rule -> rule.setOrganizationUuid(organizationUuid);
+ }
+
+ public static Consumer<RuleMetadataDto> setTags(String... tags) {
+ return rule -> rule.setTags(copyOf(tags));
+ }
+
}
}
private Set<IndexType> getUninitializedTypes(StartupIndexer indexer) {
- return indexer.getIndexTypes().stream().filter(this::getUninitialized).collect(toSet());
+ return indexer.getIndexTypes().stream().filter(this::isUninitialized).collect(toSet());
}
- private boolean getUninitialized(IndexType indexType) {
+ private boolean isUninitialized(IndexType indexType) {
+ return isUninitialized(indexType, esClient);
+ }
+
+ public static boolean isUninitialized(IndexType indexType, EsClient esClient) {
String setting = esClient.nativeClient().admin().indices().prepareGetSettings(indexType.getIndex()).get().getSetting(indexType.getIndex(),
getInitializedSettingName(indexType));
return !"true".equals(setting);
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
+import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
}
public AggregationBuilder buildStickyFacet(String fieldName, String facetName, Object... selected) {
- return buildStickyFacet(fieldName, facetName, FACET_DEFAULT_SIZE, selected);
+ return buildStickyFacet(fieldName, facetName, t -> t, selected);
+ }
+
+ /**
+ * Creates an aggregation, that will return the top-terms for <code>fieldName</code>.
+ *
+ * It will filter according to the filters of every of the <em>other</em> fields, but will not apply filters to <em>this</em> field (so that the user can see all terms, even
+ * after having chosen for one of the terms).
+ *
+ * If special filtering is required (like for nested types), additional functionality can be passed into the method in the <code>additionalAggregationFilter</code> parameter.
+ *
+ * @param fieldName the name of the field that contains the terms
+ * @param facetName the name of the aggregation (use this for to find the corresponding results in the response)
+ * @param additionalAggregationFilter additional features (like filtering using childQuery)
+ * @param selected the terms, that the user already has selected
+ * @return the (global) aggregation, that can be added on top level of the elasticsearch request
+ */
+ public AggregationBuilder buildStickyFacet(String fieldName, String facetName, Function<TermsBuilder, AggregationBuilder<?>> additionalAggregationFilter, Object... selected) {
+ return buildStickyFacet(fieldName, facetName, FACET_DEFAULT_SIZE, additionalAggregationFilter, selected);
}
public AggregationBuilder buildStickyFacet(String fieldName, String facetName, int size, Object... selected) {
+ return buildStickyFacet(fieldName, facetName, size, t -> t, selected);
+ }
+
+ private AggregationBuilder buildStickyFacet(String fieldName, String facetName, int size, Function<TermsBuilder, AggregationBuilder<?>> additionalAggregationFilter,
+ Object... selected) {
BoolQueryBuilder facetFilter = getStickyFacetFilter(fieldName);
- FilterAggregationBuilder facetTopAggregation = buildTopFacetAggregation(fieldName, facetName, facetFilter, size);
+ FilterAggregationBuilder facetTopAggregation = buildTopFacetAggregation(fieldName, facetName, facetFilter, size, additionalAggregationFilter);
facetTopAggregation = addSelectedItemsToFacet(fieldName, facetName, facetTopAggregation, selected);
return AggregationBuilders
}
public FilterAggregationBuilder buildTopFacetAggregation(String fieldName, String facetName, BoolQueryBuilder facetFilter, int size) {
+ return buildTopFacetAggregation(fieldName, facetName, facetFilter, size, t -> t);
+ }
+
+ private FilterAggregationBuilder buildTopFacetAggregation(String fieldName, String facetName, BoolQueryBuilder facetFilter, int size,
+ Function<TermsBuilder, AggregationBuilder<?>> additionalAggregationFilter) {
+ TermsBuilder termsAggregation = buildTermsFacetAggregation(fieldName, facetName, size);
+ AggregationBuilder<?> innerAggregation = additionalAggregationFilter.apply(termsAggregation);
+ return AggregationBuilders
+ .filter(facetName + "_filter")
+ .filter(facetFilter)
+ .subAggregation(innerAggregation);
+ }
+
+ private TermsBuilder buildTermsFacetAggregation(String fieldName, String facetName, int size) {
TermsBuilder termsAggregation = AggregationBuilders.terms(facetName)
.field(fieldName)
.order(order)
if (subAggregation != null) {
termsAggregation = termsAggregation.subAggregation(subAggregation);
}
- return AggregationBuilders
- .filter(facetName + "_filter")
- .filter(facetFilter)
- .subAggregation(termsAggregation);
+ return termsAggregation;
}
public FilterAggregationBuilder addSelectedItemsToFacet(String fieldName, String facetName, FilterAggregationBuilder facetTopAggregation, Object... selected) {
facetTopAggregation.subAggregation(selectedTerms);
return facetTopAggregation;
}
+
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.issue;
-
-import com.google.common.collect.HashMultiset;
-import com.google.common.collect.Multiset;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.db.rule.RuleDto;
-
-import java.util.Collection;
-
-public class RulesAggregation {
-
- private Multiset<Rule> rules;
-
- public RulesAggregation() {
- this.rules = HashMultiset.create();
- }
-
- public RulesAggregation add(RuleDto ruleDto) {
- rules.add(new Rule(ruleDto.getKey(), ruleDto.getName()));
- return this;
- }
-
- public Collection<Rule> rules() {
- return rules.elementSet();
- }
-
- public int countRule(Rule rule) {
- return rules.count(rule);
- }
-
- public static class Rule {
-
- private RuleKey ruleKey;
- private String name;
-
- public Rule(RuleKey ruleKey, String name) {
- this.ruleKey = ruleKey;
- this.name = name;
- }
-
- public RuleKey ruleKey() {
- return ruleKey;
- }
-
- public String name() {
- return name;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- Rule rule = (Rule) o;
-
- if (!ruleKey.equals(rule.ruleKey)) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return ruleKey.hashCode();
- }
- }
-}
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
-import java.util.SortedSet;
import java.util.TimeZone;
import java.util.regex.Pattern;
import javax.annotation.CheckForNull;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
-import org.elasticsearch.search.aggregations.bucket.global.Global;
-import org.elasticsearch.search.aggregations.bucket.global.GlobalBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Order;
import org.sonar.server.es.StickyFacetBuilder;
import org.sonar.server.issue.IssueQuery;
import org.sonar.server.permission.index.AuthorizationTypeSupport;
-import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.user.UserSession;
import org.sonar.server.view.index.ViewIndexDefinition;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
import static org.sonar.server.es.EsUtils.escapeSpecialRegexChars;
+import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_ORGANIZATION_UUID;
+import static org.sonar.server.issue.index.IssueIndexDefinition.INDEX_TYPE_ISSUE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_FACET_MODE_DEBT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_PARAM_ACTION_PLANS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_ASSIGNED_TO_ME;
return new IssueDoc(input);
}
};
+ public static final String AGGREGATION_NAME_FOR_TAGS = "tags__issues";
private final Sorting sorting;
private final EsClient client;
this.system = system;
this.userSession = userSession;
this.authorizationTypeSupport = authorizationTypeSupport;
+
this.sorting = new Sorting();
this.sorting.add(IssueQuery.SORT_BY_ASSIGNEE, IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE);
this.sorting.add(IssueQuery.SORT_BY_STATUS, IssueIndexDefinition.FIELD_ISSUE_STATUS);
public SearchResult<IssueDoc> search(IssueQuery query, SearchOptions options) {
SearchRequestBuilder requestBuilder = client
- .prepareSearch(IssueIndexDefinition.INDEX_TYPE_ISSUE);
+ .prepareSearch(INDEX_TYPE_ISSUE);
configureSorting(query, requestBuilder);
configurePagination(options, requestBuilder);
private Optional<Long> getMinCreatedAt(Map<String, QueryBuilder> filters, QueryBuilder esQuery) {
String facetNameAndField = IssueIndexDefinition.FIELD_ISSUE_FUNC_CREATED_AT;
SearchRequestBuilder esRequest = client
- .prepareSearch(IssueIndexDefinition.INDEX_TYPE_ISSUE)
+ .prepareSearch(INDEX_TYPE_ISSUE)
.setSize(0);
BoolQueryBuilder esFilter = boolQuery();
filters.values().stream().filter(Objects::nonNull).forEach(esFilter::must);
return value == null ? null : termQuery(field, value);
}
- public List<String> listTags(@Nullable String textQuery, int maxNumberOfTags) {
+ public List<String> listTags(String organizationUuid, @Nullable String textQuery, int maxNumberOfTags) {
SearchRequestBuilder requestBuilder = client
- .prepareSearch(IssueIndexDefinition.INDEX_TYPE_ISSUE, RuleIndexDefinition.INDEX_TYPE_RULE);
-
- requestBuilder.setQuery(boolQuery().must(matchAllQuery()).filter(createBoolFilter(
- IssueQuery.builder().checkAuthorization(false).build())));
-
- GlobalBuilder topAggreg = AggregationBuilders.global("tags");
- String tagsOnIssuesSubAggregation = "tags__issues";
- String tagsOnRulesSubAggregation = "tags__rules";
+ .prepareSearch(INDEX_TYPE_ISSUE)
+ .setQuery(boolQuery()
+ .filter(termQuery(FIELD_ISSUE_ORGANIZATION_UUID, organizationUuid)))
+ .setSize(0);
- TermsBuilder issueTags = AggregationBuilders.terms(tagsOnIssuesSubAggregation)
+ TermsBuilder termsAggregation = AggregationBuilders.terms(AGGREGATION_NAME_FOR_TAGS)
.field(IssueIndexDefinition.FIELD_ISSUE_TAGS)
.size(maxNumberOfTags)
.order(Terms.Order.term(true))
.minDocCount(1L);
- TermsBuilder ruleTags = AggregationBuilders.terms(tagsOnRulesSubAggregation)
- .field(RuleIndexDefinition.FIELD_RULE_ALL_TAGS)
- .size(maxNumberOfTags)
- .order(Terms.Order.term(true))
- .minDocCount(1L);
if (textQuery != null) {
String escapedTextQuery = escapeSpecialRegexChars(textQuery);
- issueTags.include(format(SUBSTRING_MATCH_REGEXP, escapedTextQuery));
- ruleTags.include(format(SUBSTRING_MATCH_REGEXP, escapedTextQuery));
+ termsAggregation.include(format(SUBSTRING_MATCH_REGEXP, escapedTextQuery));
}
+ requestBuilder.addAggregation(termsAggregation);
- SearchResponse searchResponse = requestBuilder.addAggregation(topAggreg.subAggregation(issueTags).subAggregation(ruleTags)).get();
- Global allTags = searchResponse.getAggregations().get("tags");
- SortedSet<String> result = Sets.newTreeSet();
- Terms issuesResult = allTags.getAggregations().get(tagsOnIssuesSubAggregation);
- Terms rulesResult = allTags.getAggregations().get(tagsOnRulesSubAggregation);
- result.addAll(EsUtils.termsKeys(issuesResult));
- result.addAll(EsUtils.termsKeys(rulesResult));
- List<String> resultAsList = Lists.newArrayList(result);
- return resultAsList.size() > maxNumberOfTags && maxNumberOfTags > 0 ? resultAsList.subList(0, maxNumberOfTags) : resultAsList;
+ SearchResponse searchResponse = requestBuilder.get();
+ Terms issuesResult = searchResponse.getAggregations().get(AGGREGATION_NAME_FOR_TAGS);
+ return EsUtils.termsKeys(issuesResult);
}
public Map<String, Long> countTags(IssueQuery query, int maxNumberOfTags) {
private Terms listTermsMatching(String fieldName, IssueQuery query, @Nullable String textQuery, Terms.Order termsOrder, int maxNumberOfTags) {
SearchRequestBuilder requestBuilder = client
- .prepareSearch(IssueIndexDefinition.INDEX_TYPE_ISSUE)
+ .prepareSearch(INDEX_TYPE_ISSUE)
// Avoids returning search hits
.setSize(0);
}
SearchRequestBuilder requestBuilder = client
- .prepareSearch(IssueIndexDefinition.INDEX_TYPE_ISSUE)
+ .prepareSearch(INDEX_TYPE_ISSUE)
.setSearchType(SearchType.SCAN)
.setScroll(TimeValue.timeValueMinutes(EsUtils.SCROLL_TIME_IN_MINUTES))
.setSize(10_000)
*/
package org.sonar.server.issue.ws;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import com.google.common.io.Resources;
+import java.util.Collection;
import java.util.List;
+import java.util.SortedSet;
import javax.annotation.Nullable;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.rule.index.RuleIndex;
import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
public class TagsAction implements IssuesWsAction {
private final IssueIndex issueIndex;
+ private final RuleIndex ruleIndex;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
- public TagsAction(IssueIndex issueIndex) {
+ public TagsAction(IssueIndex issueIndex, RuleIndex ruleIndex, DefaultOrganizationProvider defaultOrganizationProvider) {
this.issueIndex = issueIndex;
+ this.ruleIndex = ruleIndex;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
}
@Override
public void handle(Request request, Response response) throws Exception {
String query = request.param(Param.TEXT_QUERY);
int pageSize = request.mandatoryParamAsInt("ps");
- List<String> tags = listTags(query, pageSize);
+ List<String> tags = listTags(query, pageSize == 0 ? Integer.MAX_VALUE : pageSize);
writeTags(response, tags);
}
private List<String> listTags(@Nullable String textQuery, int pageSize) {
- return issueIndex.listTags(textQuery, pageSize);
+ Collection<String> issueTags = issueIndex.listTags(defaultOrganizationProvider.get().getUuid(), textQuery, pageSize);
+ Collection<String> ruleTags = ruleIndex.listTags(defaultOrganizationProvider.get().getUuid(), textQuery, pageSize);
+
+ SortedSet<String> result = Sets.newTreeSet();
+ result.addAll(issueTags);
+ result.addAll(ruleTags);
+ List<String> resultAsList = Lists.newArrayList(result);
+ return resultAsList.size() > pageSize && pageSize > 0 ? resultAsList.subList(0, pageSize) : resultAsList;
}
private static void writeTags(Response response, List<String> tags) {
import org.sonar.server.rule.RuleUpdater;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.rule.index.RuleIteratorFactory;
import org.sonar.server.rule.ws.ActiveRuleCompleter;
import org.sonar.server.rule.ws.RepositoriesAction;
import org.sonar.server.rule.ws.RuleMapper;
// rule
RuleIndexDefinition.class,
RuleIndexer.class,
- RuleIteratorFactory.class,
AnnotationRuleParser.class,
XMLRuleParser.class,
DefaultRuleFinder.class,
import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.commons.lang.StringUtils.containsIgnoreCase;
-import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_ORGANIZATION_UUID;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_ORGANIZATION_UUID;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_CREATED_AT;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_KEY;
}
String organizationUuid() {
- return getField(FIELD_ACTIVE_ORGANIZATION_UUID);
+ return getField(FIELD_ACTIVE_RULE_ORGANIZATION_UUID);
}
public ActiveRuleDoc setOrganizationUuid(String s) {
- setField(FIELD_ACTIVE_ORGANIZATION_UUID, s);
+ setField(FIELD_ACTIVE_RULE_ORGANIZATION_UUID, s);
return this;
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.ActiveRuleParamDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto.Format;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.db.rule.RuleRepositoryDto;
-import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.qualityprofile.ActiveRuleChange;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
private final ActiveRuleIndexer activeRuleIndexer;
private final Languages languages;
private final System2 system2;
- private final DefaultOrganizationProvider defaultOrganizationProvider;
public RegisterRules(RuleDefinitionsLoader defLoader, RuleActivator ruleActivator, DbClient dbClient, RuleIndexer ruleIndexer,
- ActiveRuleIndexer activeRuleIndexer, Languages languages, System2 system2, DefaultOrganizationProvider defaultOrganizationProvider) {
+ ActiveRuleIndexer activeRuleIndexer, Languages languages, System2 system2) {
this.defLoader = defLoader;
this.ruleActivator = ruleActivator;
this.dbClient = dbClient;
this.activeRuleIndexer = activeRuleIndexer;
this.languages = languages;
this.system2 = system2;
- this.defaultOrganizationProvider = defaultOrganizationProvider;
}
@Override
List<RuleDefinitionDto> removedRules = processRemainingDbRules(allRules.values(), session);
List<ActiveRuleChange> changes = removeActiveRulesOnStillExistingRepositories(session, removedRules, context);
session.commit();
+ keysToIndex.addAll(removedRules.stream().map(RuleDefinitionDto::getKey).collect(Collectors.toList()));
persistRepositories(session, context.repositories());
- ruleIndexer.delete(removedRules.stream().map(RuleDefinitionDto::getKey).collect(MoreCollectors.toList(removedRules.size())));
- ruleIndexer.index(getDefaultOrganization(), keysToIndex);
+ ruleIndexer.indexRuleDefinitions(keysToIndex);
activeRuleIndexer.index(changes);
profiler.stopDebug();
}
}
- private OrganizationDto getDefaultOrganization() {
- try (DbSession dbSession = dbClient.openSession(false)) {
- return dbClient.organizationDao().selectByUuid(dbSession, defaultOrganizationProvider.get().getUuid())
- .orElseThrow(() -> new IllegalStateException("Cannot load default organization"));
- }
- }
-
private void persistRepositories(DbSession dbSession, List<RulesDefinition.Repository> repositories) {
dbClient.ruleRepositoryDao().truncate(dbSession);
List<RuleRepositoryDto> dtos = repositories
.orElseGet(() -> createCustomRule(customRuleKey, newRule, templateRule, dbSession));
dbSession.commit();
- ruleIndexer.index(defaultOrganization, customRuleKey);
+ ruleIndexer.indexRuleDefinition(customRuleKey);
return customRuleKey;
}
dbClient.ruleDao().update(dbSession, rule);
dbSession.commit();
- ruleIndexer.delete(ruleKey);
+ ruleIndexer.indexRuleDefinition(ruleKey);
}
}
}
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.ActiveRuleParamDto;
import org.sonar.db.rule.RuleDefinitionDto;
return false;
}
- String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid();
- OrganizationDto organization = dbClient.organizationDao().selectByUuid(dbSession, defaultOrganizationUuid)
- .orElseThrow(() -> new IllegalStateException(String.format("Could not find default organization '%s'", defaultOrganizationUuid)));
-
RuleDto rule = getRuleDto(update);
// validate only the changes, not all the rule fields
apply(update, rule, userSession);
update(dbSession, rule);
updateParameters(dbSession, update, rule);
dbSession.commit();
- ruleIndexer.index(organization, rule.getKey());
+
+ ruleIndexer.indexRuleDefinition(rule.getKey());
return true;
}
package org.sonar.server.rule.index;
import com.google.common.collect.Maps;
-import java.util.Collection;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
}
public RuleDoc() {
- super(Maps.newHashMapWithExpectedSize(16));
+ super(Maps.newHashMapWithExpectedSize(15));
}
@Override
return this;
}
- public Collection<String> allTags() {
- return getField(RuleIndexDefinition.FIELD_RULE_ALL_TAGS);
- }
-
- public RuleDoc setAllTags(@Nullable Collection<String> l) {
- setField(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, l);
- return this;
- }
-
public RuleType type() {
return RuleType.valueOf(getField(RuleIndexDefinition.FIELD_RULE_TYPE));
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.rule.index;
+
+public class RuleDocWithSystemScope {
+
+ private final RuleDoc ruleDoc;
+ private final RuleExtensionDoc ruleExtensionDoc;
+
+ public RuleDocWithSystemScope(RuleDoc ruleDoc, RuleExtensionDoc ruleExtensionDoc) {
+ this.ruleDoc = ruleDoc;
+ this.ruleExtensionDoc = ruleExtensionDoc;
+ }
+
+ public RuleDoc getRuleDoc() {
+ return ruleDoc;
+ }
+
+ public RuleExtensionDoc getRuleExtensionDoc() {
+ return ruleExtensionDoc;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.rule.index;
+
+import com.google.common.collect.Maps;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang.builder.ReflectionToStringBuilder;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.db.rule.RuleMetadataDto;
+import org.sonar.server.es.BaseDoc;
+
+public class RuleExtensionDoc extends BaseDoc {
+
+ public RuleExtensionDoc(Map<String, Object> fields) {
+ super(fields);
+ }
+
+ public RuleExtensionDoc() {
+ super(Maps.newHashMapWithExpectedSize(4));
+ }
+
+ @Override
+ public String getId() {
+ // the Id is generated by elasticsearch
+ return null;
+ }
+
+ @Override
+ public String getRouting() {
+ return null;
+ }
+
+ @Override
+ public String getParent() {
+ return getRuleKey().toString();
+ }
+
+ public RuleKey getRuleKey() {
+ return getField(RuleIndexDefinition.FIELD_RULE_EXTENSION_RULE_KEY);
+ }
+
+ public RuleExtensionDoc setRuleKey(RuleKey ruleKey) {
+ setField(RuleIndexDefinition.FIELD_RULE_EXTENSION_RULE_KEY, ruleKey);
+ return this;
+ }
+
+ public RuleExtensionScope getScope() {
+ return RuleExtensionScope.parse(getField(RuleIndexDefinition.FIELD_RULE_EXTENSION_SCOPE));
+ }
+
+ public RuleExtensionDoc setScope(RuleExtensionScope scope) {
+ setField(RuleIndexDefinition.FIELD_RULE_EXTENSION_SCOPE, scope.getScope());
+ return this;
+ }
+
+ public Set<String> getTags() {
+ return getField(RuleIndexDefinition.FIELD_RULE_EXTENSION_TAGS);
+ }
+
+ public RuleExtensionDoc setTags(Set<String> tags) {
+ setField(RuleIndexDefinition.FIELD_RULE_EXTENSION_TAGS, tags);
+ return this;
+ }
+
+ public static RuleExtensionDoc of(RuleKey key, RuleExtensionScope scope, RuleMetadataDto ruleExtension) {
+ return new RuleExtensionDoc()
+ .setRuleKey(key)
+ .setScope(scope)
+ .setTags(ruleExtension.getTags());
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.rule.index;
+
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.sonar.db.organization.OrganizationDto;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class RuleExtensionScope {
+
+ private static final String FAKE_UUID_FOR_SYSTEM = "system";
+
+ private final Optional<String> organizationUuid;
+
+ private RuleExtensionScope(@Nullable String organizationUuid) {
+ this.organizationUuid = Optional.ofNullable(organizationUuid);
+ }
+
+ public static RuleExtensionScope system() {
+ return new RuleExtensionScope(null);
+ }
+
+ public static RuleExtensionScope organization(OrganizationDto organization) {
+ return organization(organization.getUuid());
+ }
+
+ public static RuleExtensionScope organization(String organizationUuid) {
+ checkArgument(!FAKE_UUID_FOR_SYSTEM.equals(organizationUuid), "The organization uuid '%s' is reserved for to store system tags in the rules index.", FAKE_UUID_FOR_SYSTEM);
+ return new RuleExtensionScope(organizationUuid);
+ }
+
+ public String getScope() {
+ return organizationUuid.orElse(FAKE_UUID_FOR_SYSTEM);
+ }
+
+ public static RuleExtensionScope parse(String scope) {
+ if (FAKE_UUID_FOR_SYSTEM.equals(scope)) {
+ return system();
+ }
+ return new RuleExtensionScope(scope);
+ }
+}
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
+import java.util.function.Function;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.SimpleQueryStringBuilder;
+import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
+import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
+import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.server.es.EsClient;
+import org.sonar.server.es.EsUtils;
import org.sonar.server.es.SearchIdResult;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.es.StickyFacetBuilder;
+import static com.google.common.base.Preconditions.checkArgument;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.simpleQueryStringQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
import static org.sonar.server.es.DefaultIndexSettingsElement.SEARCH_WORDS_ANALYZER;
import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
import static org.sonar.server.es.EsUtils.SCROLL_TIME_IN_MINUTES;
import static org.sonar.server.es.EsUtils.escapeSpecialRegexChars;
import static org.sonar.server.es.EsUtils.scrollIds;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_ORGANIZATION_UUID;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY;
-import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_ALL_TAGS;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CREATED_AT;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_EXTENSION_SCOPE;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_EXTENSION_TAGS;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_HTML_DESCRIPTION;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_INTERNAL_KEY;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_IS_TEMPLATE;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_UPDATED_AT;
import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX_TYPE_ACTIVE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX_TYPE_RULE;
+import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX_TYPE_RULE_EXTENSION;
/**
* The unique entry-point to interact with Elasticsearch index "rules".
Collections2.filter(
Collections2.transform(Arrays.asList(RuleStatus.values()), RuleStatus::toString),
input -> !RuleStatus.REMOVED.toString().equals(input)));
+ private static final String AGGREGATION_NAME_FOR_TAGS = "tagsAggregation";
private final EsClient client;
public RuleIndex(EsClient client) {
.boost(boost);
}
- private static QueryBuilder termAnyQuery(String field, String query, float boost) {
- return QueryBuilders.multiMatchQuery(query,
- field, SEARCH_WORDS_ANALYZER.subField(field))
- .operator(MatchQueryBuilder.Operator.OR)
- .boost(boost);
- }
-
/* Build main filter (match based) */
private static Map<String, QueryBuilder> buildFilters(RuleQuery query) {
}
if (isNotEmpty(query.getTags())) {
- filters.put(FIELD_RULE_ALL_TAGS,
- QueryBuilders.termsQuery(FIELD_RULE_ALL_TAGS, query.getTags()));
+ BoolQueryBuilder q = boolQuery();
+ String organizationUuid = query.getOrganizationUuid();
+ checkArgument(organizationUuid != null, "Cannot filter on tags '%s', if no organization is specified.", query.getTags());
+ query.getTags().stream()
+ .map(tag -> boolQuery()
+ .filter(QueryBuilders.termQuery(FIELD_RULE_EXTENSION_TAGS, tag))
+ .filter(termsQuery(FIELD_RULE_EXTENSION_SCOPE, RuleExtensionScope.system().getScope(), RuleExtensionScope.organization(organizationUuid).getScope())))
+ .map(childQuery -> QueryBuilders.hasChildQuery(INDEX_TYPE_RULE_EXTENSION.getType(), childQuery))
+ .forEach(q::filter);
+ filters.put(FIELD_RULE_EXTENSION_TAGS, q);
}
if (isNotEmpty(query.getTypes())) {
addTermFilter(childrenFilter, FIELD_ACTIVE_RULE_PROFILE_KEY, query.getQProfileKey());
addTermFilter(childrenFilter, FIELD_ACTIVE_RULE_INHERITANCE, query.getInheritance());
addTermFilter(childrenFilter, FIELD_ACTIVE_RULE_SEVERITY, query.getActiveSeverities());
+ addTermFilter(childrenFilter, FIELD_ACTIVE_RULE_ORGANIZATION_UUID, query.getOrganizationUuid());
// ChildQuery
QueryBuilder childQuery;
childQuery = matchAllQuery();
}
- /** Implementation of activation query */
+ /* Implementation of activation query */
if (Boolean.TRUE.equals(query.getActivation())) {
filters.put("activation",
QueryBuilders.hasChildQuery(INDEX_TYPE_ACTIVE_RULE.getType(),
}
if (options.getFacets().contains(FACET_TAGS) || options.getFacets().contains(FACET_OLD_DEFAULT)) {
Collection<String> tags = query.getTags();
+ String organizationUuid = query.getOrganizationUuid();
+ checkArgument(organizationUuid != null, "Cannot use tags facet, if no organization is specified.", query.getTags());
+
+ Function<TermsBuilder, AggregationBuilder<?>> childFeature = termsAggregation -> {
+
+ FilterAggregationBuilder scopeAggregation = AggregationBuilders.filter("scope_filter_for_" + FACET_TAGS).filter(
+ termsQuery(FIELD_RULE_EXTENSION_SCOPE,
+ RuleExtensionScope.system().getScope(),
+ RuleExtensionScope.organization(organizationUuid).getScope()))
+ .subAggregation(termsAggregation);
+
+ return AggregationBuilders.children("children_for_" + FACET_TAGS)
+ .childType(INDEX_TYPE_RULE_EXTENSION.getType())
+ .subAggregation(scopeAggregation);
+ };
+
aggregations.put(FACET_TAGS,
- stickyFacetBuilder.buildStickyFacet(FIELD_RULE_ALL_TAGS, FACET_TAGS,
+ stickyFacetBuilder.buildStickyFacet(FIELD_RULE_EXTENSION_TAGS, FACET_TAGS, childFeature,
(tags == null) ? (new String[0]) : tags.toArray()));
}
if (options.getFacets().contains(FACET_TYPES)) {
.addAggregation(termsAggregation);
SearchResponse esResponse = request.get();
+ return extractAggregationTerms(aggregationKey, esResponse);
+ }
+ private static Set<String> extractAggregationTerms(String aggregationKey, SearchResponse esResponse) {
Set<String> terms = new HashSet<>();
Terms aggregation = esResponse.getAggregations().get(aggregationKey);
if (aggregation != null) {
return terms;
}
+ public Set<String> listTags(String organizationUuid, @Nullable String query, int size) {
+ TermsQueryBuilder scopeFilter = QueryBuilders.termsQuery(
+ FIELD_RULE_EXTENSION_SCOPE,
+ RuleExtensionScope.system().getScope(),
+ RuleExtensionScope.organization(organizationUuid).getScope());
+
+ TermsBuilder termsAggregation = AggregationBuilders.terms(AGGREGATION_NAME_FOR_TAGS)
+ .field(FIELD_RULE_EXTENSION_TAGS)
+ .size(size)
+ .minDocCount(1);
+ Optional.ofNullable(query)
+ .map(EsUtils::escapeSpecialRegexChars)
+ .map(queryString -> ".*" + queryString + ".*")
+ .ifPresent(termsAggregation::include);
+
+ SearchRequestBuilder request = client
+ .prepareSearch(INDEX_TYPE_RULE_EXTENSION)
+ .setQuery(boolQuery().filter(scopeFilter))
+ .setSize(0)
+ .addAggregation(termsAggregation);
+
+ SearchResponse esResponse = request.get();
+ return extractAggregationTerms(AGGREGATION_NAME_FOR_TAGS, esResponse);
+ }
+
private static boolean isNotEmpty(@Nullable Collection list) {
return list != null && !list.isEmpty();
}
-
}
public static final String FIELD_RULE_LANGUAGE = "lang";
public static final String FIELD_RULE_IS_TEMPLATE = "isTemplate";
public static final String FIELD_RULE_TEMPLATE_KEY = "templateKey";
- public static final String FIELD_RULE_ALL_TAGS = "allTags";
public static final String FIELD_RULE_TYPE = "type";
public static final String FIELD_RULE_CREATED_AT = "createdAt";
public static final String FIELD_RULE_UPDATED_AT = "updatedAt";
public static final Set<String> SORT_FIELDS = ImmutableSet.of(
- RuleIndexDefinition.FIELD_RULE_NAME,
- RuleIndexDefinition.FIELD_RULE_UPDATED_AT,
- RuleIndexDefinition.FIELD_RULE_CREATED_AT,
- RuleIndexDefinition.FIELD_RULE_KEY);
+ FIELD_RULE_NAME,
+ FIELD_RULE_UPDATED_AT,
+ FIELD_RULE_CREATED_AT,
+ FIELD_RULE_KEY);
+
+ // Rule extension fields
+ public static final IndexType INDEX_TYPE_RULE_EXTENSION = new IndexType(INDEX, "ruleExtension");
+ /** The uuid of a {@link RuleExtensionScope} */
+ public static final String FIELD_RULE_EXTENSION_SCOPE = "scope";
+ public static final String FIELD_RULE_EXTENSION_RULE_KEY = "ruleKey";
+ public static final String FIELD_RULE_EXTENSION_TAGS = "tags";
// Active rule fields
public static final IndexType INDEX_TYPE_ACTIVE_RULE = new IndexType(INDEX, "activeRule");
- public static final String FIELD_ACTIVE_ORGANIZATION_UUID = "organizationUuid";
+ public static final String FIELD_ACTIVE_RULE_ORGANIZATION_UUID = "organizationUuid";
public static final String FIELD_ACTIVE_RULE_KEY = "key";
public static final String FIELD_ACTIVE_RULE_REPOSITORY = "repo";
public static final String FIELD_ACTIVE_RULE_INHERITANCE = "inheritance";
index.configureShards(settings, 1);
// Active rule type
- NewIndex.NewIndexType activeRuleMapping = index.createType(RuleIndexDefinition.INDEX_TYPE_ACTIVE_RULE.getType());
+ NewIndex.NewIndexType activeRuleMapping = index.createType(INDEX_TYPE_ACTIVE_RULE.getType());
activeRuleMapping.setEnableSource(false);
- activeRuleMapping.setAttribute("_parent", ImmutableMap.of("type", RuleIndexDefinition.INDEX_TYPE_RULE.getType()));
+ activeRuleMapping.setAttribute("_parent", ImmutableMap.of("type", INDEX_TYPE_RULE.getType()));
- activeRuleMapping.stringFieldBuilder(RuleIndexDefinition.FIELD_ACTIVE_ORGANIZATION_UUID).disableNorms().build();
- activeRuleMapping.stringFieldBuilder(RuleIndexDefinition.FIELD_ACTIVE_RULE_KEY).addSubFields(SORTABLE_ANALYZER).build();
- activeRuleMapping.stringFieldBuilder(RuleIndexDefinition.FIELD_ACTIVE_RULE_RULE_KEY).addSubFields(SORTABLE_ANALYZER).build();
- activeRuleMapping.stringFieldBuilder(RuleIndexDefinition.FIELD_ACTIVE_RULE_REPOSITORY).build();
- activeRuleMapping.stringFieldBuilder(RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY).disableNorms().build();
- activeRuleMapping.stringFieldBuilder(RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE).disableNorms().build();
- activeRuleMapping.stringFieldBuilder(RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY).disableNorms().build();
+ activeRuleMapping.stringFieldBuilder(FIELD_ACTIVE_RULE_ORGANIZATION_UUID).disableNorms().build();
+ activeRuleMapping.stringFieldBuilder(FIELD_ACTIVE_RULE_KEY).addSubFields(SORTABLE_ANALYZER).build();
+ activeRuleMapping.stringFieldBuilder(FIELD_ACTIVE_RULE_RULE_KEY).addSubFields(SORTABLE_ANALYZER).build();
+ activeRuleMapping.stringFieldBuilder(FIELD_ACTIVE_RULE_REPOSITORY).build();
+ activeRuleMapping.stringFieldBuilder(FIELD_ACTIVE_RULE_PROFILE_KEY).disableNorms().build();
+ activeRuleMapping.stringFieldBuilder(FIELD_ACTIVE_RULE_INHERITANCE).disableNorms().build();
+ activeRuleMapping.stringFieldBuilder(FIELD_ACTIVE_RULE_SEVERITY).disableNorms().build();
- activeRuleMapping.createLongField(RuleIndexDefinition.FIELD_ACTIVE_RULE_CREATED_AT);
- activeRuleMapping.createLongField(RuleIndexDefinition.FIELD_ACTIVE_RULE_UPDATED_AT);
+ activeRuleMapping.createLongField(FIELD_ACTIVE_RULE_CREATED_AT);
+ activeRuleMapping.createLongField(FIELD_ACTIVE_RULE_UPDATED_AT);
+
+ // Rule extension type
+ NewIndex.NewIndexType ruleExtensionType = index.createType(INDEX_TYPE_RULE_EXTENSION.getType());
+ ruleExtensionType.setEnableSource(false);
+ ruleExtensionType.setAttribute("_parent", ImmutableMap.of("type", INDEX_TYPE_RULE.getType()));
+
+ ruleExtensionType.stringFieldBuilder(FIELD_RULE_EXTENSION_SCOPE).disableNorms().build();
+ ruleExtensionType.stringFieldBuilder(FIELD_RULE_EXTENSION_RULE_KEY).disableNorms().build();
+ ruleExtensionType.stringFieldBuilder(FIELD_RULE_EXTENSION_TAGS).build();
// Rule type
- NewIndex.NewIndexType ruleMapping = index.createType(RuleIndexDefinition.INDEX_TYPE_RULE.getType());
+ NewIndex.NewIndexType ruleMapping = index.createType(INDEX_TYPE_RULE.getType());
ruleMapping.setEnableSource(false);
ruleMapping.stringFieldBuilder(FIELD_RULE_KEY).addSubFields(SORTABLE_ANALYZER).build();
ruleMapping.createBooleanField(FIELD_RULE_IS_TEMPLATE);
ruleMapping.stringFieldBuilder(FIELD_RULE_TEMPLATE_KEY).disableNorms().build();
-
- ruleMapping.stringFieldBuilder(FIELD_RULE_ALL_TAGS).addSubFields(SEARCH_WORDS_ANALYZER).build();
+
ruleMapping.stringFieldBuilder(FIELD_RULE_TYPE).disableNorms().build();
ruleMapping.createLongField(FIELD_RULE_CREATED_AT);
*/
package org.sonar.server.rule.index;
-import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.IndexType;
import org.sonar.server.es.StartupIndexer;
-import org.sonar.server.organization.DefaultOrganizationProvider;
+import static java.util.Collections.singletonList;
import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX_TYPE_RULE;
+import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX_TYPE_RULE_EXTENSION;
public class RuleIndexer implements StartupIndexer {
private final EsClient esClient;
private final DbClient dbClient;
- private final RuleIteratorFactory ruleIteratorFactory;
- private final DefaultOrganizationProvider defaultOrganizationProvider;
- public RuleIndexer(EsClient esClient, DbClient dbClient, RuleIteratorFactory ruleIteratorFactory, DefaultOrganizationProvider defaultOrganizationProvider) {
+ public RuleIndexer(EsClient esClient, DbClient dbClient) {
this.esClient = esClient;
this.dbClient = dbClient;
- this.ruleIteratorFactory = ruleIteratorFactory;
- this.defaultOrganizationProvider = defaultOrganizationProvider;
}
@Override
public Set<IndexType> getIndexTypes() {
- return ImmutableSet.of(INDEX_TYPE_RULE);
+ return ImmutableSet.of(INDEX_TYPE_RULE, INDEX_TYPE_RULE_EXTENSION);
}
@Override
public void indexOnStartup(Set<IndexType> uninitializedIndexTypes) {
BulkIndexer bulk = new BulkIndexer(esClient, RuleIndexDefinition.INDEX).setSize(Size.LARGE);
+ bulk.start();
// index all definitions and system extensions
if (uninitializedIndexTypes.contains(INDEX_TYPE_RULE)) {
- try(DbSession dbSession = dbClient.openSession(false)) {
-
- String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid();
- OrganizationDto defaultOrganization = dbClient.organizationDao().selectByUuid(dbSession, defaultOrganizationUuid)
- .orElseThrow(() -> new IllegalStateException(String.format("Cannot load default organization for uuid '%s'", defaultOrganizationUuid)));
+ try (RuleIterator rules = new RuleIteratorForSingleChunk(dbClient, null)) {
+ doIndexRuleDefinitions(rules, bulk);
+ }
+ }
- try (RuleIterator rules = new RuleIteratorForSingleChunk(dbClient, defaultOrganization, null)) {
- doIndex(bulk, rules);
- }
+ // index all organization extensions
+ if (uninitializedIndexTypes.contains(INDEX_TYPE_RULE_EXTENSION)) {
+ try (RuleMetadataIterator metadatas = new RuleMetadataIterator(dbClient)) {
+ doIndexRuleExtensions(metadatas, bulk);
}
}
+
+ bulk.stop();
}
- public void index(OrganizationDto organization, RuleKey ruleKey) {
- BulkIndexer bulk = createBulkIndexer(Size.REGULAR);
- try (RuleIterator rules = ruleIteratorFactory.createForKey(organization, ruleKey)) {
- doIndex(bulk, rules);
- }
+ public void indexRuleDefinition(RuleKey ruleKey) {
+ indexRuleDefinitions(singletonList(ruleKey));
}
- public void index(OrganizationDto organization, List<RuleKey> ruleKeys) {
- BulkIndexer bulk = createBulkIndexer(Size.REGULAR);
- try (RuleIterator rules = ruleIteratorFactory.createForKeys(organization, ruleKeys)) {
- doIndex(bulk, rules);
+ public void indexRuleDefinitions(List<RuleKey> ruleKeys) {
+ BulkIndexer bulk = new BulkIndexer(esClient, RuleIndexDefinition.INDEX).setSize(Size.REGULAR);
+ bulk.start();
+
+ try (RuleIterator rules = new RuleIteratorForMultipleChunks(dbClient, ruleKeys)) {
+ doIndexRuleDefinitions(rules, bulk);
}
+
+ bulk.stop();
}
- @VisibleForTesting
- public void index(Iterator<RuleDoc> rules) {
- doIndex(createBulkIndexer(Size.REGULAR), rules);
+ public void indexRuleExtension(OrganizationDto organization, RuleKey ruleKey) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ dbClient.ruleDao()
+ .selectMetadataByKey(dbSession, ruleKey, organization)
+ .map(ruleExtension -> RuleExtensionDoc.of(ruleKey, RuleExtensionScope.organization(organization), ruleExtension))
+ .map(Arrays::asList)
+ .map(List::iterator)
+ .ifPresent(metadatas -> {
+ BulkIndexer bulk = new BulkIndexer(esClient, RuleIndexDefinition.INDEX).setSize(Size.REGULAR);
+ bulk.start();
+
+ doIndexRuleExtensions(metadatas, bulk);
+
+ bulk.stop();
+ });
+ }
}
- private static void doIndex(BulkIndexer bulk, Iterator<RuleDoc> rules) {
- bulk.start();
+ private static void doIndexRuleDefinitions(Iterator<RuleDocWithSystemScope> rules, BulkIndexer bulk) {
while (rules.hasNext()) {
- RuleDoc rule = rules.next();
- bulk.add(newIndexRequest(rule));
+ RuleDocWithSystemScope ruleWithExtension = rules.next();
+ bulk.add(newIndexRequest(ruleWithExtension.getRuleDoc()));
+ bulk.add(newIndexRequest(ruleWithExtension.getRuleExtensionDoc()));
}
- bulk.stop();
}
- private BulkIndexer createBulkIndexer(Size size) {
- BulkIndexer bulk = new BulkIndexer(esClient, INDEX_TYPE_RULE.getIndex());
- bulk.setSize(size);
- return bulk;
+ private static void doIndexRuleExtensions(Iterator<RuleExtensionDoc> metadatas, BulkIndexer bulk) {
+ while (metadatas.hasNext()) {
+ RuleExtensionDoc metadata = metadatas.next();
+ bulk.add(newIndexRequest(metadata));
+ }
}
private static IndexRequest newIndexRequest(RuleDoc rule) {
return new IndexRequest(INDEX_TYPE_RULE.getIndex(), INDEX_TYPE_RULE.getType(), rule.key().toString()).source(rule.getFields());
}
- public void delete(RuleKey ruleKey) {
- esClient.prepareDelete(INDEX_TYPE_RULE, ruleKey.toString())
- .setRefresh(true)
- .get();
- }
-
- public void delete(List<RuleKey> rules) {
- BulkIndexer bulk = createBulkIndexer(Size.REGULAR);
- bulk.start();
- for (RuleKey rule : rules) {
- bulk.addDeletion(INDEX_TYPE_RULE, rule.toString());
- }
- bulk.stop();
+ private static IndexRequest newIndexRequest(RuleExtensionDoc ruleExtension) {
+ return new IndexRequest(INDEX_TYPE_RULE_EXTENSION.getIndex(), INDEX_TYPE_RULE_EXTENSION.getType())
+ .source(ruleExtension.getFields())
+ .parent(ruleExtension.getParent());
}
}
import java.util.Iterator;
-public interface RuleIterator extends Iterator<RuleDoc>, AutoCloseable {
+public interface RuleIterator extends Iterator<RuleDocWithSystemScope>, AutoCloseable {
@Override
void close();
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.rule.index;
-
-import java.util.List;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.db.DbClient;
-import org.sonar.db.organization.OrganizationDto;
-
-import static java.util.Arrays.asList;
-
-public class RuleIteratorFactory {
-
- private final DbClient dbClient;
-
- public RuleIteratorFactory(DbClient dbClient) {
- this.dbClient = dbClient;
- }
-
- public RuleIterator createForKey(OrganizationDto organization, RuleKey ruleKey) {
- return new RuleIteratorForSingleChunk(dbClient, organization, asList(ruleKey));
- }
-
- public RuleIterator createForKeys(OrganizationDto organization, List<RuleKey> ruleKeys) {
- return new RuleIteratorForMultipleChunks(dbClient, organization, ruleKeys);
- }
-}
import org.sonar.api.rule.RuleKey;
import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbClient;
-import org.sonar.db.organization.OrganizationDto;
import static java.util.Optional.ofNullable;
public class RuleIteratorForMultipleChunks implements RuleIterator {
private final DbClient dbClient;
- private final OrganizationDto organization;
private final Iterator<List<RuleKey>> iteratorOverChunks;
private RuleIteratorForSingleChunk currentChunk;
- public RuleIteratorForMultipleChunks(DbClient dbClient, OrganizationDto organization, Collection<RuleKey> keys) {
+ public RuleIteratorForMultipleChunks(DbClient dbClient, Collection<RuleKey> keys) {
this.dbClient = dbClient;
- this.organization = organization;
iteratorOverChunks = DatabaseUtils.toUniqueAndSortedPartitions(keys).iterator();
}
}
@Override
- public RuleDoc next() {
+ public RuleDocWithSystemScope next() {
for (;;) {
if (currentChunk != null && currentChunk.hasNext()) {
return currentChunk.next();
private RuleIteratorForSingleChunk nextChunk() {
List<RuleKey> nextInput = iteratorOverChunks.next();
- return new RuleIteratorForSingleChunk(dbClient, organization, nextInput);
+ return new RuleIteratorForSingleChunk(dbClient, nextInput);
}
@Override
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.ResultSetIterator;
-import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.SeverityUtil;
import org.sonar.markdown.Markdown;
"r.priority",
"r.status",
"r.is_template",
- "rm.tags",
"r.system_tags",
+ "t.plugin_rule_key",
// column 11
- "t.plugin_rule_key",
"t.plugin_name",
"r.plugin_config_key",
"r.language",
};
private static final String SQL_ALL = "SELECT " + StringUtils.join(FIELDS, ",") + " FROM rules r " +
- "LEFT OUTER JOIN rules t ON t.id=r.template_id " +
- "LEFT OUTER JOIN rules_metadata rm ON rm.rule_id = r.id and rm.organization_uuid=?";
-
+ "LEFT OUTER JOIN rules t ON t.id=r.template_id";
private static final Splitter TAGS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
private final DbSession session;
- private final OrganizationDto organization;
private final List<RuleKey> ruleKeys;
private final PreparedStatement stmt;
- private final ResultSetIterator<RuleDoc> iterator;
+ private final ResultSetIterator<RuleDocWithSystemScope> iterator;
- RuleIteratorForSingleChunk(DbClient dbClient, OrganizationDto organization, @Nullable List<RuleKey> ruleKeys) {
+ RuleIteratorForSingleChunk(DbClient dbClient, @Nullable List<RuleKey> ruleKeys) {
checkArgument(ruleKeys == null || ruleKeys.size() <= DatabaseUtils.PARTITION_SIZE_FOR_ORACLE,
"Cannot search for more than " + DatabaseUtils.PARTITION_SIZE_FOR_ORACLE + " rule keys at once. Please provide the keys in smaller chunks.");
- this.organization = organization;
this.ruleKeys = ruleKeys;
this.session = dbClient.openSession(false);
}
@Override
- public RuleDoc next() {
+ public RuleDocWithSystemScope next() {
return iterator.next();
}
private void setParameters(PreparedStatement stmt) throws SQLException {
AtomicInteger index = new AtomicInteger(1);
- stmt.setString(index.getAndIncrement(), organization.getUuid());
if (ruleKeys != null && !ruleKeys.isEmpty()) {
for (RuleKey ruleKey : ruleKeys) {
stmt.setString(index.getAndIncrement(), ruleKey.repository());
}
}
- private static final class RuleIteratorInternal extends ResultSetIterator<RuleDoc> {
+ private static final class RuleIteratorInternal extends ResultSetIterator<RuleDocWithSystemScope> {
public RuleIteratorInternal(PreparedStatement stmt) throws SQLException {
super(stmt);
}
@Override
- protected RuleDoc read(ResultSet rs) throws SQLException {
+ protected RuleDocWithSystemScope read(ResultSet rs) throws SQLException {
RuleDoc doc = new RuleDoc();
+ RuleExtensionDoc extensionDoc = new RuleExtensionDoc().setScope(RuleExtensionScope.system());
String ruleKey = rs.getString(1);
String repositoryKey = rs.getString(2);
RuleKey key = RuleKey.of(repositoryKey, ruleKey);
+ extensionDoc.setRuleKey(key);
// all the fields must be present, even if value is null
doc.setKey(key.toString());
doc.setSeverity(SeverityUtil.getSeverityFromOrdinal(rs.getInt(6)));
doc.setStatus(rs.getString(7));
doc.setIsTemplate(rs.getBoolean(8));
- doc.setAllTags(Sets.union(stringTagsToSet(rs.getString(9)), stringTagsToSet(rs.getString(10))));
+ extensionDoc.setTags(stringTagsToSet(rs.getString(9)));
- String templateRuleKey = rs.getString(11);
- String templateRepoKey = rs.getString(12);
+ String templateRuleKey = rs.getString(10);
+ String templateRepoKey = rs.getString(11);
if (templateRepoKey != null && templateRuleKey != null) {
doc.setTemplateKey(RuleKey.of(templateRepoKey, templateRuleKey).toString());
} else {
doc.setTemplateKey(null);
}
- doc.setInternalKey(rs.getString(13));
- doc.setLanguage(rs.getString(14));
- doc.setType(RuleType.valueOf(rs.getInt(15)));
- doc.setCreatedAt(rs.getLong(16));
- doc.setUpdatedAt(rs.getLong(17));
+ doc.setInternalKey(rs.getString(12));
+ doc.setLanguage(rs.getString(13));
+ doc.setType(RuleType.valueOf(rs.getInt(14)));
+ doc.setCreatedAt(rs.getLong(15));
+ doc.setUpdatedAt(rs.getLong(16));
- return doc;
+ return new RuleDocWithSystemScope(doc, extensionDoc);
}
private static Set<String> stringTagsToSet(@Nullable String tags) {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.rule.index;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.Set;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.db.DatabaseUtils;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.ResultSetIterator;
+
+/**
+ * Scrolls over table RULES_METADATA and reads documents to populate the rule extension index type
+ */
+public class RuleMetadataIterator implements Iterator<RuleExtensionDoc>, AutoCloseable {
+
+ private static final String[] FIELDS = {
+ "r.plugin_name",
+ "r.plugin_rule_key",
+ "rm.organization_uuid",
+ "rm.tags"
+ };
+
+ private static final String SQL_ALL = "SELECT " + StringUtils.join(FIELDS, ",") + " FROM rules r " +
+ "INNER JOIN rules_metadata rm ON rm.rule_id = r.id " +
+ "WHERE rm.tags is not null AND rm.tags != ''";
+ private static final Splitter TAGS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
+
+ private final DbSession session;
+
+ private final PreparedStatement stmt;
+ private final ResultSetIterator<RuleExtensionDoc> iterator;
+
+ RuleMetadataIterator(DbClient dbClient) {
+ this.session = dbClient.openSession(false);
+
+ try {
+ String sql = SQL_ALL;
+ stmt = dbClient.getMyBatis().newScrollingSelectStatement(session, sql);
+ iterator = createIterator();
+ } catch (Exception e) {
+ session.close();
+ throw new IllegalStateException("Fail to prepare SQL request to select all rules", e);
+ }
+ }
+
+ private RuleMetadataIteratorInternal createIterator() {
+ try {
+ return new RuleMetadataIteratorInternal(stmt);
+ } catch (SQLException e) {
+ DatabaseUtils.closeQuietly(stmt);
+ throw new IllegalStateException("Fail to prepare SQL request to select all rules", e);
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public RuleExtensionDoc next() {
+ return iterator.next();
+ }
+
+ @Override
+ public void close() {
+ try {
+ iterator.close();
+ } finally {
+ DatabaseUtils.closeQuietly(stmt);
+ session.close();
+ }
+ }
+
+ private static final class RuleMetadataIteratorInternal extends ResultSetIterator<RuleExtensionDoc> {
+
+ public RuleMetadataIteratorInternal(PreparedStatement stmt) throws SQLException {
+ super(stmt);
+ }
+
+ @Override
+ protected RuleExtensionDoc read(ResultSet rs) throws SQLException {
+ RuleExtensionDoc doc = new RuleExtensionDoc();
+
+ String ruleKey = rs.getString(1);
+ String repositoryKey = rs.getString(2);
+ RuleKey key = RuleKey.of(repositoryKey, ruleKey);
+ doc.setRuleKey(key);
+ doc.setScope(RuleExtensionScope.organization(rs.getString(3)));
+ doc.setTags(stringTagsToSet(rs.getString(4)));
+
+ return doc;
+ }
+
+ private static Set<String> stringTagsToSet(@Nullable String tags) {
+ return ImmutableSet.copyOf(TAGS_SPLITTER.split(tags == null ? "" : tags));
+ }
+ }
+}
private boolean ascendingSort = true;
private String internalKey;
private String ruleKey;
+ private String organizationUuid;
@CheckForNull
public String getQProfileKey() {
public String getRuleKey() {
return ruleKey;
}
+
+ @CheckForNull
+ public String getOrganizationUuid() {
+ return organizationUuid;
+ }
+
+ public RuleQuery setOrganizationUuid(@Nullable String organizationUuid) {
+ this.organizationUuid = organizationUuid;
+ return this;
+ }
}
package org.sonar.server.rule.ws;
import com.google.common.io.Resources;
+import java.util.Optional;
import java.util.Set;
+import javax.annotation.Nullable;
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.server.ws.WebService.NewAction;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.rule.index.RuleIndex;
-import org.sonar.server.rule.index.RuleIndexDefinition;
+import org.sonar.server.ws.WsUtils;
+
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
public class TagsAction implements RulesWsAction {
private final RuleIndex ruleIndex;
+ private final DbClient dbClient;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
- public TagsAction(RuleIndex ruleIndex) {
+ public TagsAction(RuleIndex ruleIndex, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider) {
this.ruleIndex = ruleIndex;
+ this.dbClient = dbClient;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
}
@Override
.setDescription("The size of the list to return, 0 for all tags")
.setExampleValue("25")
.setDefaultValue("0");
+ action
+ .createParam(PARAM_ORGANIZATION)
+ .setDescription("Organization key")
+ .setRequired(false)
+ .setInternal(true)
+ .setExampleValue("my-org")
+ .setSince("6.4");
+
}
@Override
public void handle(Request request, Response response) {
+ OrganizationDto organization = getOrganization(request.param(PARAM_ORGANIZATION));
String query = request.param(Param.TEXT_QUERY);
int pageSize = request.mandatoryParamAsInt("ps");
- Set<String> tags = ruleIndex.terms(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, query, pageSize);
+
+ Set<String> tags = ruleIndex.listTags(organization.getUuid(), query, pageSize == 0 ? Integer.MAX_VALUE : pageSize);
+
+ writeResponse(response, tags);
+ }
+
+ private OrganizationDto getOrganization(@Nullable String organizationKey) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ String organizationOrDefaultKey = Optional.ofNullable(organizationKey)
+ .orElseGet(defaultOrganizationProvider.get()::getKey);
+ return WsUtils.checkFoundWithOptional(
+ dbClient.organizationDao().selectByKey(dbSession, organizationOrDefaultKey),
+ "No organization with key '%s'", organizationOrDefaultKey);
+ }
+ }
+
+ private static void writeResponse(Response response, Set<String> tags) {
JsonWriter json = response.newJsonWriter().beginObject();
json.name("tags").beginArray();
- for (String tag : tags) {
- json.value(tag);
- }
+ tags.forEach(json::value);
json.endArray().endObject().close();
}
}
import org.sonar.db.component.SnapshotTesting;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.issue.IssueTesting;
-import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.ProjectIndexer;
String suffix = String.valueOf(id);
ComponentDto project = newProjectDto(db.organizations().insert(), "project-uuid-" + suffix)
.setKey("project-key-" + suffix);
- RuleDto rule = RuleTesting.newDto(RuleKey.of("sonarqube", "rule-" + suffix));
- dbClient.ruleDao().insert(dbSession, rule.getDefinition());
- IssueDto issue = IssueTesting.newDto(rule, project, project).setKee("issue-key-" + suffix).setUpdatedAt(new Date().getTime());
+ RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("sonarqube", "rule-" + suffix));
+ dbClient.ruleDao().insert(dbSession, rule);
+ IssueDto issue = IssueTesting.newIssue(rule, project, project).setKee("issue-key-" + suffix).setUpdatedAt(new Date().getTime());
dbClient.componentDao().insert(dbSession, project);
SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, SnapshotTesting.newAnalysis(project));
dbClient.issueDao().insert(dbSession, issue);
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
@Test
public void insert_new_issue() {
- RuleDto rule = RuleTesting.newDto(RuleKey.of("xoo", "S01"));
- dbTester.rules().insertRule(rule);
+ RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
+ dbTester.rules().insert(rule);
OrganizationDto organizationDto = dbTester.organizations().insert();
ComponentDto project = ComponentTesting.newProjectDto(organizationDto);
dbClient.componentDao().insert(session, project);
import org.sonar.server.issue.index.IssueDoc;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.permission.GroupPermissionChange;
import org.sonar.server.permission.PermissionChange;
import org.sonar.server.permission.PermissionUpdater;
private DbSession session;
private IssueService service;
private RuleIndexer ruleIndexer;
- private OrganizationDto defaultOrganization;
@Before
public void setUp() {
session = db.openSession(false);
service = tester.get(IssueService.class);
ruleIndexer = tester.get(RuleIndexer.class);
- String defaultOrganizationUuid = tester.get(DefaultOrganizationProvider.class).get().getUuid();
- defaultOrganization = db.organizationDao().selectByUuid(session, defaultOrganizationUuid)
- .orElseThrow(() -> new IllegalStateException(String.format("Could not find defautl organization '%s'", defaultOrganizationUuid)));
}
@After
@Test
public void set_tags() {
- RuleDto rule = newRule(defaultOrganization);
+ RuleDto rule = newRule();
ComponentDto project = newProject();
ComponentDto file = newFile(project);
userSessionRule.logIn("john").addProjectUuidPermissions(UserRole.USER, project.uuid());
@Test
public void list_component_tags() {
- RuleDto rule = newRule(defaultOrganization);
+ RuleDto rule = newRule();
ComponentDto project = newProject();
ComponentDto file = newFile(project);
saveIssue(IssueTesting.newDto(rule, file, project).setTags(ImmutableSet.of("convention", "java8", "bug")));
@Test
public void test_listAuthors() {
- RuleDto rule = newRule(defaultOrganization);
+ RuleDto rule = newRule();
ComponentDto project = newProject();
ComponentDto file = newFile(project);
saveIssue(IssueTesting.newDto(rule, file, project).setAuthorLogin("luke.skywalker"));
@Test
public void listAuthors_escapes_regexp_special_characters() {
- saveIssue(IssueTesting.newDto(newRule(defaultOrganization), newFile(newProject()), newProject()).setAuthorLogin("name++"));
+ saveIssue(IssueTesting.newDto(newRule(), newFile(newProject()), newProject()).setAuthorLogin("name++"));
assertThat(service.listAuthors("invalidRegexp[", 5)).isEmpty();
assertThat(service.listAuthors("nam+", 5)).isEmpty();
assertThat(service.listAuthors(".*", 5)).isEmpty();
}
- private RuleDto newRule(OrganizationDto organization) {
- return newRule(organization, RuleTesting.newXooX1());
+ private RuleDto newRule() {
+ return newRule(RuleTesting.newXooX1());
}
- private RuleDto newRule(OrganizationDto organization, RuleDto rule) {
+ private RuleDto newRule(RuleDto rule) {
RuleDao ruleDao = tester.get(RuleDao.class);
ruleDao.insert(session, rule.getDefinition());
if (rule.getOrganizationUuid() != null) {
ruleDao.insertOrUpdate(session, rule.getMetadata().setRuleId(rule.getId()));
}
session.commit();
- ruleIndexer.index(organization, rule.getKey());
+ ruleIndexer.indexRuleDefinition(rule.getDefinition().getKey());
return rule;
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue;
+
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Multiset;
+import java.util.Collection;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.db.rule.RuleDefinitionDto;
+
+public class RulesAggregation {
+
+ private Multiset<Rule> rules;
+
+ public RulesAggregation() {
+ this.rules = HashMultiset.create();
+ }
+
+ public RulesAggregation add(RuleDefinitionDto ruleDto) {
+ rules.add(new Rule(ruleDto.getKey(), ruleDto.getName()));
+ return this;
+ }
+
+ public Collection<Rule> rules() {
+ return rules.elementSet();
+ }
+
+ public int countRule(Rule rule) {
+ return rules.count(rule);
+ }
+
+ public static class Rule {
+
+ private RuleKey ruleKey;
+ private String name;
+
+ public Rule(RuleKey ruleKey, String name) {
+ this.ruleKey = ruleKey;
+ this.name = name;
+ }
+
+ public RuleKey ruleKey() {
+ return ruleKey;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Rule rule = (Rule) o;
+
+ if (!ruleKey.equals(rule.ruleKey)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return ruleKey.hashCode();
+ }
+ }
+}
import org.junit.Test;
import org.sonar.api.rule.RuleKey;
-import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleTesting;
import static org.assertj.core.api.Assertions.assertThat;
public void count_rules() {
RulesAggregation rulesAggregation = new RulesAggregation();
RuleKey ruleKey = RuleKey.of("xoo", "S001");
- RuleDto ruleDto = RuleTesting.newDto(ruleKey).setName("Rule name");
+ RuleDefinitionDto ruleDto = RuleTesting.newRule(ruleKey).setName("Rule name");
rulesAggregation.add(ruleDto);
rulesAggregation.add(ruleDto);
public void count_rules_with_different_rules() {
RulesAggregation rulesAggregation = new RulesAggregation();
- RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("xoo", "S001")).setName("Rule name 1");
+ RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("xoo", "S001")).setName("Rule name 1");
rulesAggregation.add(ruleDto);
rulesAggregation.add(ruleDto);
- rulesAggregation.add(RuleTesting.newDto(RuleKey.of("xoo", "S002")).setName("Rule name 2"));
+ rulesAggregation.add(RuleTesting.newRule(RuleKey.of("xoo", "S002")).setName("Rule name 2"));
assertThat(rulesAggregation.rules()).hasSize(2);
}
package org.sonar.server.issue.index;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import java.util.Date;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.permission.index.AuthorizationTypeSupport;
import org.sonar.server.permission.index.PermissionIndexerDao;
import org.sonar.server.permission.index.PermissionIndexerTester;
-import org.sonar.server.rule.index.RuleDoc;
-import org.sonar.server.rule.index.RuleDocTesting;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.view.index.ViewIndexDefinition;
import org.sonar.server.view.index.ViewIndexer;
+import static com.google.common.collect.ImmutableSet.of;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.db.component.ComponentTesting.newProjectDto;
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
-import static org.sonar.db.rule.RuleTesting.XOO_X1;
-import static org.sonar.db.rule.RuleTesting.XOO_X2;
import static org.sonar.db.user.GroupTesting.newGroupDto;
import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
new ViewIndexDefinition(new MapSettings()),
new RuleIndexDefinition(new MapSettings()));
@Rule
+ public DbTester db = DbTester.create(system2);
+ @Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
@Rule
public ExpectedException expectedException = ExpectedException.none();
private IssueIndexer issueIndexer = new IssueIndexer(tester.client(), new IssueIteratorFactory(null));
private ViewIndexer viewIndexer = new ViewIndexer(null, tester.client());
- private RuleIndexer ruleIndexer = new RuleIndexer(tester.client(), null, null, null);
+ private RuleIndexer ruleIndexer = new RuleIndexer(tester.client(), db.getDbClient());
private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(tester, issueIndexer);
- private IssueIndex underTest = new IssueIndex(tester.client(), system2, userSessionRule, new AuthorizationTypeSupport(userSessionRule));
+ private IssueIndex underTest = new IssueIndex(tester.client(), system2, userSessionRule, new AuthorizationTypeSupport(userSessionRule)
+ );
@Before
public void setUp() {
@Test
public void list_tags() {
- indexRules(
- RuleDocTesting.newDoc(XOO_X1).setAllTags(asList("tag1", "systag1")),
- RuleDocTesting.newDoc(XOO_X2).setAllTags(asList("tag2", "systag2")));
+ RuleDefinitionDto r1 = db.rules().insert();
+ ruleIndexer.indexRuleDefinition(r1.getKey());
+
+ RuleDefinitionDto r2 = db.rules().insert();
+ ruleIndexer.indexRuleDefinition(r2.getKey());
+
+ OrganizationDto org = db.organizations().insert();
ComponentDto project = newProjectDto(newOrganizationDto());
ComponentDto file = newFileDto(project, null);
indexIssues(
- newDoc("ISSUE1", file).setRuleKey(XOO_X1.toString()).setTags(ImmutableSet.of("convention", "java8", "bug")),
- newDoc("ISSUE2", file).setRuleKey(XOO_X1.toString()).setTags(ImmutableSet.of("convention", "bug")),
- newDoc("ISSUE3", file).setRuleKey(XOO_X2.toString()),
- newDoc("ISSUE4", file).setRuleKey(XOO_X1.toString()).setTags(ImmutableSet.of("convention")));
+ newDoc("ISSUE1", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention", "java8", "bug")),
+ newDoc("ISSUE2", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention", "bug")),
+ newDoc("ISSUE3", file).setOrganizationUuid(org.getUuid()).setRuleKey(r2.getKey().toString()),
+ newDoc("ISSUE4", file).setOrganizationUuid(org.getUuid()).setRuleKey(r1.getKey().toString()).setTags(of("convention")));
- assertThat(underTest.listTags(null, 5)).containsOnly("convention", "java8", "bug", "systag1", "systag2");
- assertThat(underTest.listTags(null, 2)).containsOnly("bug", "convention");
- assertThat(underTest.listTags("vent", 5)).containsOnly("convention");
- assertThat(underTest.listTags("sys", 5)).containsOnly("systag1", "systag2");
- assertThat(underTest.listTags(null, 1)).containsOnly("bug");
- assertThat(underTest.listTags(null, Integer.MAX_VALUE)).containsOnly("convention", "java8", "bug", "systag1", "systag2", "tag1", "tag2");
- assertThat(underTest.listTags("invalidRegexp[", 5)).isEmpty();
+ assertThat(underTest.listTags(org.getUuid(), null, Integer.MAX_VALUE)).containsOnly("convention", "java8", "bug");
+ assertThat(underTest.listTags(org.getUuid(), null, 2)).containsOnly("bug", "convention");
+ assertThat(underTest.listTags(org.getUuid(), "vent", Integer.MAX_VALUE)).containsOnly("convention");
+ assertThat(underTest.listTags(org.getUuid(), null, 1)).containsOnly("bug");
+ assertThat(underTest.listTags(org.getUuid(), null, Integer.MAX_VALUE)).containsOnly("convention", "java8", "bug");
+ assertThat(underTest.listTags(org.getUuid(), "invalidRegexp[", Integer.MAX_VALUE)).isEmpty();
}
@Test
private void indexView(String viewUuid, List<String> projects) {
viewIndexer.index(new ViewDoc().setUuid(viewUuid).setProjects(projects));
}
-
- private void indexRules(RuleDoc... rules) {
- ruleIndexer.index(asList(rules).iterator());
- }
}
*/
package org.sonar.server.issue.ws;
-import com.google.common.collect.ImmutableSet;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.issue.IssueTesting;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
import org.sonar.server.issue.index.IssueIteratorFactory;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.permission.index.AuthorizationTypeSupport;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.rule.index.RuleIteratorFactory;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import static java.util.Arrays.asList;
-import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.db.component.ComponentTesting.newFileDto;
-import static org.sonar.db.rule.RuleTesting.newRuleDto;
+import static org.sonar.db.rule.RuleTesting.setSystemTags;
+import static org.sonar.db.rule.RuleTesting.setTags;
import static org.sonar.test.JsonAssert.assertJson;
public class TagsActionTest {
public EsTester es = new EsTester(new IssueIndexDefinition(new MapSettings()), new RuleIndexDefinition(new MapSettings()));
private IssueIndexer issueIndexer = new IssueIndexer(es.client(), new IssueIteratorFactory(db.getDbClient()));
- private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), null, new RuleIteratorFactory(db.getDbClient()), null);
+ private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient());
private IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSession, new AuthorizationTypeSupport(userSession));
+ private RuleIndex ruleIndex = new RuleIndex(es.client());
- private WsActionTester tester = new WsActionTester(new TagsAction(issueIndex));
+ private WsActionTester tester = new WsActionTester(new TagsAction(issueIndex, ruleIndex, TestDefaultOrganizationProvider.from(db)));
private OrganizationDto organization;
@Before
@Test
public void return_tags_from_rules() throws Exception {
- RuleDto r = db.rules().insertRule(organization, rule -> rule.setSystemTags(ImmutableSet.of("tag1")), rule -> rule.setTags(ImmutableSet.of("tag2")));
- RuleDto r2 = db.rules().insertRule(organization, rule -> rule.setSystemTags(ImmutableSet.of("tag3")), rule -> rule.setTags(ImmutableSet.of("tag4", "tag5")));
- db.commit();
- ruleIndexer.index(organization, asList(r.getKey(), r2.getKey()));
+ RuleDefinitionDto r = db.rules().insert(setSystemTags("tag1"));
+ ruleIndexer.indexRuleDefinition(r.getKey());
+ db.rules().insertOrUpdateMetadata(r, organization, setTags("tag2"));
+ ruleIndexer.indexRuleExtension(organization, r.getKey());
+
+ RuleDefinitionDto r2 = db.rules().insert(setSystemTags("tag3"));
+ ruleIndexer.indexRuleDefinition(r2.getKey());
+ db.rules().insertOrUpdateMetadata(r2, organization, setTags("tag4", "tag5"));
+ ruleIndexer.indexRuleExtension(organization, r2.getKey());
String result = tester.newRequest().execute().getInput();
assertJson(result).isSimilarTo("{\"tags\":[\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"]}");
insertIssueWithBrowsePermission(insertRuleWithoutTags(), "tag1", "tag2");
insertIssueWithBrowsePermission(insertRuleWithoutTags(), "tag3", "tag4", "tag5");
issueIndexer.indexOnStartup(null);
- RuleDto r = db.rules().insertRule(db.getDefaultOrganization(), rule -> rule.setSystemTags(ImmutableSet.of("tag6")).setTags(ImmutableSet.of("tag7")));
- ruleIndexer.index(organization, r.getKey());
+
+ RuleDefinitionDto r = db.rules().insert(setSystemTags("tag6"));
+ ruleIndexer.indexRuleDefinition(r.getKey());
+ db.rules().insertOrUpdateMetadata(r, organization, setTags("tag7"));
+ ruleIndexer.indexRuleExtension(organization, r.getKey());
String result = tester.newRequest().execute().getInput();
assertJson(result).isSimilarTo("{\"tags\":[\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\", \"tag6\", \"tag7\"]}");
public void test_example() throws Exception {
insertIssueWithBrowsePermission(insertRuleWithoutTags(), "convention");
issueIndexer.indexOnStartup(null);
- RuleDto r = db.rules().insertRule(db.getDefaultOrganization(), rule -> rule.setSystemTags(ImmutableSet.of("cwe")).setTags(ImmutableSet.of("security")));
- ruleIndexer.index(organization, r.getKey());
+
+ RuleDefinitionDto r = db.rules().insert(setSystemTags("cwe"));
+ ruleIndexer.indexRuleDefinition(r.getKey());
+ db.rules().insertOrUpdateMetadata(r, organization, setTags("security"));
+ ruleIndexer.indexRuleExtension(organization, r.getKey());
String result = tester.newRequest().execute().getInput();
assertJson(result).isSimilarTo(tester.getDef().responseExampleAsString());
assertThat(action.params()).hasSize(2);
Param query = action.param("q");
+ assertThat(query).isNotNull();
assertThat(query.isRequired()).isFalse();
assertThat(query.description()).isNotEmpty();
assertThat(query.exampleValue()).isNotEmpty();
Param pageSize = action.param("ps");
+ assertThat(pageSize).isNotNull();
assertThat(pageSize.isRequired()).isFalse();
assertThat(pageSize.defaultValue()).isEqualTo("10");
assertThat(pageSize.description()).isNotEmpty();
assertThat(pageSize.exampleValue()).isNotEmpty();
}
- private RuleDto insertRuleWithoutTags() {
- RuleDto ruleDto = newRuleDto(db.getDefaultOrganization()).setTags(emptySet()).setSystemTags(emptySet());
- db.rules().insertRule(ruleDto);
- return ruleDto;
+ private RuleDefinitionDto insertRuleWithoutTags() {
+ return db.rules().insert(setSystemTags());
}
- private IssueDto insertIssue(RuleDto rule, String... tags) {
+ private IssueDto insertIssue(RuleDefinitionDto rule, String... tags) {
ComponentDto project = db.components().insertProject(organization);
ComponentDto file = db.components().insertComponent(newFileDto(project));
- IssueDto issueDto = IssueTesting.newDto(rule, file, project).setTags(asList(tags));
+ IssueDto issueDto = IssueTesting.newIssue(rule, file, project).setTags(asList(tags));
return db.issues().insertIssue(issueDto);
}
userSession.logIn("john").addProjectUuidPermissions(USER, issue.getProjectUuid());
}
- private IssueDto insertIssueWithBrowsePermission(RuleDto rule, String... tags) {
+ private IssueDto insertIssueWithBrowsePermission(RuleDefinitionDto rule, String... tags) {
IssueDto issue = insertIssue(rule, tags);
setUserWithBrowsePermission(issue);
return issue;
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.ActiveRuleParamDto;
import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;
-import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.sonar.db.qualityprofile.ActiveRuleDto.INHERITED;
import static org.sonar.db.qualityprofile.ActiveRuleDto.OVERRIDES;
import static org.sonar.db.rule.RuleTesting.XOO_X1;
import static org.sonar.db.rule.RuleTesting.XOO_X2;
-import static org.sonar.db.rule.RuleTesting.newDto;
+import static org.sonar.db.rule.RuleTesting.newRule;
import static org.sonar.db.rule.RuleTesting.newXooX1;
import static org.sonar.db.rule.RuleTesting.newXooX2;
import static org.sonar.server.qualityprofile.QProfileTesting.XOO_P1_KEY;
// create pre-defined rules
RuleDto xooRule1 = newXooX1().setSeverity("MINOR").setLanguage("xoo");
- RuleDto xooRule2 = newXooX2().setSeverity("MAJOR").setLanguage("xoo");
db.ruleDao().insert(dbSession, xooRule1.getDefinition());
- db.ruleDao().insert(dbSession, xooRule2.getDefinition());
db.ruleDao().insertRuleParam(dbSession, xooRule1.getDefinition(), RuleParamDto.createFor(xooRule1.getDefinition())
.setName("max").setDefaultValue("10").setType(RuleParamType.INTEGER.type()));
dbSession.commit();
- dbSession.clearCache();
+ ruleIndexer.indexRuleDefinition(xooRule1.getDefinition().getKey());
+
+ RuleDto xooRule2 = newXooX2().setSeverity("MAJOR").setLanguage("xoo");
+ db.ruleDao().insert(dbSession, xooRule2.getDefinition());
+ dbSession.commit();
+ ruleIndexer.indexRuleDefinition(xooRule2.getDefinition().getKey());
+
this.organization = OrganizationTesting.newOrganizationDto();
db.organizationDao().insert(dbSession, organization);
- ruleIndexer.index(organization, asList(xooRule1.getKey(), xooRule2.getKey()));
}
@After
@Test
public void backup() throws Exception {
RuleKey blahRuleKey = RuleKey.of("blah", "my-rule");
- RuleDto blahRule = newDto(blahRuleKey).setSeverity("INFO").setLanguage("xoo");
- db.ruleDao().insert(dbSession, blahRule.getDefinition());
+ RuleDefinitionDto blahRule = newRule(blahRuleKey).setSeverity("INFO").setLanguage("xoo");
+ db.ruleDao().insert(dbSession, blahRule);
dbSession.commit();
- dbSession.clearCache();
- ruleIndexer.index(organization, blahRuleKey);
+ ruleIndexer.indexRuleDefinition(blahRule.getKey());
// create profile P1 with rules x2 and x1 activated
QualityProfileDto profile = newXooP1(organization);
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.ActiveRuleParamDto;
import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;
-import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.sonar.server.qualityprofile.QProfileTesting.getDefaultOrganization;
// create pre-defined rules
RuleDto xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR");
- RuleDto xooRule2 = RuleTesting.newXooX2().setSeverity("MAJOR");
- db.ruleDao().insert(dbSession, xooRule1.getDefinition());
- db.ruleDao().insert(dbSession, xooRule2.getDefinition());
- db.ruleDao().insertRuleParam(dbSession, xooRule1.getDefinition(), RuleParamDto.createFor(xooRule1.getDefinition())
+ RuleDefinitionDto xooRule1Definition = xooRule1.getDefinition();
+ db.ruleDao().insert(dbSession, xooRule1Definition);
+ db.ruleDao().insertRuleParam(dbSession, xooRule1Definition, RuleParamDto.createFor(xooRule1Definition)
.setName("max").setDefaultValue("10").setType(RuleParamType.INTEGER.type()));
+ dbSession.commit();
+ ruleIndexer.indexRuleDefinition(xooRule1Definition.getKey());
+
+ RuleDto xooRule2 = RuleTesting.newXooX2().setSeverity("MAJOR");
+ RuleDefinitionDto xooRule2Definition = xooRule2.getDefinition();
+ db.ruleDao().insert(dbSession, xooRule2Definition);
+ dbSession.commit();
+ ruleIndexer.indexRuleDefinition(xooRule2Definition.getKey());
// create pre-defined profile
sourceProfile = QProfileTesting.newXooP1(organization);
db.qualityProfileDao().insert(dbSession, sourceProfile);
dbSession.commit();
- ruleIndexer.index(organization, asList(xooRule1.getKey(), xooRule2.getKey()));
}
@After
// index all rules
dbSession.commit();
- ruleIndexer.index(organization, asList(javaRule, xooRule1, xooRule2, xooTemplateRule1, xooCustomRule1).stream().map(RuleDto::getKey).collect(Collectors.toList()));
+ ruleIndexer.indexRuleDefinitions(asList(javaRule, xooRule1, xooRule2, xooTemplateRule1, xooCustomRule1).stream().map(RuleDto::getKey).collect(Collectors.toList()));
}
@After
keys.add(ruleDefinitionDto.getKey());
}
dbSession.commit();
- ruleIndexer.index(organization, keys);
+ ruleIndexer.indexRuleDefinitions(keys);
// 0. No active rules so far (base case) and plenty rules available
verifyZeroActiveRules(XOO_P1_KEY);
long now = 2000000L;
// Index one active rule
- RuleDefinitionDto rule = RuleTesting.newDto(RULE_KEY_1).getDefinition();
+ RuleDefinitionDto rule = RuleTesting.newRule(RULE_KEY_1);
dbTester.rules().insert(rule);
QualityProfileDto profile = QualityProfileDto.createFor("qp")
.setOrganizationUuid(organization.getUuid())
assertThat(esTester.getIds(INDEX_TYPE_ACTIVE_RULE)).containsOnly(activeRule.getKey().toString());
// Index another active rule
- RuleDefinitionDto rule2 = RuleTesting.newDto(RULE_KEY_2).getDefinition();
+ RuleDefinitionDto rule2 = RuleTesting.newRule(RULE_KEY_2);
dbTester.rules().insert(rule2);
ActiveRuleDto activeRule2 = ActiveRuleDto.createFor(profile, rule2).setSeverity(Severity.CRITICAL)
.setCreatedAt(now).setUpdatedAt(now);
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.db.qualityprofile.QualityProfileTesting;
-import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.EsTester;
import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.rule.index.RuleIteratorFactory;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.util.TypeValidations;
TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
ruleIndexer = new RuleIndexer(
esClient,
- null,
- new RuleIteratorFactory(dbClient),
- null
- );
+ dbClient);
activeRuleIndexer = new ActiveRuleIndexer(
System2.INSTANCE,
dbClient,
QualityProfileDto parent1 = createProfile();
QualityProfileDto child = createProfile();
- RuleDto rule1 = createRule();
+ RuleDefinitionDto rule1 = createRule();
createActiveRule(rule1, parent1);
- ruleIndexer.index(organization, rule1.getKey());
+ ruleIndexer.indexRuleDefinition(rule1.getKey());
activeRuleIndexer.index();
assertThat(dbClient.activeRuleDao().selectByProfileKey(dbSession, child.getKey())).isEmpty();
QualityProfileDto parent2 = createProfile();
QualityProfileDto child = createProfile();
- RuleDto rule1 = createRule();
- RuleDto rule2 = createRule();
+ RuleDefinitionDto rule1 = createRule();
+ RuleDefinitionDto rule2 = createRule();
createActiveRule(rule1, parent1);
createActiveRule(rule2, parent2);
- ruleIndexer.index(organization, Stream.of(rule1, rule2).map(RuleDto::getKey).collect(MoreCollectors.toList()));
+ ruleIndexer.indexRuleDefinitions(Stream.of(rule1, rule2).map(RuleDefinitionDto::getKey).collect(MoreCollectors.toList()));
activeRuleIndexer.index();
// Set parent 1
QualityProfileDto parent = createProfile();
QualityProfileDto child = createProfile();
- RuleDto rule1 = createRule();
+ RuleDefinitionDto rule1 = createRule();
createActiveRule(rule1, parent);
- ruleIndexer.index(organization, rule1.getKey());
+ ruleIndexer.indexRuleDefinition(rule1.getKey());
activeRuleIndexer.index();
// Set parent
QualityProfileDto parent2 = createProfile();
QualityProfileDto child = createProfile();
- RuleDto rule1 = createRule();
- RuleDto rule2 = createRule();
+ RuleDefinitionDto rule1 = createRule();
+ RuleDefinitionDto rule2 = createRule();
createActiveRule(rule1, parent1);
createActiveRule(rule2, parent2);
- ruleIndexer.index(organization, rule1.getKey());
+ ruleIndexer.indexRuleDefinition(rule1.getKey());
activeRuleIndexer.index();
assertThat(dbClient.activeRuleDao().selectByProfileKey(dbSession, child.getKey())).isEmpty();
QualityProfileDto parent = createProfile();
QualityProfileDto child = createProfile();
- RuleDto rule1 = createRule();
+ RuleDefinitionDto rule1 = createRule();
createActiveRule(rule1, parent);
- ruleIndexer.index(organization, rule1.getKey());
+ ruleIndexer.indexRuleDefinition(rule1.getKey());
activeRuleIndexer.index();
assertThat(dbClient.activeRuleDao().selectByProfileKey(dbSession, child.getKey())).isEmpty();
return profile;
}
- private RuleDto createRule() {
- RuleDto rule = RuleTesting.newDto(RuleKey.of(ruleRepository, randomAlphanumeric(5)))
+ private RuleDefinitionDto createRule() {
+ RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of(ruleRepository, randomAlphanumeric(5)))
.setLanguage(language.getKey())
.setSeverity(Severity.BLOCKER)
.setStatus(RuleStatus.READY);
- dbClient.ruleDao().insert(dbSession, rule.getDefinition());
+ dbClient.ruleDao().insert(dbSession, rule);
dbSession.commit();
return rule;
}
- private ActiveRuleDto createActiveRule(RuleDto rule, QualityProfileDto profile) {
- ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule.getDefinition())
+ private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QualityProfileDto profile) {
+ ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule)
.setSeverity(rule.getSeverityString());
dbClient.activeRuleDao().insert(dbSession, activeRule);
dbSession.commit();
import org.sonar.db.qualityprofile.QProfileChangeDto;
import org.sonar.db.qualityprofile.QProfileChangeQuery;
import org.sonar.db.qualityprofile.QualityProfileTesting;
-import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserTesting;
}
private void insertRule(RuleKey key, String name) {
- RuleDto dto = RuleTesting.newDto(key).setName(name);
- dbTester.rules().insertRule(dto);
+ RuleDefinitionDto dto = RuleTesting.newRule(key).setName(name);
+ dbTester.rules().insert(dto);
dbTester.getSession().commit();
}
import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.rule.index.RuleIteratorFactory;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
private DbSession dbSession = dbTester.getSession();
private RuleIndex ruleIndex = new RuleIndex(esTester.client());
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
- private RuleIndexer ruleIndexer = new RuleIndexer(esTester.client(), null, new RuleIteratorFactory(dbClient), null);
+ private RuleIndexer ruleIndexer = new RuleIndexer(esTester.client(), dbClient);
private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(system2, dbClient, esTester.client());
private ProfileImporter[] profileImporters = createImporters();
private QProfileExporters qProfileExporters = new QProfileExporters(dbClient, null,
private void insertRule(RuleDefinitionDto ruleDto) {
dbClient.ruleDao().insert(dbSession, ruleDto);
dbSession.commit();
- ruleIndexer.index(organization, ruleDto.getKey());
+ ruleIndexer.indexRuleDefinition(ruleDto.getKey());
}
private CreateWsResponse executeRequest(String name, String language) {
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
-import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.EsTester;
import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.rule.index.RuleIteratorFactory;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.util.TypeValidations;
import org.sonar.server.ws.WsActionTester;
import org.sonar.test.JsonAssert;
-import static java.util.Arrays.asList;
-
public class InheritanceActionTest {
@Rule
dbClient = dbTester.getDbClient();
dbSession = dbTester.getSession();
esClient = esTester.client();
- ruleIndexer = new RuleIndexer(esClient, null, new RuleIteratorFactory(dbClient), null);
+ ruleIndexer = new RuleIndexer(esClient, dbClient);
activeRuleIndexer = new ActiveRuleIndexer(System2.INSTANCE, dbClient, esClient);
TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
underTest = new InheritanceAction(
createActiveRule(rule2, groupWide);
dbSession.commit();
- ruleIndexer.index(organization, asList(rule1.getKey(), rule2.getKey(), rule3.getKey()));
activeRuleIndexer.index();
QualityProfileDto companyWide = createProfile("xoo", "My Company Profile", "xoo-my-company-profile-12345");
private RuleDefinitionDto createRule(String lang, String id) {
long now = new Date().getTime();
- RuleDto rule = RuleTesting.newDto(RuleKey.of("blah", id))
+ RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("blah", id))
.setLanguage(lang)
.setSeverity(Severity.BLOCKER)
.setStatus(RuleStatus.READY)
.setUpdatedAt(now)
.setCreatedAt(now);
- dbClient.ruleDao().insert(dbSession, rule.getDefinition());
- return rule.getDefinition();
+ dbClient.ruleDao().insert(dbSession, rule);
+ dbSession.commit();
+ ruleIndexer.indexRuleDefinition(rule.getKey());
+ return rule;
}
private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QualityProfileDto profile) {
import org.sonar.db.qualityprofile.ActiveRuleKey;
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
-import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.exceptions.BadRequestException;
RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
createActiveRule(rule, profile);
session.commit();
- ruleIndexer.index(organization, rule.getKey());
+ ruleIndexer.indexRuleDefinition(rule.getKey());
activeRuIndexer.index();
// 0. Assert No Active Rule for profile
QualityProfileDto profile = createProfile("java");
RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
session.commit();
- ruleIndexer.index(organization, rule.getKey());
+ ruleIndexer.indexRuleDefinition(rule.getKey());
// 0. Assert No Active Rule for profile
assertThat(db.activeRuleDao().selectByProfileKey(session, profile.getKey())).isEmpty();
QualityProfileDto profile = createProfile("java");
RuleDefinitionDto rule = createRule("php", "toto");
session.commit();
- ruleIndexer.index(organization, rule.getKey());
+ ruleIndexer.indexRuleDefinition(rule.getKey());
// 0. Assert No Active Rule for profile
assertThat(db.activeRuleDao().selectByProfileKey(session, profile.getKey())).isEmpty();
QualityProfileDto profile = createProfile("java");
RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
session.commit();
- ruleIndexer.index(organization, rule.getKey());
+ ruleIndexer.indexRuleDefinition(rule.getKey());
// 0. Assert No Active Rule for profile
assertThat(db.activeRuleDao().selectByProfileKey(session, profile.getKey())).isEmpty();
}
private RuleDefinitionDto createRule(String lang, String id) {
- RuleDto rule = RuleTesting.newDto(RuleKey.of("blah", id))
+ RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("blah", id))
.setLanguage(lang)
.setSeverity(Severity.BLOCKER)
.setStatus(RuleStatus.READY);
- db.ruleDao().insert(session, rule.getDefinition());
+ db.ruleDao().insert(session, rule);
session.commit();
- ruleIndexer.index(organization, rule.getKey());
- return rule.getDefinition();
+ ruleIndexer.indexRuleDefinition(rule.getKey());
+ return rule;
}
private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QualityProfileDto profile) {
import org.sonar.db.rule.RuleRepositoryDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchOptions;
-import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.rule.index.RuleIteratorFactory;
import org.sonar.server.rule.index.RuleQuery;
import static com.google.common.collect.Sets.newHashSet;
@Before
public void before() {
when(system.now()).thenReturn(DATE1.getTime());
- ruleIndexer = new RuleIndexer(esTester.client(), null, new RuleIteratorFactory(dbClient), null);
+ ruleIndexer = new RuleIndexer(esTester.client(), dbClient);
ruleIndex = new RuleIndex(esTester.client());
activeRuleIndexer = new ActiveRuleIndexer(system, dbClient, esTester.client());
}
// verify repositories
assertThat(dbClient.ruleRepositoryDao().selectAll(dbTester.getSession())).extracting(RuleRepositoryDto::getKey).containsOnly("fake");
}
+
@Test
public void insert_then_remove_rule() {
String ruleKey = randomAlphanumeric(5);
Languages languages = mock(Languages.class);
when(languages.get("java")).thenReturn(mock(Language.class));
- RegisterRules task = new RegisterRules(loader, ruleActivator, dbClient, ruleIndexer, activeRuleIndexer, languages, system, TestDefaultOrganizationProvider.from(dbTester));
+ RegisterRules task = new RegisterRules(loader, ruleActivator, dbClient, ruleIndexer, activeRuleIndexer, languages, system);
task.start();
// Execute a commit to refresh session state as the task is using its own session
dbTester.getSession().commit();
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
+import static org.sonar.db.rule.RuleTesting.newRule;
// TODO replace ServerTester by EsTester / DbTester
public class RuleCreatorMediumTest {
@Test
public void create_custom_rule_with_no_parameter_value() {
// insert template rule
- RuleDto templateRule = createTemplateRuleWithIntArrayParam();
+ RuleDefinitionDto templateRule = createTemplateRuleWithIntArrayParam();
NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
@Test
public void create_custom_rule_with_multiple_parameter_values() {
// insert template rule
- RuleDto templateRule = createTemplateRuleWithIntArrayParam();
+ RuleDefinitionDto templateRule = createTemplateRuleWithIntArrayParam();
NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
@Test
public void create_custom_rule_with_invalid_parameter() {
// insert template rule
- RuleDto templateRule = createTemplateRuleWithIntArrayParam();
+ RuleDefinitionDto templateRule = createTemplateRuleWithIntArrayParam();
// Create custom rule
NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
@Test
public void create_custom_rule_with_invalid_parameters() {
// insert template rule
- RuleDto templateRule = createTemplateRuleWithTwoIntParams();
+ RuleDefinitionDto templateRule = createTemplateRuleWithTwoIntParams();
// Create custom rule
NewCustomRule newRule = NewCustomRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
@Test
public void fail_to_create_custom_rule_when_wrong_rule_template() {
// insert rule
- RuleDto rule = RuleTesting.newDto(RuleKey.of("java", "S001")).setIsTemplate(false);
- dao.insert(dbSession, rule.getDefinition());
+ RuleDefinitionDto rule = newRule(RuleKey.of("java", "S001")).setIsTemplate(false);
+ dao.insert(dbSession, rule);
dbSession.commit();
// Create custom rule with unknown template rule
RuleParamDto ruleParamDto = RuleParamDto.createFor(templateRule.getDefinition()).setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*");
dao.insertRuleParam(dbSession, templateRule.getDefinition(), ruleParamDto);
dbSession.commit();
- ruleIndexer.index(defaultOrganization, templateRule.getKey());
+ ruleIndexer.indexRuleDefinition(templateRule.getDefinition().getKey());
return templateRule;
}
- private RuleDto createTemplateRuleWithIntArrayParam() {
- RuleDto templateRule = RuleTesting.newDto(RuleKey.of("java", "S002"))
+ private RuleDefinitionDto createTemplateRuleWithIntArrayParam() {
+ RuleDefinitionDto templateRule = newRule(RuleKey.of("java", "S002"))
.setIsTemplate(true)
.setLanguage("java")
.setConfigKey("S002")
.setGapDescription("desc")
.setCreatedAt(new Date().getTime())
.setUpdatedAt(new Date().getTime());
- dao.insert(dbSession, templateRule.getDefinition());
- RuleParamDto ruleParamDto = RuleParamDto.createFor(templateRule.getDefinition())
+ dao.insert(dbSession, templateRule);
+ RuleParamDto ruleParamDto = RuleParamDto.createFor(templateRule)
.setName("myIntegers").setType("INTEGER,multiple=true,values=1;2;3").setDescription("My Integers").setDefaultValue("1");
- dao.insertRuleParam(dbSession, templateRule.getDefinition(), ruleParamDto);
+ dao.insertRuleParam(dbSession, templateRule, ruleParamDto);
dbSession.commit();
- ruleIndexer.index(defaultOrganization, templateRule.getKey());
+ ruleIndexer.indexRuleDefinition(templateRule.getKey());
return templateRule;
}
- private RuleDto createTemplateRuleWithTwoIntParams() {
- RuleDto templateRule = RuleTesting.newDto(RuleKey.of("java", "S003"))
+ private RuleDefinitionDto createTemplateRuleWithTwoIntParams() {
+ RuleDefinitionDto templateRule = newRule(RuleKey.of("java", "S003"))
.setIsTemplate(true)
.setLanguage("java")
.setConfigKey("S003")
.setGapDescription("desc")
.setCreatedAt(new Date().getTime())
.setUpdatedAt(new Date().getTime());
- dao.insert(dbSession, templateRule.getDefinition());
- RuleParamDto ruleParam1Dto = RuleParamDto.createFor(templateRule.getDefinition())
+ dao.insert(dbSession, templateRule);
+ RuleParamDto ruleParam1Dto = RuleParamDto.createFor(templateRule)
.setName("first").setType("INTEGER").setDescription("First integer").setDefaultValue("0");
- dao.insertRuleParam(dbSession, templateRule.getDefinition(), ruleParam1Dto);
- RuleParamDto ruleParam2Dto = RuleParamDto.createFor(templateRule.getDefinition())
+ dao.insertRuleParam(dbSession, templateRule, ruleParam1Dto);
+ RuleParamDto ruleParam2Dto = RuleParamDto.createFor(templateRule)
.setName("second").setType("INTEGER").setDescription("Second integer").setDefaultValue("0");
- dao.insertRuleParam(dbSession, templateRule.getDefinition(), ruleParam2Dto);
+ dao.insertRuleParam(dbSession, templateRule, ruleParam2Dto);
dbSession.commit();
return templateRule;
}
.setUpdatedAt(PAST);
dao.insert(dbSession, templateRule.getDefinition());
dbSession.commit();
- ruleIndexer.index(organization, templateRule.getKey());
+ ruleIndexer.indexRuleDefinition(templateRule.getDefinition().getKey());
// Verify in index
assertThat(index.searchAll(new RuleQuery())).containsOnly(templateRule.getKey());
.setUpdatedAt(PAST);
dao.insert(dbSession, customRule.getDefinition());
dbSession.commit();
- ruleIndexer.index(organization, customRule.getKey());
+ ruleIndexer.indexRuleDefinition(customRule.getDefinition().getKey());
// Verify in index
assertThat(index.searchAll(new RuleQuery())).containsOnly(templateRule.getKey(), customRule.getKey());
public void fail_to_delete_if_not_custom() {
// Create rule
RuleKey ruleKey = RuleKey.of("java", "S001");
- dao.insert(dbSession, RuleTesting.newDto(ruleKey).getDefinition());
+ dao.insert(dbSession, RuleTesting.newRule(ruleKey));
dbSession.commit();
try {
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Test;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.server.qualityprofile.RuleActivation;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.rule.index.RuleIndex;
-import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;
@Test
public void do_not_update_rule_with_removed_status() {
- ruleDao.insert(dbSession, RuleTesting.newDto(RULE_KEY).setStatus(RuleStatus.REMOVED).getDefinition());
+ ruleDao.insert(dbSession, RuleTesting.newRule(RULE_KEY).setStatus(RuleStatus.REMOVED));
dbSession.commit();
RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setTags(Sets.newHashSet("java9"));
assertThat(rule.getNoteUpdatedAt()).isNull();
}
+ @Ignore
@Test
public void set_tags() {
// insert db
RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setTags(Sets.newHashSet("bug", "java8"));
underTest.update(update, userSessionRule);
- dbSession.clearCache();
RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
assertThat(rule.getTags()).containsOnly("bug");
assertThat(rule.getSystemTags()).containsOnly("java8", "javadoc");
// verify that tags are indexed in index
- Set<String> tags = tester.get(RuleIndex.class).terms(RuleIndexDefinition.FIELD_RULE_ALL_TAGS);
+ Set<String> tags = ruleIndex.listTags(defaultOrganization.getUuid(), null, 10);
assertThat(tags).containsOnly("bug", "java8", "javadoc");
}
assertThat(rule.getSystemTags()).containsOnly("java8", "javadoc");
// verify that tags are indexed in index
- Set<String> tags = tester.get(RuleIndex.class).terms(RuleIndexDefinition.FIELD_RULE_ALL_TAGS);
+ Set<String> tags = ruleIndex.listTags(defaultOrganization.getUuid(), null, 10);
assertThat(tags).containsOnly("java8", "javadoc");
}
@Test
public void override_debt() {
- ruleDao.insert(dbSession, RuleTesting.newDto(RULE_KEY)
+ ruleDao.insert(dbSession, RuleTesting.newRule(RULE_KEY)
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name())
.setDefRemediationGapMultiplier("1d")
- .setDefRemediationBaseEffort("5min")
- .getDefinition());
+ .setDefRemediationBaseEffort("5min"));
dbSession.commit();
DefaultDebtRemediationFunction fn = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "1min");
@Test
public void override_debt_only_offset() {
- ruleDao.insert(dbSession, RuleTesting.newDto(RULE_KEY)
+ ruleDao.insert(dbSession, RuleTesting.newRule(RULE_KEY)
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR.name())
.setDefRemediationGapMultiplier("1d")
- .setDefRemediationBaseEffort(null)
- .getDefinition());
+ .setDefRemediationBaseEffort(null));
dbSession.commit();
RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
@Test
public void override_debt_from_linear_with_offset_to_constant() {
- ruleDao.insert(dbSession, RuleTesting.newDto(RULE_KEY)
+ ruleDao.insert(dbSession, RuleTesting.newRule(RULE_KEY)
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name())
.setDefRemediationGapMultiplier("1d")
- .setDefRemediationBaseEffort("5min")
- .getDefinition());
+ .setDefRemediationBaseEffort("5min"));
dbSession.commit();
RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
@Test
public void fail_to_update_plugin_rule_if_name_is_set() {
// Create rule rule
- RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("squid", "S01"));
- ruleDao.insert(dbSession, ruleDto.getDefinition());
+ RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("squid", "S01"));
+ ruleDao.insert(dbSession, ruleDto);
dbSession.commit();
@Test
public void fail_to_update_plugin_rule_if_description_is_set() {
// Create rule rule
- RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("squid", "S01"));
- ruleDao.insert(dbSession, ruleDto.getDefinition());
+ RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("squid", "S01"));
+ ruleDao.insert(dbSession, ruleDto);
dbSession.commit();
@Test
public void fail_to_update_plugin_rule_if_severity_is_set() {
// Create rule rule
- RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("squid", "S01"));
- ruleDao.insert(dbSession, ruleDto.getDefinition());
+ RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("squid", "S01"));
+ ruleDao.insert(dbSession, ruleDto);
dbSession.commit();
package org.sonar.server.rule.index;
import com.google.common.collect.Maps;
-import java.util.Arrays;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
.setStatus(RuleStatus.READY.name())
.setLanguage("xoo")
.setIsTemplate(false)
- .setAllTags(Arrays.asList("spring", "performance"))
.setType(RuleType.CODE_SMELL)
.setCreatedAt(1_500_000_000L)
.setUpdatedAt(1_600_000_000L);
assertThat(context.getIndices()).hasSize(1);
NewIndex ruleIndex = context.getIndices().get("rules");
assertThat(ruleIndex).isNotNull();
- assertThat(ruleIndex.getTypes().keySet()).containsOnly("rule", "activeRule");
+ assertThat(ruleIndex.getTypes().keySet()).containsOnly("activeRule", "ruleExtension", "rule");
// no cluster by default
assertThat(ruleIndex.getSettings().get("index.number_of_shards")).isEqualTo("1");
package org.sonar.server.rule.index;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
-import org.elasticsearch.search.SearchHit;
+import java.util.function.Consumer;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.sonar.api.config.MapSettings;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.ActiveRuleKey;
-import org.sonar.db.rule.RuleTesting;
+import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.rule.RuleMetadataDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchIdResult;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.qualityprofile.index.ActiveRuleDocTesting;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
+import static com.google.common.collect.ImmutableSet.of;
import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
-import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.MapEntry.entry;
import static org.sonar.api.rules.RuleType.BUG;
import static org.sonar.api.rules.RuleType.CODE_SMELL;
import static org.sonar.api.rules.RuleType.VULNERABILITY;
+import static org.sonar.db.rule.RuleTesting.setCreatedAt;
+import static org.sonar.db.rule.RuleTesting.setIsTemplate;
+import static org.sonar.db.rule.RuleTesting.setLanguage;
+import static org.sonar.db.rule.RuleTesting.setName;
+import static org.sonar.db.rule.RuleTesting.setOrganizationUuid;
+import static org.sonar.db.rule.RuleTesting.setRepositoryKey;
+import static org.sonar.db.rule.RuleTesting.setRuleKey;
+import static org.sonar.db.rule.RuleTesting.setSeverity;
+import static org.sonar.db.rule.RuleTesting.setStatus;
+import static org.sonar.db.rule.RuleTesting.setSystemTags;
+import static org.sonar.db.rule.RuleTesting.setTags;
+import static org.sonar.db.rule.RuleTesting.setTemplateId;
+import static org.sonar.db.rule.RuleTesting.setType;
+import static org.sonar.db.rule.RuleTesting.setUpdatedAt;
import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.INHERITED;
import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.OVERRIDES;
-import static org.sonar.server.rule.index.RuleDocTesting.newDoc;
import static org.sonar.server.rule.index.RuleIndex.FACET_LANGUAGES;
import static org.sonar.server.rule.index.RuleIndex.FACET_REPOSITORIES;
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.rule.index.RuleIndexDefinition.INDEX_TYPE_ACTIVE_RULE;
-import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX_TYPE_RULE;
public class RuleIndexTest {
- private static final RuleKey RULE_KEY_1 = RuleTesting.XOO_X1;
- private static final RuleKey RULE_KEY_2 = RuleTesting.XOO_X2;
- private static final RuleKey RULE_KEY_3 = RuleTesting.XOO_X3;
- private static final RuleKey RULE_KEY_4 = RuleKey.of("xoo", "x4");
private static final String QUALITY_PROFILE_KEY1 = "qp1";
private static final String QUALITY_PROFILE_KEY2 = "qp2";
@Rule
public EsTester tester = new EsTester(new RuleIndexDefinition(new MapSettings()));
+ @Rule
+ public DbTester dbTester = DbTester.create(system2);
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
private RuleIndex index;
private RuleIndexer ruleIndexer;
@Before
public void setUp() {
- ruleIndexer = new RuleIndexer(tester.client(), null, null, null);
- activeRuleIndexer = new ActiveRuleIndexer(system2, null, tester.client());
+ ruleIndexer = new RuleIndexer(tester.client(), dbTester.getDbClient());
+ activeRuleIndexer = new ActiveRuleIndexer(system2, dbTester.getDbClient(), tester.client());
index = new RuleIndex(tester.client());
}
@Test
public void search_all_rules() {
- indexRules(
- newDoc(RuleKey.of("javascript", "S001")),
- newDoc(RuleKey.of("java", "S002")));
+ createRule();
+ createRule();
SearchIdResult results = index.search(new RuleQuery(), new SearchOptions());
@Test
public void search_by_key() {
- RuleKey js1 = RuleKey.of("javascript", "X001");
- RuleKey cobol1 = RuleKey.of("cobol", "X001");
- RuleKey php2 = RuleKey.of("php", "S002");
- indexRules(
- newDoc(js1).setName("First rule").setHtmlDescription("The first rule"),
- newDoc(cobol1).setName("Second rule").setHtmlDescription("The second rule"),
- newDoc(php2).setName("Third rule").setHtmlDescription("The third rule"));
+ RuleDefinitionDto js1 = createRule(
+ setRepositoryKey("javascript"),
+ setRuleKey("X001"));
+ RuleDefinitionDto cobol1 = createRule(
+ setRepositoryKey("cobol"),
+ setRuleKey("X001"));
+ RuleDefinitionDto php2 = createRule(
+ setRepositoryKey("php"),
+ setRuleKey("S002"));
// key
RuleQuery query = new RuleQuery().setQueryText("X001");
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(js1, cobol1);
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(js1.getKey(), cobol1.getKey());
// partial key does not match
query = new RuleQuery().setQueryText("X00");
// repo:key -> nice-to-have !
query = new RuleQuery().setQueryText("javascript:X001");
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(js1);
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(js1.getKey());
}
@Test
public void search_by_case_insensitive_key() {
- RuleKey ruleKey = RuleKey.of("javascript", "X001");
- indexRules(newDoc(ruleKey).setName("Name without key").setHtmlDescription("Description without key"));
+ RuleDefinitionDto ruleDto = createRule(
+ setRepositoryKey("javascript"),
+ setRuleKey("X001"));
RuleQuery query = new RuleQuery().setQueryText("x001");
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(ruleKey);
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(ruleDto.getKey());
}
@Test
public void filter_by_key() {
- indexRules(
- newDoc(RuleKey.of("javascript", "X001")),
- newDoc(RuleKey.of("cobol", "X001")),
- newDoc(RuleKey.of("php", "S002")));
+ createRule(
+ setRepositoryKey("javascript"),
+ setRuleKey("X001"));
+ createRule(
+ setRepositoryKey("cobol"),
+ setRuleKey("X001"));
+ createRule(
+ setRepositoryKey("php"),
+ setRuleKey("S002"));
// key
RuleQuery query = new RuleQuery().setKey(RuleKey.of("javascript", "X001").toString());
@Test
public void search_name_by_query() {
- indexRules(newDoc(RuleKey.of("javascript", "S001"))
- .setName("testing the partial match and matching of rule"));
+ createRule(setName("testing the partial match and matching of rule"));
// substring
RuleQuery query = new RuleQuery().setQueryText("test");
public void search_name_with_protected_chars() {
String nameWithProtectedChars = "ja#va&sc\"r:ipt";
- indexRules(newDoc(RuleKey.of("javascript", "S001"))
- .setName(nameWithProtectedChars));
+ RuleDefinitionDto ruleDto = createRule(setName(nameWithProtectedChars));
RuleQuery protectedCharsQuery = new RuleQuery().setQueryText(nameWithProtectedChars);
List<RuleKey> results = index.search(protectedCharsQuery, new SearchOptions()).getIds();
- assertThat(results).containsOnly(RuleKey.of("javascript", "S001"));
+ assertThat(results).containsOnly(ruleDto.getKey());
}
@Test
public void search_by_any_of_repositories() {
- indexRules(
- newDoc(RuleKey.of("findbugs", "S001")),
- newDoc(RuleKey.of("pmd", "S002")));
+ RuleDefinitionDto findbugs = createRule(
+ setRepositoryKey("findbugs"),
+ setRuleKey("S001"));
+ RuleDefinitionDto pmd = createRule(
+ setRepositoryKey("pmd"),
+ setRuleKey("S002"));
- List<SearchHit> docs = tester.getDocuments(INDEX_TYPE_RULE);
- for (SearchHit doc : docs) {
- System.out.println(doc.getSourceAsString());
- }
RuleQuery query = new RuleQuery().setRepositories(asList("checkstyle", "pmd"));
SearchIdResult results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("pmd", "S002"));
+ assertThat(results.getIds()).containsOnly(pmd.getKey());
// no results
query = new RuleQuery().setRepositories(singletonList("checkstyle"));
assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
// empty list => no filter
- query = new RuleQuery().setRepositories(Collections.emptyList());
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ query = new RuleQuery().setRepositories(emptyList());
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(findbugs.getKey(), pmd.getKey());
}
@Test
public void filter_by_tags() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setAllTags(singleton("tag1")),
- newDoc(RuleKey.of("java", "S002")).setAllTags(singleton("tag2")));
+ OrganizationDto organization = dbTester.organizations().insert();
+
+ RuleDefinitionDto rule1 = createRule(setSystemTags("tag1s"));
+ createRuleMetadata(rule1, organization, setTags("tag1"));
+ RuleDefinitionDto rule2 = createRule(setSystemTags("tag2s"));
+ createRuleMetadata(rule2, organization, setTags("tag2"));
// find all
RuleQuery query = new RuleQuery();
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(rule1.getKey(), rule2.getKey());
+
+ // tag2s in filter
+ query = new RuleQuery().setOrganizationUuid(organization.getUuid()).setTags(of("tag2s"));
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(rule2.getKey());
+
// tag2 in filter
- query = new RuleQuery().setTags(ImmutableSet.of("tag2"));
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S002"));
+ query = new RuleQuery().setOrganizationUuid(organization.getUuid()).setTags(of("tag2"));
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(rule2.getKey());
// empty list => no filter
query = new RuleQuery().setTags(emptySet());
// null list => no filter
query = new RuleQuery().setTags(null);
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(rule1.getKey(), rule2.getKey());
+ }
+
+ @SafeVarargs
+ private final RuleDefinitionDto createRule(Consumer<RuleDefinitionDto>... populaters) {
+ RuleDefinitionDto ruleDto = dbTester.rules().insert(populaters);
+ ruleIndexer.indexRuleDefinition(ruleDto.getKey());
+ return ruleDto;
+ }
+
+ @SafeVarargs
+ private final RuleMetadataDto createRuleMetadata(RuleDefinitionDto rule, OrganizationDto organization, Consumer<RuleMetadataDto>... populaters) {
+ RuleMetadataDto ruleMetadataDto = dbTester.rules().insertOrUpdateMetadata(rule, organization, populaters);
+ ruleIndexer.indexRuleExtension(organization, rule.getKey());
+ return ruleMetadataDto;
}
@Test
public void tags_facet_supports_selected_value_with_regexp_special_characters() {
- indexRules(newDoc(RuleKey.of("java", "S001")).setAllTags(singleton("misra++")));
+ OrganizationDto organization = dbTester.organizations().insert();
- RuleQuery query = new RuleQuery().setTags(singletonList("misra["));
- SearchOptions options = new SearchOptions().addFacets(RuleIndex.FACET_TAGS);
+ RuleDefinitionDto rule = createRule();
+ createRuleMetadata(rule, organization, setTags("misra++"));
+
+ RuleQuery query = new RuleQuery()
+ .setOrganizationUuid(organization.getUuid())
+ .setTags(singletonList("misra["));
+ SearchOptions options = new SearchOptions().addFacets(FACET_TAGS);
// do not fail
assertThat(index.search(query, options).getTotal()).isEqualTo(0);
@Test
public void search_by_types() {
- indexRules(
- 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));
+ RuleDefinitionDto codeSmell = createRule(setType(CODE_SMELL));
+ RuleDefinitionDto vulnerability = createRule(setType(VULNERABILITY));
+ RuleDefinitionDto bug1 = createRule(setType(BUG));
+ RuleDefinitionDto bug2 = createRule(setType(BUG));
// find all
RuleQuery query = new RuleQuery();
assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(4);
// type3 in filter
- query = new RuleQuery().setTypes(ImmutableSet.of(VULNERABILITY));
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RULE_KEY_2);
+ query = new RuleQuery().setTypes(of(VULNERABILITY));
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(vulnerability.getKey());
- query = new RuleQuery().setTypes(ImmutableSet.of(BUG));
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RULE_KEY_3, RULE_KEY_4);
+ query = new RuleQuery().setTypes(of(BUG));
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(bug1.getKey(), bug2.getKey());
// types in query => nothing
query = new RuleQuery().setQueryText("code smell bug vulnerability");
@Test
public void search_by_is_template() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setIsTemplate(false),
- newDoc(RuleKey.of("java", "S002")).setIsTemplate(true));
+ RuleDefinitionDto ruleNoTemplate = createRule(setIsTemplate(false));
+ RuleDefinitionDto ruleIsTemplate = createRule(setIsTemplate(true));
// find all
RuleQuery query = new RuleQuery();
// Only template
query = new RuleQuery().setIsTemplate(true);
results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
+ assertThat(results.getIds()).containsOnly(ruleIsTemplate.getKey());
// Only not template
query = new RuleQuery().setIsTemplate(false);
results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S001"));
+ assertThat(results.getIds()).containsOnly(ruleNoTemplate.getKey());
// null => no filter
query = new RuleQuery().setIsTemplate(null);
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsOnly(ruleIsTemplate.getKey(), ruleNoTemplate.getKey());
}
@Test
public void search_by_template_key() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setIsTemplate(true),
- newDoc(RuleKey.of("java", "S001_MY_CUSTOM")).setTemplateKey("java:S001"));
+ RuleDefinitionDto template = createRule(setIsTemplate(true));
+ RuleDefinitionDto customRule = createRule(setTemplateId(template.getId()));
// find all
RuleQuery query = new RuleQuery();
assertThat(results.getIds()).hasSize(2);
// Only custom rule
- query = new RuleQuery().setTemplateKey("java:S001");
+ query = new RuleQuery().setTemplateKey(template.getKey().toString());
results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S001_MY_CUSTOM"));
+ assertThat(results.getIds()).containsOnly(customRule.getKey());
// null => no filter
query = new RuleQuery().setTemplateKey(null);
@Test
public void search_by_any_of_languages() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setLanguage("java"),
- newDoc(RuleKey.of("javascript", "S002")).setLanguage("js"));
+ RuleDefinitionDto java = createRule(setLanguage("java"));
+ RuleDefinitionDto javascript = createRule(setLanguage("js"));
RuleQuery query = new RuleQuery().setLanguages(asList("cobol", "js"));
SearchIdResult results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("javascript", "S002"));
+ assertThat(results.getIds()).containsOnly(javascript.getKey());
// no results
query = new RuleQuery().setLanguages(singletonList("cpp"));
assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
// empty list => no filter
- query = new RuleQuery().setLanguages(Collections.emptyList());
+ query = new RuleQuery().setLanguages(emptyList());
assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
// null list => no filter
@Test
public void search_by_any_of_severities() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setSeverity(BLOCKER),
- newDoc(RuleKey.of("java", "S002")).setSeverity(INFO));
+ RuleDefinitionDto blocker = createRule(setSeverity(BLOCKER));
+ RuleDefinitionDto info = createRule(setSeverity(INFO));
RuleQuery query = new RuleQuery().setSeverities(asList(INFO, MINOR));
SearchIdResult results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
+ assertThat(results.getIds()).containsOnly(info.getKey());
// no results
query = new RuleQuery().setSeverities(singletonList(MINOR));
assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
// empty list => no filter
- query = new RuleQuery().setSeverities(Collections.emptyList());
+ query = new RuleQuery().setSeverities(emptyList());
assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
// null list => no filter
@Test
public void search_by_any_of_statuses() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setStatus(RuleStatus.BETA.name()),
- newDoc(RuleKey.of("java", "S002")).setStatus(RuleStatus.READY.name()));
+ RuleDefinitionDto beta = createRule(setStatus(RuleStatus.BETA));
+ RuleDefinitionDto ready = createRule(setStatus(RuleStatus.READY));
RuleQuery query = new RuleQuery().setStatuses(asList(RuleStatus.DEPRECATED, RuleStatus.READY));
SearchIdResult<RuleKey> results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
+ assertThat(results.getIds()).containsOnly(ready.getKey());
// no results
query = new RuleQuery().setStatuses(singletonList(RuleStatus.DEPRECATED));
assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
// empty list => no filter
- query = new RuleQuery().setStatuses(Collections.emptyList());
+ query = new RuleQuery().setStatuses(emptyList());
assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
// null list => no filter
@Test
public void search_by_profile() throws InterruptedException {
- indexRules(
- newDoc(RULE_KEY_1),
- newDoc(RULE_KEY_2),
- newDoc(RULE_KEY_3));
+ RuleDefinitionDto rule1 = createRule();
+ RuleDefinitionDto rule2 = createRule();
+ RuleDefinitionDto rule3 = createRule();
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)));
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, rule1.getKey())),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, rule1.getKey())),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, rule2.getKey())));
assertThat(tester.countDocuments(INDEX_TYPE_ACTIVE_RULE)).isEqualTo(3);
// 1. get all active rules.
assertThat(index.search(new RuleQuery().setActivation(true), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_1, RULE_KEY_2);
+ .containsOnly(rule1.getKey(), rule2.getKey());
// 2. get all inactive rules.
assertThat(index.search(new RuleQuery().setActivation(false), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_3);
+ .containsOnly(rule3.getKey());
// 3. get all rules not active on profile
assertThat(index.search(new RuleQuery().setActivation(false).setQProfileKey(QUALITY_PROFILE_KEY2), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_2, RULE_KEY_3);
+ .containsOnly(rule2.getKey(), rule3.getKey());
// 4. get all active rules on profile
assertThat(index.search(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY2), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_1);
+ .containsOnly(rule1.getKey());
}
@Test
public void search_by_profile_and_inheritance() {
- indexRules(
- newDoc(RULE_KEY_1),
- newDoc(RULE_KEY_2),
- newDoc(RULE_KEY_3),
- newDoc(RULE_KEY_4));
+ RuleDefinitionDto rule1 = createRule();
+ RuleDefinitionDto rule2 = createRule();
+ RuleDefinitionDto rule3 = createRule();
+ RuleDefinitionDto rule4 = createRule();
- ActiveRuleKey activeRuleKey1 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1);
- ActiveRuleKey activeRuleKey2 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2);
- ActiveRuleKey activeRuleKey3 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_3);
+ ActiveRuleKey activeRuleKey1 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, rule1.getKey());
+ ActiveRuleKey activeRuleKey2 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, rule2.getKey());
+ ActiveRuleKey activeRuleKey3 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, rule3.getKey());
indexActiveRules(
ActiveRuleDocTesting.newDoc(activeRuleKey1),
ActiveRuleDocTesting.newDoc(activeRuleKey2),
ActiveRuleDocTesting.newDoc(activeRuleKey3),
// Profile 2 is a child a profile 1
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)).setInheritance(INHERITED.name()),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_2)).setInheritance(OVERRIDES.name()),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_3)).setInheritance(INHERITED.name()));
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, rule1.getKey())).setInheritance(INHERITED.name()),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, rule2.getKey())).setInheritance(OVERRIDES.name()),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, rule3.getKey())).setInheritance(INHERITED.name()));
// 0. get all rules
assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds())
// 2. get all inactive rules.
assertThat(index.search(new RuleQuery()
.setActivation(false), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_4);
+ .containsOnly(rule4.getKey());
// 3. get Inherited Rules on profile1
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY1)
- .setInheritance(ImmutableSet.of(INHERITED.name())),
+ .setInheritance(of(INHERITED.name())),
new SearchOptions()).getIds())
.isEmpty();
// 4. get Inherited Rules on profile2
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY2)
- .setInheritance(ImmutableSet.of(INHERITED.name())),
+ .setInheritance(of(INHERITED.name())),
new SearchOptions()).getIds())
.hasSize(2);
// 5. get Overridden Rules on profile1
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY1)
- .setInheritance(ImmutableSet.of(OVERRIDES.name())),
+ .setInheritance(of(OVERRIDES.name())),
new SearchOptions()).getIds())
.isEmpty();
// 6. get Overridden Rules on profile2
assertThat(index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY2)
- .setInheritance(ImmutableSet.of(OVERRIDES.name())),
+ .setInheritance(of(OVERRIDES.name())),
new SearchOptions()).getIds())
.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())),
+ .setInheritance(of(INHERITED.name(), OVERRIDES.name())),
new SearchOptions()).getIds())
.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())),
+ .setInheritance(of(INHERITED.name(), OVERRIDES.name())),
new SearchOptions()).getIds())
.hasSize(3);
}
@Test
public void search_by_profile_and_active_severity() {
- indexRules(
- newDoc(RULE_KEY_1).setSeverity(MAJOR),
- newDoc(RULE_KEY_2).setSeverity(MINOR),
- newDoc(RULE_KEY_3).setSeverity(INFO));
+ RuleDefinitionDto major = createRule(setSeverity(MAJOR));
+ RuleDefinitionDto minor = createRule(setSeverity(MINOR));
+ RuleDefinitionDto info = createRule(setSeverity(INFO));
indexActiveRules(
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)).setSeverity(BLOCKER),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)).setSeverity(BLOCKER),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)).setSeverity(CRITICAL));
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, major.getKey())).setSeverity(BLOCKER),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, major.getKey())).setSeverity(BLOCKER),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, minor.getKey())).setSeverity(CRITICAL));
// 1. get all active rules.
assertThat(index.search(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY1), new SearchOptions()).getIds())
SearchIdResult<RuleKey> result = index.search(new RuleQuery().setActivation(true)
.setQProfileKey(QUALITY_PROFILE_KEY1).setActiveSeverities(singletonList(CRITICAL)),
new SearchOptions().addFacets(singletonList(RuleIndex.FACET_ACTIVE_SEVERITIES)));
- assertThat(result.getIds()).containsOnly(RULE_KEY_2);
+ assertThat(result.getIds()).containsOnly(minor.getKey());
// check stickyness of active severity facet
assertThat(result.getFacets().get(RuleIndex.FACET_ACTIVE_SEVERITIES)).containsOnly(entry(BLOCKER, 1L), entry(CRITICAL, 1L));
@Test
public void all_tags() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setAllTags(asList("tag1", "sys1", "sys2")),
- newDoc(RuleKey.of("java", "S002")).setAllTags(asList("tag2")));
+ OrganizationDto organization = dbTester.organizations().insert();
+
+ RuleDefinitionDto rule1 = createRule(setSystemTags("sys1", "sys2"));
+ createRuleMetadata(rule1, organization,
+ setOrganizationUuid(organization.getUuid()),
+ setTags("tag1"));
- assertThat(index.terms(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, null, 10)).containsOnly("tag1", "tag2", "sys1", "sys2");
+ RuleDefinitionDto rule2 = createRule(setSystemTags());
+ createRuleMetadata(rule2, organization,
+ setOrganizationUuid(organization.getUuid()),
+ setTags("tag2"));
+
+ assertThat(index.listTags(organization.getUuid(), null, 10)).containsOnly("tag1", "tag2", "sys1", "sys2");
+ }
+
+ @Test
+ public void all_tags_minds_the_oranization() {
+ OrganizationDto organization1 = dbTester.organizations().insert();
+ RuleDefinitionDto rule1 = createRule(setSystemTags("sys1"));
+ createRuleMetadata(rule1, organization1,
+ setOrganizationUuid(organization1.getUuid()),
+ setTags("tag1"));
+
+ OrganizationDto organization2 = dbTester.organizations().insert();
+ RuleDefinitionDto rule2 = createRule(setSystemTags("sys2"));
+ createRuleMetadata(rule2, organization2,
+ setOrganizationUuid(organization2.getUuid()),
+ setTags("tag2"));
+
+ assertThat(index.listTags(organization1.getUuid(), null, 10)).containsOnly("tag1", "sys1", "sys2");
+ assertThat(index.listTags(organization2.getUuid(), null, 10)).containsOnly("tag2", "sys1", "sys2");
}
@Test
public void available_since() throws InterruptedException {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setCreatedAt(1000L),
- newDoc(RuleKey.of("java", "S002")).setCreatedAt(2000L));
+ RuleKey ruleOld = createRule(setCreatedAt(1000L)).getKey();
+ RuleKey ruleOlder = createRule(setCreatedAt(2000L)).getKey();
// 0. find all rules;
- assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds()).hasSize(2);
+ assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(ruleOld, ruleOlder);
// 1. find all rules available since a date;
RuleQuery availableSinceQuery = new RuleQuery().setAvailableSince(2000L);
- assertThat(index.search(availableSinceQuery, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S002"));
+ assertThat(index.search(availableSinceQuery, new SearchOptions()).getIds()).containsOnly(ruleOlder);
// 2. find no new rules since tomorrow.
RuleQuery availableSinceNowQuery = new RuleQuery().setAvailableSince(3000L);
- assertThat(index.search(availableSinceNowQuery, new SearchOptions()).getIds()).hasSize(0);
+ assertThat(index.search(availableSinceNowQuery, new SearchOptions()).getIds()).containsOnly();
}
@Test
public void global_facet_on_repositories_and_tags() {
- indexRules(
- newDoc(RuleKey.of("php", "S001")).setAllTags(singletonList("sysTag")),
- newDoc(RuleKey.of("php", "S002")).setAllTags(singletonList("tag1")),
- newDoc(RuleKey.of("javascript", "S002")).setAllTags(asList("tag1", "tag2")));
+ OrganizationDto organization = dbTester.organizations().insert();
+
+ createRule(setRepositoryKey("php"), setSystemTags("sysTag"));
+ RuleDefinitionDto rule1 = createRule(setRepositoryKey("php"), setSystemTags());
+ createRuleMetadata(rule1, organization, setTags("tag1"));
+ RuleDefinitionDto rule2 = createRule(setRepositoryKey("javascript"), setSystemTags());
+ createRuleMetadata(rule2, organization, setTags("tag1", "tag2"));
// should not have any facet!
- RuleQuery query = new RuleQuery();
- SearchIdResult result = index.search(query, new SearchOptions());
- assertThat(result.getFacets().getAll()).isEmpty();
+ RuleQuery query = new RuleQuery().setOrganizationUuid(organization.getUuid());
+ SearchIdResult result1 = index.search(query, new SearchOptions());
+ assertThat(result1.getFacets().getAll()).isEmpty();
// should not have any facet on non matching query!
- result = index.search(new RuleQuery().setQueryText("aeiou"), new SearchOptions().addFacets(singletonList("repositories")));
- assertThat(result.getFacets().getAll()).hasSize(1);
- assertThat(result.getFacets().getAll().get("repositories")).isEmpty();
+ SearchIdResult result2 = index.search(new RuleQuery().setQueryText("aeiou"), new SearchOptions().addFacets(singletonList("repositories")));
+ assertThat(result2.getFacets().getAll()).hasSize(1);
+ assertThat(result2.getFacets().getAll().get("repositories")).isEmpty();
// Repositories Facet is preset
- result = index.search(query, new SearchOptions().addFacets(asList("repositories", "tags")));
- assertThat(result.getFacets()).isNotNull();
- assertThat(result.getFacets().getAll()).hasSize(2);
+ SearchIdResult result3 = index.search(query, new SearchOptions().addFacets(asList("repositories", "tags")));
+ assertThat(result3.getFacets()).isNotNull();
// Verify the value of a given facet
- Map<String, Long> repoFacets = result.getFacets().get("repositories");
+ Map<String, Long> repoFacets = result3.getFacets().get("repositories");
assertThat(repoFacets).containsOnly(entry("php", 2L), entry("javascript", 1L));
// Check that tag facet has both Tags and SystemTags values
- Map<String, Long> tagFacets = result.getFacets().get("tags");
+ Map<String, Long> tagFacets = result3.getFacets().get("tags");
assertThat(tagFacets).containsOnly(entry("tag1", 2L), entry("sysTag", 1L), entry("tag2", 1L));
+
+ // Check that there are no other facets
+ assertThat(result3.getFacets().getAll()).hasSize(2);
+ }
+
+ private void sticky_facet_rule_setup() {
+ insertRuleDefinition(setRepositoryKey("xoo"), setRuleKey("S001"), setLanguage("java"), setSystemTags(), setType(BUG));
+ insertRuleDefinition(setRepositoryKey("xoo"), setRuleKey("S002"), setLanguage("java"), setSystemTags(), setType(CODE_SMELL));
+ insertRuleDefinition(setRepositoryKey("xoo"), setRuleKey("S003"), setLanguage("java"), setSystemTags("T1", "T2"), setType(CODE_SMELL));
+ insertRuleDefinition(setRepositoryKey("xoo"), setRuleKey("S011"), setLanguage("cobol"), setSystemTags(), setType(CODE_SMELL));
+ insertRuleDefinition(setRepositoryKey("xoo"), setRuleKey("S012"), setLanguage("cobol"), setSystemTags(), setType(BUG));
+ insertRuleDefinition(setRepositoryKey("foo"), setRuleKey("S013"), setLanguage("cobol"), setSystemTags("T3", "T4"), setType(VULNERABILITY));
+ insertRuleDefinition(setRepositoryKey("foo"), setRuleKey("S111"), setLanguage("cpp"), setSystemTags(), setType(BUG));
+ insertRuleDefinition(setRepositoryKey("foo"), setRuleKey("S112"), setLanguage("cpp"), setSystemTags(), setType(CODE_SMELL));
+ insertRuleDefinition(setRepositoryKey("foo"), setRuleKey("S113"), setLanguage("cpp"), setSystemTags("T2", "T3"), setType(CODE_SMELL));
}
@Test
- public void sticky_facets() {
- indexRules(
- newDoc(RuleKey.of("xoo", "S001")).setLanguage("java").setAllTags(Collections.emptyList()).setType(BUG),
- newDoc(RuleKey.of("xoo", "S002")).setLanguage("java").setAllTags(Collections.emptyList()).setType(CODE_SMELL),
- newDoc(RuleKey.of("xoo", "S003")).setLanguage("java").setAllTags(asList("T1", "T2")).setType(CODE_SMELL),
- newDoc(RuleKey.of("xoo", "S011")).setLanguage("cobol").setAllTags(Collections.emptyList()).setType(CODE_SMELL),
- newDoc(RuleKey.of("xoo", "S012")).setLanguage("cobol").setAllTags(Collections.emptyList()).setType(BUG),
- newDoc(RuleKey.of("foo", "S013")).setLanguage("cobol").setAllTags(asList("T3", "T4")).setType(VULNERABILITY),
- newDoc(RuleKey.of("foo", "S111")).setLanguage("cpp").setAllTags(Collections.emptyList()).setType(BUG),
- newDoc(RuleKey.of("foo", "S112")).setLanguage("cpp").setAllTags(Collections.emptyList()).setType(CODE_SMELL),
- newDoc(RuleKey.of("foo", "S113")).setLanguage("cpp").setAllTags(asList("T2", "T3")).setType(CODE_SMELL));
+ public void sticky_facets_base() {
+ sticky_facet_rule_setup();
- // 0 assert Base
- assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds()).hasSize(9);
+ RuleQuery query = new RuleQuery();
+
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(9);
+ }
+
+ /**
+ * Facet with no filters at all
+ */
+ @Test
+ public void sticky_facets_no_filters() {
+ sticky_facet_rule_setup();
+
+ RuleQuery query = new RuleQuery()
+ .setOrganizationUuid("some_uuid");
- // 1 Facet with no filters at all
- SearchIdResult result = index.search(new RuleQuery(), new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS, FACET_TYPES)));
+ SearchIdResult result = index.search(query, new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES,
+ FACET_TAGS, FACET_TYPES)));
assertThat(result.getFacets().getAll()).hasSize(4);
assertThat(result.getFacets().getAll().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java", "cobol");
assertThat(result.getFacets().getAll().get(FACET_REPOSITORIES).keySet()).containsExactly("xoo", "foo");
assertThat(result.getFacets().getAll().get(FACET_TAGS).keySet()).containsOnly("T1", "T2", "T3", "T4");
assertThat(result.getFacets().getAll().get(FACET_TYPES).keySet()).containsOnly("BUG", "CODE_SMELL", "VULNERABILITY");
+ }
- // 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)));
+ /**
+ * Facet with a language filter
+ * -- lang facet should still have all language
+ */
+ @Test
+ public void sticky_facets_with_1_filter() {
+ sticky_facet_rule_setup();
+
+ RuleQuery query = new RuleQuery()
+ .setOrganizationUuid("some_uuid")
+ .setLanguages(ImmutableList.of("cpp"));
+
+ SearchIdResult result = index.search(query, 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");
+ assertThat(result.getFacets().get(FACET_REPOSITORIES).keySet()).containsOnly("foo");
+ assertThat(result.getFacets().get(FACET_TAGS).keySet()).containsOnly("T2", "T3");
+ }
+
+ @Test
+ public void tags_facet_should_find_tags_of_specified_organization() {
+ OrganizationDto organization = dbTester.organizations().insert();
+
+ RuleDefinitionDto rule = insertRuleDefinition(setSystemTags());
+ dbTester.rules().insertOrUpdateMetadata(rule, organization, setTags("bla"));
+ ruleIndexer.indexRuleExtension(organization, rule.getKey());
+
+ RuleQuery query = new RuleQuery()
+ .setOrganizationUuid(organization.getUuid());
+ SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));
+
+ SearchIdResult result = index.search(query, options);
+ assertThat(result.getFacets().get(FACET_TAGS)).contains(entry("bla", 1L));
+ }
+
+ @Test
+ public void tags_facet_should_not_find_tags_of_any_other_organization() {
+ OrganizationDto organization1 = dbTester.organizations().insert();
+ OrganizationDto organization2 = dbTester.organizations().insert();
+
+ RuleDefinitionDto rule = insertRuleDefinition(setSystemTags());
+ dbTester.rules().insertOrUpdateMetadata(rule, organization1, setTags("bla"));
+
+ RuleQuery query = new RuleQuery()
+ .setOrganizationUuid(organization2.getUuid());
+ SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));
+
+ SearchIdResult result = index.search(query, options);
+ assertThat(result.getFacets().get(FACET_TAGS)).contains();
+ }
- // 3 facet with 2 filters
- // -- lang facet for tag T2
- // -- tag facet for lang cpp
- // -- repository for cpp & T2
- result = index.search(new RuleQuery()
+ @Test
+ public void tags_facet_should_be_available_if_organization_is_speficied() {
+ RuleQuery query = new RuleQuery()
+ .setOrganizationUuid("some_org_id");
+ SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));
+
+ SearchIdResult result = index.search(query, options);
+ assertThat(result.getFacets().get(FACET_TAGS)).isNotNull();
+ }
+
+ @Test
+ public void tags_facet_should_be_unavailable_if_no_organization_is_specfified() {
+ RuleQuery query = new RuleQuery();
+ SearchOptions options = new SearchOptions().addFacets(singletonList(FACET_TAGS));
+
+ thrown.expectMessage("Cannot use tags facet, if no organization is specified.");
+ index.search(query, options);
+ }
+
+ /**
+ * Facet with 2 filters
+ * -- lang facet for tag T2
+ * -- tag facet for lang cpp
+ * -- repository for cpp & T2
+ */
+ @Test
+ public void sticky_facets_with_2_filters() {
+ sticky_facet_rule_setup();
+
+ RuleQuery query = new RuleQuery()
+ .setOrganizationUuid("some_uuid")
.setLanguages(ImmutableList.of("cpp"))
- .setTags(ImmutableList.of("T2")), new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
+ .setTags(ImmutableList.of("T2"));
+
+ SearchIdResult result = index.search(query, 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");
assertThat(result.getFacets().get(FACET_REPOSITORIES).keySet()).containsOnly("foo");
assertThat(result.getFacets().get(FACET_TAGS).keySet()).containsOnly("T2", "T3");
+ }
- // 4 facet with 3 filters
- // -- lang facet for tag T2
- // -- tag facet for lang cpp & java
- // -- repository for (cpp || java) & T2
- // -- type
- result = index.search(new RuleQuery()
+ /**
+ * Facet with 3 filters
+ * -- lang facet for tag T2
+ * -- tag facet for lang cpp & java
+ * -- repository for (cpp || java) & T2
+ * -- type
+ */
+ @Test
+ public void sticky_facets_with_3_filters() {
+ sticky_facet_rule_setup();
+
+ RuleQuery query = new RuleQuery()
+ .setOrganizationUuid("some_uuid")
.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));
+
+ SearchIdResult result = index.search(query, 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");
@Test
public void sort_by_name() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setName("abcd"),
- newDoc(RuleKey.of("java", "S002")).setName("ABC"),
- newDoc(RuleKey.of("java", "S003")).setName("FGH"));
+ RuleDefinitionDto abcd = insertRuleDefinition(setName("abcd"));
+ RuleDefinitionDto abc = insertRuleDefinition(setName("ABC"));
+ RuleDefinitionDto fgh = insertRuleDefinition(setName("FGH"));
// ascending
RuleQuery query = new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_NAME);
SearchIdResult<RuleKey> results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S002"), RuleKey.of("java", "S001"), RuleKey.of("java", "S003"));
+ assertThat(results.getIds()).containsExactly(abc.getKey(), abcd.getKey(), fgh.getKey());
// descending
query = new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_NAME).setAscendingSort(false);
results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S003"), RuleKey.of("java", "S001"), RuleKey.of("java", "S002"));
+ assertThat(results.getIds()).containsExactly(fgh.getKey(), abcd.getKey(), abc.getKey());
}
@Test
public void default_sort_is_by_updated_at_desc() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setCreatedAt(1000L).setUpdatedAt(1000L),
- newDoc(RuleKey.of("java", "S002")).setCreatedAt(1000L).setUpdatedAt(3000L),
- newDoc(RuleKey.of("java", "S003")).setCreatedAt(1000L).setUpdatedAt(2000L));
+ RuleDefinitionDto old = insertRuleDefinition(setCreatedAt(1000L), setUpdatedAt(1000L));
+ RuleDefinitionDto oldest = insertRuleDefinition(setCreatedAt(1000L), setUpdatedAt(3000L));
+ RuleDefinitionDto older = insertRuleDefinition(setCreatedAt(1000L), setUpdatedAt(2000L));
SearchIdResult<RuleKey> results = index.search(new RuleQuery(), new SearchOptions());
- assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S002"), RuleKey.of("java", "S003"), RuleKey.of("java", "S001"));
+ assertThat(results.getIds()).containsExactly(oldest.getKey(), older.getKey(), old.getKey());
}
@Test
@Test
public void paging() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")),
- newDoc(RuleKey.of("java", "S002")),
- newDoc(RuleKey.of("java", "S003")));
+ insertRuleDefinition();
+ insertRuleDefinition();
+ insertRuleDefinition();
// from 0 to 1 included
SearchOptions options = new SearchOptions();
@Test
public void search_all_keys_by_query() {
- indexRules(
- newDoc(RuleKey.of("javascript", "X001")),
- newDoc(RuleKey.of("cobol", "X001")),
- newDoc(RuleKey.of("php", "S002")));
+ insertRuleDefinition(setRepositoryKey("javascript"), setRuleKey("X001"));
+ insertRuleDefinition(setRepositoryKey("cobol"), setRuleKey("X001"));
+ insertRuleDefinition(setRepositoryKey("php"), setRuleKey("S002"));
// key
assertThat(index.searchAll(new RuleQuery().setQueryText("X001"))).hasSize(2);
@Test
public void search_all_keys_by_profile() {
- indexRules(
- newDoc(RULE_KEY_1),
- newDoc(RULE_KEY_2),
- newDoc(RULE_KEY_3));
+ RuleDefinitionDto rule1 = insertRuleDefinition();
+ RuleDefinitionDto rule2 = insertRuleDefinition();
+ RuleDefinitionDto rule3 = insertRuleDefinition();
+
+ RuleKey rule1Key = rule1.getKey();
+ RuleKey rule2Key = rule2.getKey();
+ RuleKey rule3Key = rule3.getKey();
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)));
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, rule1Key)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, rule1Key)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, rule2Key)));
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);
+ assertThat(index.searchAll(new RuleQuery().setActivation(true))).containsOnly(rule1Key, rule2Key);
// 2. get all inactive rules.
- assertThat(index.searchAll(new RuleQuery().setActivation(false))).containsOnly(RULE_KEY_3);
+ assertThat(index.searchAll(new RuleQuery().setActivation(false))).containsOnly(rule3Key);
// 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);
+ assertThat(index.searchAll(new RuleQuery().setActivation(false).setQProfileKey(QUALITY_PROFILE_KEY2))).containsOnly(rule2Key, rule3Key);
// 4. get all active rules on profile
- assertThat(index.searchAll(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY2))).containsOnly(RULE_KEY_1);
+ assertThat(index.searchAll(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY2))).containsOnly(rule1Key);
}
- private void indexRules(RuleDoc... rules) {
- ruleIndexer.index(asList(rules).iterator());
+ @SafeVarargs
+ private final RuleDefinitionDto insertRuleDefinition(Consumer<RuleDefinitionDto>... populaters) {
+ RuleDefinitionDto ruleDefinitionDto = dbTester.rules().insert(populaters);
+ ruleIndexer.indexRuleDefinition(ruleDefinitionDto.getKey());
+ return ruleDefinitionDto;
}
private void indexActiveRules(ActiveRuleDoc... docs) {
*/
package org.sonar.server.rule.index;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.MapSettings;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
-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.organization.OrganizationDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.server.es.EsTester;
public class RuleIndexerTest {
- private System2 system2 = System2.INSTANCE;
-
@Rule
public EsTester esTester = new EsTester(new RuleIndexDefinition(new MapSettings()));
@Rule
- public DbTester dbTester = DbTester.create(system2);
+ public DbTester dbTester = DbTester.create();
private DbClient dbClient = dbTester.getDbClient();
+ private final RuleIndexer underTest = new RuleIndexer(esTester.client(), dbClient);
private DbSession dbSession = dbTester.getSession();
private RuleDefinitionDto rule = new RuleDefinitionDto()
.setRuleKey("S001")
.setType(RuleType.BUG)
.setCreatedAt(1500000000000L)
.setUpdatedAt(1600000000000L);
- private OrganizationDto organization;
-
- @Before
- public void before() {
- organization = dbTester.getDefaultOrganization();
- }
@Test
public void index_nothing() {
- RuleIndexer indexer = createIndexer();
-// indexer.index(Iterators.emptyIterator());
+ // underTest.index(Iterators.emptyIterator());
assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(0L);
}
dbClient.ruleDao().insert(dbSession, rule);
dbSession.commit();
- RuleIndexer indexer = createIndexer();
- indexer.index(organization, rule.getKey());
+ underTest.indexRuleDefinition(rule.getKey());
assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1);
}
@Test
public void removed_rule_is_not_removed_from_index() {
- RuleIndexer indexer = createIndexer();
-
// Create and Index rule
dbClient.ruleDao().insert(dbSession, rule.setStatus(RuleStatus.READY));
dbSession.commit();
- indexer.index(organization, rule.getKey());
+ underTest.indexRuleDefinition(rule.getKey());
assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1);
// Remove rule
dbTester.getDbClient().ruleDao().update(dbTester.getSession(), rule.setStatus(RuleStatus.READY).setUpdatedAt(2000000000000L));
dbTester.getSession().commit();
- indexer.index(organization, rule.getKey());
-
- assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1);
- }
-
- @Test
- public void index_on_startup() {
- RuleIndexer indexer = createIndexer();
-
- // Create and Index rule
- dbClient.ruleDao().insert(dbSession, rule.setStatus(RuleStatus.READY));
- dbSession.commit();
+ underTest.indexRuleDefinition(rule.getKey());
- indexer.indexOnStartup(indexer.getIndexTypes());
assertThat(esTester.countDocuments(RuleIndexDefinition.INDEX_TYPE_RULE)).isEqualTo(1);
}
-
- private RuleIndexer createIndexer() {
- return new RuleIndexer(esTester.client(), dbClient, new RuleIteratorFactory(dbTester.getDbClient()), TestDefaultOrganizationProvider.from(dbTester));
- }
-
}
private DbClient dbClient = dbTester.getDbClient();
private DbSession dbSession = dbTester.getSession();
- private RuleDto templateRule;
+ private RuleDefinitionDto templateRule;
private RuleDefinitionDto customRule;
@Before
public void setUp() throws Exception {
- templateRule = new RuleDto()
+ templateRule = new RuleDefinitionDto()
.setRuleKey("S001")
.setRepositoryKey("xoo")
.setConfigKey("S1")
.setSystemTags(newHashSet("cwe"))
.setType(RuleType.BUG)
.setCreatedAt(1500000000000L)
- .setUpdatedAt(1600000000000L)
- .setOrganizationUuid(dbTester.getDefaultOrganization().getUuid())
- .setTags(newHashSet("performance"));
+ .setUpdatedAt(1600000000000L);
customRule = new RuleDefinitionDto()
.setRuleKey("S002")
@Test
public void iterator_over_one_rule() {
- dbTester.rules().insertRule(templateRule);
+ dbTester.rules().insert(templateRule);
- List<RuleDoc> results = getResults();
+ List<RuleDocWithSystemScope> results = getResults();
assertThat(results).hasSize(1);
- RuleDoc templateDoc = getRuleDoc(results, templateRule.getRuleKey());
+ RuleDocWithSystemScope ruleDocWithSystemScope = getRuleDoc(results, templateRule.getRuleKey());
+ RuleDoc templateDoc = ruleDocWithSystemScope.getRuleDoc();
+ RuleExtensionDoc templateExtensionDoc = ruleDocWithSystemScope.getRuleExtensionDoc();
assertThat(templateDoc).isNotNull();
assertThat(templateDoc.key()).isEqualTo(RuleKey.of("xoo", "S001"));
assertThat(templateDoc.ruleKey()).isEqualTo("S001");
assertThat(templateDoc.severity()).isEqualTo(Severity.BLOCKER);
assertThat(templateDoc.status()).isEqualTo(RuleStatus.READY);
assertThat(templateDoc.isTemplate()).isTrue();
- assertThat(templateDoc.allTags()).containsOnly("performance", "cwe");
+ assertThat(templateExtensionDoc.getTags()).containsOnly("cwe");
assertThat(templateDoc.createdAt()).isEqualTo(1500000000000L);
assertThat(templateDoc.updatedAt()).isEqualTo(1600000000000L);
}
@Test
public void iterator_over_rules() {
- dbTester.rules().insertRule(templateRule);
+ dbTester.rules().insert(templateRule);
dbClient.ruleDao().insert(dbSession, customRule);
dbSession.commit();
- List<RuleDoc> results = getResults();
+ List<RuleDocWithSystemScope> results = getResults();
assertThat(results).hasSize(2);
- RuleDoc templateDoc = getRuleDoc(results, templateRule.getRuleKey());
+ RuleDocWithSystemScope templateDocWithSystemScope = getRuleDoc(results, templateRule.getRuleKey());
+ RuleDoc templateDoc = templateDocWithSystemScope.getRuleDoc();
+ RuleExtensionDoc templateExtensionDoc = templateDocWithSystemScope.getRuleExtensionDoc();
assertThat(templateDoc.key()).isEqualTo(RuleKey.of("xoo", "S001"));
assertThat(templateDoc.ruleKey()).isEqualTo("S001");
assertThat(templateDoc.repository()).isEqualTo("xoo");
assertThat(templateDoc.severity()).isEqualTo(Severity.BLOCKER);
assertThat(templateDoc.status()).isEqualTo(RuleStatus.READY);
assertThat(templateDoc.isTemplate()).isTrue();
- assertThat(templateDoc.allTags()).containsOnly("performance", "cwe");
+ assertThat(templateExtensionDoc.getTags()).containsOnly("cwe");
assertThat(templateDoc.createdAt()).isEqualTo(1500000000000L);
assertThat(templateDoc.updatedAt()).isEqualTo(1600000000000L);
- RuleDoc customDoc = getRuleDoc(results, customRule.getRuleKey());
+ RuleDocWithSystemScope customDocWithSystemScope = getRuleDoc(results, customRule.getRuleKey());
+ RuleDoc customDoc = customDocWithSystemScope.getRuleDoc();
+ RuleExtensionDoc customExtensionDoc = customDocWithSystemScope.getRuleExtensionDoc();
assertThat(customDoc.key()).isEqualTo(RuleKey.of("xoo", "S002"));
assertThat(customDoc.ruleKey()).isEqualTo("S002");
assertThat(customDoc.repository()).isEqualTo("xoo");
assertThat(customDoc.severity()).isEqualTo(Severity.MAJOR);
assertThat(customDoc.status()).isEqualTo(RuleStatus.BETA);
assertThat(customDoc.isTemplate()).isFalse();
- assertThat(customDoc.allTags()).isEmpty();
+ assertThat(customExtensionDoc.getTags()).isEmpty();
assertThat(customDoc.createdAt()).isEqualTo(2000000000000L);
assertThat(customDoc.updatedAt()).isEqualTo(2100000000000L);
}
@Test
public void custom_rule() {
- dbTester.rules().insertRule(templateRule);
+ dbTester.rules().insert(templateRule);
dbClient.ruleDao().insert(dbSession, customRule.setTemplateId(templateRule.getId()));
dbSession.commit();
- List<RuleDoc> results = getResults();
+ List<RuleDocWithSystemScope> results = getResults();
assertThat(results).hasSize(2);
- RuleDoc templateDoc = getRuleDoc(results, templateRule.getRuleKey());
+ RuleDocWithSystemScope templateDocWithSystemScope = getRuleDoc(results, templateRule.getRuleKey());
+ RuleDoc templateDoc = templateDocWithSystemScope.getRuleDoc();
assertThat(templateDoc.isTemplate()).isTrue();
assertThat(templateDoc.templateKey()).isNull();
- RuleDoc customDoc = getRuleDoc(results, customRule.getRuleKey());
+ RuleDocWithSystemScope customDocWithSystemScope = getRuleDoc(results, customRule.getRuleKey());
+ RuleDoc customDoc = customDocWithSystemScope.getRuleDoc();
assertThat(customDoc.isTemplate()).isFalse();
assertThat(customDoc.templateKey()).isEqualTo(RuleKey.of("xoo", "S001"));
}
@Test
public void removed_rule_is_returned() {
- dbTester.rules().insertRule(templateRule.setStatus(RuleStatus.REMOVED));
+ dbTester.rules().insert(templateRule.setStatus(RuleStatus.REMOVED));
dbSession.commit();
- List<RuleDoc> results = getResults();
+ List<RuleDocWithSystemScope> results = getResults();
assertThat(results).hasSize(1);
}
- private List<RuleDoc> getResults() {
- return Lists.newArrayList(new RuleIteratorForSingleChunk(dbTester.getDbClient(), dbTester.getDefaultOrganization(), null));
+ private List<RuleDocWithSystemScope> getResults() {
+ return Lists.newArrayList(new RuleIteratorForSingleChunk(dbTester.getDbClient(), null));
}
- private RuleDoc getRuleDoc(List<RuleDoc> results, String ruleKey) {
- RuleDoc rule;
+ private RuleDocWithSystemScope getRuleDoc(List<RuleDocWithSystemScope> results, String ruleKey) {
+ RuleDocWithSystemScope rule;
rule = results.stream()
- .filter(r -> ruleKey.equals(r.key().rule()))
+ .filter(r -> ruleKey.equals(r.getRuleDoc().key().rule()))
.findAny()
.orElseThrow(() -> new NotFoundException("Rule not found in results"));
return rule;
@Test
public void return_rules_in_protobuf() throws Exception {
- dbTester.rules().insertRule(RuleTesting.newDto(RuleKey.of("java", "S001")).setConfigKey(null).setName(null));
- dbTester.rules().insertRule(RuleTesting.newDto(RuleKey.of("java", "S002")).setConfigKey("I002").setName("Rule Two"));
+ dbTester.rules().insert(RuleTesting.newRule(RuleKey.of("java", "S001")).setConfigKey(null).setName(null));
+ dbTester.rules().insert(RuleTesting.newRule(RuleKey.of("java", "S002")).setConfigKey("I002").setName("Rule Two"));
dbTester.getSession().commit();
TestResponse response = tester.newRequest()
*/
package org.sonar.server.rule.ws;
-import com.google.common.collect.ImmutableSet;
-import java.util.Collections;
-import java.util.stream.Stream;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.server.ws.WebService;
-import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
tester.get(ActiveRuleDao.class).insert(session, activeRuleDto);
session.commit();
- ruleIndexer.index(defaultOrganization, rule.getKey());
+ ruleIndexer.indexRuleDefinition(rule.getDefinition().getKey());
activeRuleIndexer.index();
// 1. With Activation
result = request.execute();
result.assertJson(this.getClass(), "show_rule_no_active.json");
}
-
- @Test
- public void get_tags() throws Exception {
- QualityProfileDto profile = QProfileTesting.newXooP1(defaultOrganization);
- tester.get(QualityProfileDao.class).insert(session, profile);
-
- RuleDto rule = RuleTesting.newXooX1(defaultOrganization)
- .setTags(ImmutableSet.of("hello", "world"))
- .setSystemTags(Collections.<String>emptySet());
- ruleDao.insert(session, rule.getDefinition());
- ruleDao.insertOrUpdate(session, rule.getMetadata().setRuleId(rule.getId()));
-
- RuleDto rule2 = RuleTesting.newXooX2(defaultOrganization)
- .setTags(ImmutableSet.of("hello", "java"))
- .setSystemTags(ImmutableSet.of("sys1"));
- ruleDao.insert(session, rule2.getDefinition());
- ruleDao.insertOrUpdate(session, rule2.getMetadata().setRuleId(rule2.getId()));
-
- session.commit();
- ruleIndexer.index(defaultOrganization, Stream.of(rule, rule2).map(RuleDto::getKey).collect(MoreCollectors.toList()));
-
- tester.wsTester().newGetRequest(API_ENDPOINT, API_TAGS_METHOD).execute().assertJson(this.getClass(), "get_tags.json");
- tester.wsTester().newGetRequest(API_ENDPOINT, API_TAGS_METHOD)
- .setParam("ps", "1").execute().assertJson(this.getClass(), "get_tags_limited.json");
- tester.wsTester().newGetRequest(API_ENDPOINT, API_TAGS_METHOD)
- .setParam("q", "ll").execute().assertJson(this.getClass(), "get_tags_filtered.json");
- }
-
}
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.rule.RuleKey;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsTester;
+import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
@Test
public void return_lang_key_field_when_language_name_is_not_available() throws Exception {
- insertRule(RuleTesting.newDto(RuleKey.of("other", "rule")).setLanguage("unknown").getDefinition());
+ insertRule(RuleTesting.newRule(RuleKey.of("other", "rule")).setLanguage("unknown"));
dbSession.commit();
WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD).setParam(WebService.Param.FIELDS, "langName");
result.assertJson(this.getClass(), "get_note_as_markdown_and_html.json");
}
+ @Ignore
@Test
public void filter_by_tags() throws Exception {
- insertRule(RuleTesting.newXooX1()
- .setSystemTags(ImmutableSet.of("tag1"))
- .getDefinition());
- insertRule(RuleTesting.newXooX2()
- .setSystemTags(ImmutableSet.of("tag2"))
- .getDefinition());
-
- dbSession.commit();
+ insertRule(RuleTesting.newRule()
+ .setSystemTags(ImmutableSet.of("tag1")));
+ insertRule(RuleTesting.newRule()
+ .setSystemTags(ImmutableSet.of("tag2")));
activeRuleIndexer.index();
private void insertRule(RuleDefinitionDto definition) {
ruleDao.insert(dbSession, definition);
dbSession.commit();
- ruleIndexer.index(defaultOrganizationDto, definition.getKey());
+ ruleIndexer.indexRuleDefinition(definition.getKey());
}
}
@Test
public void show_rule_with_no_default_and_no_overridden_debt() throws Exception {
- RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"))
+ RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("java", "S001"))
.setName("Rule S001")
.setDescription("Rule S001 <b>description</b>")
.setDescriptionFormat(Format.HTML)
.setDefRemediationFunction(null)
.setDefRemediationGapMultiplier(null)
.setDefRemediationBaseEffort(null);
- ruleDao.insert(session, ruleDto.getDefinition());
+ ruleDao.insert(session, ruleDto);
session.commit();
session.clearCache();
@Test
public void show_rule_when_activated() throws Exception {
- RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"))
+ RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("java", "S001"))
.setName("Rule S001")
.setDescription("Rule S001 <b>description</b>")
.setDescriptionFormat(Format.HTML)
.setType(RuleType.BUG)
.setCreatedAt(new Date().getTime())
.setUpdatedAt(new Date().getTime());
- RuleDefinitionDto definition = ruleDto.getDefinition();
- ruleDao.insert(session, definition);
+ ruleDao.insert(session, ruleDto);
session.commit();
- ruleIndexer.index(defaultOrganization, definition.getKey());
- RuleParamDto regexParam = RuleParamDto.createFor(definition).setName("regex").setType("STRING").setDescription("Reg *exp*").setDefaultValue(".*");
- ruleDao.insertRuleParam(session, definition, regexParam);
+ ruleIndexer.indexRuleDefinition(ruleDto.getKey());
+ RuleParamDto regexParam = RuleParamDto.createFor(ruleDto).setName("regex").setType("STRING").setDescription("Reg *exp*").setDefaultValue(".*");
+ ruleDao.insertRuleParam(session, ruleDto, regexParam);
QualityProfileDto profile = QualityProfileDto.createFor("profile")
.setOrganizationUuid(defaultOrganizationProvider.get().getUuid())
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.rule.ws;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.config.MapSettings;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.server.es.EsClient;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
+import org.sonar.server.rule.index.RuleIndex;
+import org.sonar.server.rule.index.RuleIndexDefinition;
+import org.sonar.server.rule.index.RuleIndexer;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.rule.RuleTesting.setSystemTags;
+import static org.sonar.db.rule.RuleTesting.setTags;
+import static org.sonar.test.JsonAssert.assertJson;
+
+public class TagsActionTest {
+
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ @Rule
+ public DbTester dbTester = DbTester.create();
+ @Rule
+ public EsTester esTester = new EsTester(new RuleIndexDefinition(new MapSettings()));
+
+ private DbClient dbClient = dbTester.getDbClient();
+ private EsClient esClient = esTester.client();
+ private RuleIndex ruleIndex = new RuleIndex(esClient);
+ private RuleIndexer ruleIndexer = new RuleIndexer(esClient, dbClient);
+
+ private WsActionTester tester = new WsActionTester(new org.sonar.server.rule.ws.TagsAction(ruleIndex, dbClient, TestDefaultOrganizationProvider.from(dbTester)));
+ private OrganizationDto organization;
+
+ @Before
+ public void before() {
+ organization = dbTester.organizations().insert();
+ }
+
+ @Test
+ public void test_definition() {
+ WebService.Action action = tester.getDef();
+ assertThat(action.description()).isNotEmpty();
+ assertThat(action.responseExampleAsString()).isNotEmpty();
+ assertThat(action.isPost()).isFalse();
+ assertThat(action.isInternal()).isFalse();
+ assertThat(action.params()).hasSize(3);
+
+ WebService.Param query = action.param("q");
+ assertThat(query).isNotNull();
+ assertThat(query.isRequired()).isFalse();
+ assertThat(query.description()).isNotEmpty();
+ assertThat(query.exampleValue()).isNotEmpty();
+
+ WebService.Param pageSize = action.param("ps");
+ assertThat(pageSize).isNotNull();
+ assertThat(pageSize.isRequired()).isFalse();
+ assertThat(pageSize.defaultValue()).isEqualTo("0");
+ assertThat(pageSize.description()).isNotEmpty();
+ assertThat(pageSize.exampleValue()).isNotEmpty();
+
+ WebService.Param organization = action.param("organization");
+ assertThat(organization).isNotNull();
+ assertThat(organization.isRequired()).isFalse();
+ assertThat(organization.isInternal()).isTrue();
+ assertThat(organization.description()).isNotEmpty();
+ assertThat(organization.exampleValue()).isNotEmpty();
+ assertThat(organization.since()).isEqualTo("6.4");
+ }
+
+ @Test
+ public void return_system_tag() throws Exception {
+ RuleDefinitionDto r = dbTester.rules().insert(setSystemTags("tag"));
+ ruleIndexer.indexRuleDefinition(r.getKey());
+
+ String result = tester.newRequest().execute().getInput();
+ assertJson(result).isSimilarTo("{\"tags\":[\"tag\"]}");
+ }
+
+ @Test
+ public void return_tag() throws Exception {
+ RuleDefinitionDto r = dbTester.rules().insert(setSystemTags());
+ ruleIndexer.indexRuleDefinition(r.getKey());
+ dbTester.rules().insertOrUpdateMetadata(r, organization, setTags("tag"));
+ ruleIndexer.indexRuleExtension(organization, r.getKey());
+
+ String result = tester.newRequest().setParam("organization", organization.getKey()).execute().getInput();
+ assertJson(result).isSimilarTo("{\"tags\":[\"tag\"]}");
+ }
+}
@Test
public void clear_views_lookup_cache_on_index_view_uuid() {
- IssueIndex issueIndex = new IssueIndex(esTester.client(), System2.INSTANCE, userSessionRule, new AuthorizationTypeSupport(userSessionRule));
+ IssueIndex issueIndex = new IssueIndex(esTester.client(), System2.INSTANCE, userSessionRule, new AuthorizationTypeSupport(userSessionRule)
+ );
IssueIndexer issueIndexer = new IssueIndexer(esTester.client(), new IssueIteratorFactory(dbClient));
String viewUuid = "ABCD";
+++ /dev/null
-{
- "tags": [
- "sys1",
- "java",
- "world",
- "hello"
- ]
-}