package org.sonar.db.rule;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleQuery;
import org.sonar.core.util.UuidFactory;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Collections.emptyList;
+import static java.util.stream.Collectors.toMap;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
import static org.sonar.db.DatabaseUtils.executeLargeInputsWithoutOutput;
import static org.sonar.db.DatabaseUtils.executeLargeUpdates;
.forEach(consumer));
}
- public void scrollIndexingRulesByKeys(DbSession dbSession, Collection<String> ruleUuids, Consumer<RuleForIndexingDto> consumer) {
+ public void selectIndexingRulesByKeys(DbSession dbSession, Collection<String> ruleUuids, Consumer<RuleForIndexingDto> consumer) {
RuleMapper mapper = mapper(dbSession);
executeLargeInputsWithoutOutput(ruleUuids,
- pageOfRuleUuids -> mapper
- .selectIndexingRulesByUuids(pageOfRuleUuids)
- .forEach(consumer));
+ pageOfRuleUuids -> {
+ List<RuleDto> ruleDtos = mapper.selectByUuids(pageOfRuleUuids);
+ processRuleDtos(ruleDtos, consumer, mapper);
+ });
+ }
+
+ public void selectIndexingRules(DbSession dbSession, Consumer<RuleForIndexingDto> consumer) {
+ RuleMapper mapper = mapper(dbSession);
+ executeLargeInputsWithoutOutput(mapper.selectAll(),
+ ruleDtos -> processRuleDtos(ruleDtos, consumer, mapper));
}
- public void scrollIndexingRules(DbSession dbSession, Consumer<RuleForIndexingDto> consumer) {
- mapper(dbSession).scrollIndexingRules(context -> {
- RuleForIndexingDto dto = context.getResultObject();
- consumer.accept(dto);
- });
+ private static RuleForIndexingDto toRuleForIndexingDto(RuleDto r, Map<String, RuleDto> templateDtos) {
+ RuleForIndexingDto ruleForIndexingDto = RuleForIndexingDto.fromRuleDto(r);
+ if (templateDtos.containsKey(r.getTemplateUuid())) {
+ ruleForIndexingDto.setTemplateRuleKey(templateDtos.get(r.getTemplateUuid()).getRuleKey());
+ ruleForIndexingDto.setTemplateRepository(templateDtos.get(r.getTemplateUuid()).getRepositoryKey());
+ }
+ return ruleForIndexingDto;
+ }
+
+ private static void processRuleDtos(List<RuleDto> ruleDtos, Consumer<RuleForIndexingDto> consumer, RuleMapper mapper) {
+ List<String> templateRuleUuids = ruleDtos.stream()
+ .map(RuleDto::getTemplateUuid)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ Map<String, RuleDto> templateDtos = findTemplateDtos(mapper, templateRuleUuids);
+ ruleDtos.stream().map(r -> toRuleForIndexingDto(r, templateDtos)).forEach(consumer);
+ }
+
+ private static Map<String, RuleDto> findTemplateDtos(RuleMapper mapper, List<String> templateRuleUuids) {
+ if (!templateRuleUuids.isEmpty()) {
+ return mapper.selectByUuids(templateRuleUuids).stream().collect(toMap(RuleDto::getUuid, Function.identity()));
+ }else{
+ return Collections.emptyMap();
+ }
}
private static RuleMapper mapper(DbSession session) {
*/
package org.sonar.db.rule;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Sets;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
private Integer severity;
private RuleStatus status;
private boolean isTemplate;
- private String systemTags;
- private String tags;
- private String securityStandards;
+ private Set<String> systemTags;
+ private Set<String> tags;
+ private Set<String> securityStandards;
private String templateRuleKey;
private String templateRepository;
private String internalKey;
private Set<RuleDescriptionSectionDto> ruleDescriptionSectionsDtos = new HashSet<>();
+ @VisibleForTesting
public RuleForIndexingDto() {
// nothing to do here
}
+ public static RuleForIndexingDto fromRuleDto(RuleDto r) {
+ RuleForIndexingDto ruleForIndexingDto = new RuleForIndexingDto();
+ ruleForIndexingDto.createdAt = r.getCreatedAt();
+ ruleForIndexingDto.uuid = r.getUuid();
+ ruleForIndexingDto.repository = r.getRepositoryKey();
+ ruleForIndexingDto.pluginRuleKey = r.getRuleKey();
+ ruleForIndexingDto.name = r.getName();
+ ruleForIndexingDto.descriptionFormat = r.getDescriptionFormat();
+ ruleForIndexingDto.severity = r.getSeverity();
+ ruleForIndexingDto.status = r.getStatus();
+ ruleForIndexingDto.isTemplate = r.isTemplate();
+ ruleForIndexingDto.systemTags = Sets.newHashSet(r.getSystemTags());
+ ruleForIndexingDto.tags = r.getMetadata() != null ? Sets.newHashSet(r.getMetadata().getTags()) : Collections.emptySet();
+ ruleForIndexingDto.securityStandards = Sets.newHashSet(r.getSecurityStandards());
+ ruleForIndexingDto.internalKey = r.getConfigKey();
+ ruleForIndexingDto.language = r.getLanguage();
+ ruleForIndexingDto.isExternal = r.isExternal();
+ ruleForIndexingDto.type = r.getType();
+ ruleForIndexingDto.createdAt = r.getCreatedAt();
+ ruleForIndexingDto.updatedAt = r.getUpdatedAt();
+ if (r.getRuleDescriptionSectionDtos() != null) {
+ ruleForIndexingDto.setRuleDescriptionSectionsDtos(Sets.newHashSet(r.getRuleDescriptionSectionDtos()));
+ }
+ return ruleForIndexingDto;
+ }
+
public String getUuid() {
return uuid;
}
}
public Set<String> getSystemTags() {
- return RuleDefinitionDto.deserializeTagsString(systemTags);
+ return Collections.unmodifiableSet(systemTags);
}
public Set<String> getTags() {
- return RuleDefinitionDto.deserializeTagsString(tags);
+ return Collections.unmodifiableSet(tags);
}
public Set<String> getSecurityStandards() {
- return RuleDefinitionDto.deserializeSecurityStandardsString(securityStandards);
+ return Collections.unmodifiableSet(securityStandards);
}
public String getTemplateRuleKey() {
}
public Set<RuleDescriptionSectionDto> getRuleDescriptionSectionsDtos() {
- return ruleDescriptionSectionsDtos;
+ return Collections.unmodifiableSet(ruleDescriptionSectionsDtos);
}
public void setRuleDescriptionSectionsDtos(Set<RuleDescriptionSectionDto> ruleDescriptionSectionsDtos) {
public RuleDescriptionSectionDto getDefaultRuleDescriptionSectionDto() {
return findExistingSectionWithSameKey(DEFAULT_KEY).orElse(null);
}
+
+ public void setTemplateRuleKey(String templateRuleKey) {
+ this.templateRuleKey = templateRuleKey;
+ }
+
+ public void setTemplateRepository(String templateRepository) {
+ this.templateRepository = templateRepository;
+ }
}
</resultMap>
- <resultMap id="ruleForIndexingDtoResultMap" type="org.sonar.db.rule.RuleForIndexingDto">
- <result property="uuid" column="uuid"/>
- <result property="repository" column="repository"/>
- <result property="pluginRuleKey" column="pluginRuleKey"/>
- <result property="name" column="name"/>
- <result property="descriptionFormat" column="descriptionFormat"/>
- <result property="severity" column="severity"/>
- <result property="status" column="status"/>
- <result property="isTemplate" column="isTemplate"/>
- <result property="isExternal" column="isExternal"/>
- <result property="systemTags" column="systemTags"/>
- <result property="securityStandards" column="securityStandards"/>
- <result property="templateRuleKey" column="templateRuleKey"/>
- <result property="templateRepository" column="templateRepository"/>
- <result property="internalKey" column="internalKey"/>
- <result property="language" column="language"/>
- <result property="type" column="type"/>
- <result property="createdAt" column="createdAt"/>
- <result property="updatedAt" column="updatedAt"/>
- <result property="tags" column="tags"/>
- <collection property="ruleDescriptionSectionsDtos" ofType="org.sonar.db.rule.RuleDescriptionSectionDto">
- <id property="uuid" column="rds_uuid"/>
- <result property="key" column="rds_kee"/>
- <result property="description" column="rds_description"/>
- </collection>
- </resultMap>
-
<select id="selectAllDefinitions" resultMap="ruleDefinitionResultMap">
select
<include refid="selectRuleTableColumns"/>
</foreach>
</select>
- <select id="selectIndexingRulesByUuids" parameterType="map" resultMap="ruleForIndexingDtoResultMap">
- <include refid="sqlSelectIndexingRules"/>
- where
- <foreach collection="ruleUuids" index="index" item="ruleUuid" open="" separator=" or " close="">
- r.uuid=#{ruleUuid,jdbcType=VARCHAR}
- </foreach>
- order by r.created_at asc
- </select>
-
- <select id="scrollIndexingRules" resultMap="ruleForIndexingDtoResultMap" fetchSize="${_scrollFetchSize}"
- resultSetType="FORWARD_ONLY" resultOrdered="true">
- <include refid="sqlSelectIndexingRules"/>
- order by r.created_at,r.uuid asc
- </select>
-
- <sql id="sqlSelectIndexingRules">
- select
- r.uuid as "uuid",
- r.plugin_name as "repository",
- r.plugin_rule_key as "pluginRuleKey",
- r.name as "name",
- r.description_format as "descriptionFormat",
- r.priority as "severity",
- r.status as "status",
- r.is_template as "isTemplate",
- r.is_external as "isExternal",
- r.system_tags as "systemTags",
- r.security_standards as "securityStandards",
- t.plugin_rule_key as "templateRuleKey",
- t.plugin_name as "templateRepository",
- r.plugin_config_key as "internalKey",
- r.language as "language",
- r.rule_type as "type",
- r.created_at as "createdAt",
- r.updated_at as "updatedAt",
- rm.tags as "tags",
- rds.uuid as "rds_uuid",
- rds.kee as "rds_kee",
- rds.description as "rds_description"
- from rules r
- left outer join rules t on t.uuid = r.template_uuid
- left outer join rules_metadata rm on r.uuid = rm.rule_uuid
- left outer join rule_desc_sections rds on
- rds.rule_uuid = r.uuid
- </sql>
-
<select id="selectByQuery" parameterType="map" resultMap="ruleResultMap">
select
<include refid="selectJoinedTablesColumns"/>
public void scrollIndexingRules_on_empty_table() {
Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
- underTest.scrollIndexingRules(db.getSession(), accumulator);
+ underTest.selectIndexingRules(db.getSession(), accumulator);
assertThat(accumulator.list).isEmpty();
}
});
RuleDefinitionDto r2 = db.rules().insert(r -> r.setIsExternal(true));
- underTest.scrollIndexingRules(db.getSession(), accumulator);
+ underTest.selectIndexingRules(db.getSession(), accumulator);
assertThat(accumulator.list)
.extracting(RuleForIndexingDto::getUuid, RuleForIndexingDto::getRuleKey)
public void scrollIndexingRules_maps_rule_definition_fields_for_regular_rule_and_template_rule() {
Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
RuleDefinitionDto r1 = db.rules().insert();
+ RuleMetadataDto r1Metadatas = db.rules().insertOrUpdateMetadata(r1, r -> r.setTagsField("t1,t2"));
RuleDefinitionDto r2 = db.rules().insert(rule -> rule.setTemplateUuid(r1.getUuid()));
- underTest.scrollIndexingRules(db.getSession(), accumulator);
+ underTest.selectIndexingRules(db.getSession(), accumulator);
assertThat(accumulator.list).hasSize(2);
RuleForIndexingDto firstRule = accumulator.list.get(0);
RuleForIndexingDto secondRule = accumulator.list.get(1);
assertRuleDefinitionFieldsAreEquals(r1, firstRule);
+ assertRuleMetadataFieldsAreEquals(r1Metadatas, firstRule);
assertThat(firstRule.getTemplateRuleKey()).isNull();
assertThat(firstRule.getTemplateRepository()).isNull();
assertRuleDefinitionFieldsAreEquals(r2, secondRule);
assertThat(secondRule.getTemplateRepository()).isEqualTo(r1.getRepositoryKey());
}
+
@Test
public void scrollIndexingRulesByKeys() {
Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
RuleDefinitionDto r1 = db.rules().insert();
db.rules().insert();
- underTest.scrollIndexingRulesByKeys(db.getSession(), singletonList(r1.getUuid()), accumulator);
+ underTest.selectIndexingRulesByKeys(db.getSession(), singletonList(r1.getUuid()), accumulator);
assertThat(accumulator.list)
.extracting(RuleForIndexingDto::getUuid, RuleForIndexingDto::getRuleKey)
RuleDefinitionDto r1 = db.rules().insert();
RuleDefinitionDto r2 = db.rules().insert(rule -> rule.setTemplateUuid(r1.getUuid()));
- underTest.scrollIndexingRulesByKeys(db.getSession(), Arrays.asList(r1.getUuid(), r2.getUuid()), accumulator);
+ underTest.selectIndexingRulesByKeys(db.getSession(), Arrays.asList(r1.getUuid(), r2.getUuid()), accumulator);
assertThat(accumulator.list).hasSize(2);
RuleForIndexingDto firstRule = accumulator.list.stream().filter(t -> t.getUuid().equals(r1.getUuid())).findFirst().get();
assertThat(firstRule.getUpdatedAt()).isEqualTo(r1.getUpdatedAt());
}
+ private static void assertRuleMetadataFieldsAreEquals(RuleMetadataDto r1Metadatas, RuleForIndexingDto firstRule) {
+ assertThat(r1Metadatas.getTags()).isEqualTo(firstRule.getTags());
+ }
+
@Test
public void scrollIndexingRulesByKeys_scrolls_nothing_if_key_does_not_exist() {
Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
db.rules().insert();
String nonExistingRuleUuid = "non-existing-uuid";
- underTest.scrollIndexingRulesByKeys(db.getSession(), singletonList(nonExistingRuleUuid), accumulator);
+ underTest.selectIndexingRulesByKeys(db.getSession(), singletonList(nonExistingRuleUuid), accumulator);
assertThat(accumulator.list).isEmpty();
}
try (DbSession dbSession = dbClient.openSession(false)) {
BulkIndexer bulk = createBulkIndexer(bulkSize, IndexingListener.FAIL_ON_ERROR);
bulk.start();
- dbClient.ruleDao().scrollIndexingRules(dbSession, dto -> bulk.add(ruleDocOf(dto).toIndexRequest()));
+ dbClient.ruleDao().selectIndexingRules(dbSession, dto -> bulk.add(ruleDocOf(dto).toIndexRequest()));
bulk.stop();
}
}
.map(EsQueueDto::getDocId)
.collect(toHashSet(items.size()));
- dbClient.ruleDao().scrollIndexingRulesByKeys(dbSession, ruleUuids,
+ dbClient.ruleDao().selectIndexingRulesByKeys(dbSession, ruleUuids,
r -> {
bulkIndexer.add(ruleDocOf(r).toIndexRequest());
ruleUuids.remove(r.getUuid());