private Optional<RuleDefinitionDto> getDbRuleFor(RulesDefinition.Rule ruleDef) { RuleKey ruleKey = RuleKey.of(ruleDef.repository().key(), ruleDef.key()); Optional<RuleDefinitionDto> res = Stream.concat(Stream.of(ruleKey), ruleDef.deprecatedRuleKeys().stream()) .map(dbRules::get) .filter(Objects::nonNull) .findFirst(); // may occur in case of plugin downgrade if (!res.isPresent()) { return Optional.ofNullable(dbRulesByDbDeprecatedKey.get(ruleKey)); } return res; }
private static void verifyRuleKeyConsistency(List<RulesDefinition.ExtendedRepository> repositories, RegisterRulesContext registerRulesContext) { List<RulesDefinition.Rule> definedRules = repositories.stream() .flatMap(r -> r.rules().stream()) .collect(toList()); Set<RuleKey> definedRuleKeys = definedRules.stream() .map(r -> RuleKey.of(r.repository().key(), r.key())) .collect(toSet()); List<RuleKey> definedDeprecatedRuleKeys = definedRules.stream() .flatMap(r -> r.deprecatedRuleKeys().stream()) .collect(toList()); // Find duplicates in declared deprecated rule keys Set<RuleKey> duplicates = findDuplicates(definedDeprecatedRuleKeys); checkState(duplicates.isEmpty(), "The following deprecated rule keys are declared at least twice [%s]", lazyToString(() -> duplicates.stream().map(RuleKey::toString).collect(Collectors.joining(",")))); // Find rule keys that are both deprecated and used Set<RuleKey> intersection = intersection(new HashSet<>(definedRuleKeys), new HashSet<>(definedDeprecatedRuleKeys)).immutableCopy(); checkState(intersection.isEmpty(), "The following rule keys are declared both as deprecated and used key [%s]", lazyToString(() -> intersection.stream().map(RuleKey::toString).collect(Collectors.joining(",")))); // Find incorrect usage of deprecated keys ImmutableMap<RuleKey, SingleDeprecatedRuleKey> dbDeprecatedRuleKeysByOldRuleKey = registerRulesContext.getDbDeprecatedKeysByOldRuleKey(); Set<String> incorrectRuleKeyMessage = definedRules.stream() .flatMap(r -> filterInvalidDeprecatedRuleKeys(dbDeprecatedRuleKeysByOldRuleKey, r)) .filter(Objects::nonNull) .collect(Collectors.toSet()); checkState(incorrectRuleKeyMessage.isEmpty(), "An incorrect state of deprecated rule keys has been detected.\n %s", lazyToString(() -> incorrectRuleKeyMessage.stream().collect(Collectors.joining("\n")))); }
private void persistRepositories(DbSession dbSession, List<RulesDefinition.Repository> repositories) { List<RuleRepositoryDto> dtos = repositories .stream() .map(r -> new RuleRepositoryDto(r.key(), r.language(), r.name())) .collect(toList(repositories.size())); List<String> keys = dtos.stream().map(RuleRepositoryDto::getKey).collect(toList(repositories.size())); dbClient.ruleRepositoryDao().insertOrUpdate(dbSession, dtos); dbClient.ruleRepositoryDao().deleteIfKeyNotIn(dbSession, keys); dbSession.commit(); }
private RepositoryImpl(NewRepositoryImpl newRepository, @Nullable Repository mergeInto) { this.key = newRepository.key; this.language = newRepository.language; this.isExternal = newRepository.isExternal; Map<String, Rule> ruleBuilder = new HashMap<>(); if (mergeInto != null) { if (!StringUtils.equals(newRepository.language, mergeInto.language()) || !StringUtils.equals(newRepository.key, mergeInto.key())) { throw new IllegalArgumentException(format("Bug - language and key of the repositories to be merged should be the sames: %s and %s", newRepository, mergeInto)); } this.name = StringUtils.defaultIfBlank(mergeInto.name(), newRepository.name); for (Rule rule : mergeInto.rules()) { if (!newRepository.key().startsWith("common-") && ruleBuilder.containsKey(rule.key())) { Loggers.get(getClass()).warn("The rule '{}' of repository '{}' is declared several times", rule.key(), mergeInto.key()); } ruleBuilder.put(rule.key(), rule); } } else { this.name = newRepository.name; } for (NewRule newRule : newRepository.newRules.values()) { newRule.validate(); ruleBuilder.put(newRule.key, new Rule(this, newRule)); } this.rulesByKey = unmodifiableMap(ruleBuilder); }
private static boolean noTemplateRuleWithOrganizationsEnabled(RegisterRulesContext registerRulesContext, boolean orgsEnabled, RulesDefinition.Rule ruleDef) { if (!ruleDef.template() || !orgsEnabled) { return false; } Optional<RuleDefinitionDto> dbRule = registerRulesContext.getDbRuleFor(ruleDef); if (dbRule.isPresent() && dbRule.get().getStatus() == RuleStatus.REMOVED) { RuleDefinitionDto dto = dbRule.get(); LOG.debug("Template rule {} kept removed, because organizations are enabled.", dto.getKey()); registerRulesContext.removed(dto); } else { LOG.info("Template rule {} will not be imported, because organizations are enabled.", RuleKey.of(ruleDef.repository().key(), ruleDef.key())); } return true; }
private static Rule toRuleNotNull(RulesDefinition.Rule ruleDef) { Rule rule = Rule.create(ruleDef.repository().key(), ruleDef.key()) .setName(ruleDef.name()) .setSeverity(RulePriority.valueOf(ruleDef.severity())) .setLanguage(ruleDef.repository().language()) .setIsTemplate(ruleDef.template()) .setConfigKey(ruleDef.internalKey()); for (Param param : ruleDef.params()) { rule.createParameter(param.key()).setDefaultValue(param.defaultValue()).setDescription(param.description()); } return rule; }
private void persistRepositories(DbSession dbSession, List<RulesDefinition.Repository> repositories) { List<RuleRepositoryDto> dtos = repositories .stream() .map(r -> new RuleRepositoryDto(r.key(), r.language(), r.name())) .collect(toList(repositories.size())); List<String> keys = dtos.stream().map(RuleRepositoryDto::getKey).collect(toList(repositories.size())); dbClient.ruleRepositoryDao().insertOrUpdate(dbSession, dtos); dbClient.ruleRepositoryDao().deleteIfKeyNotIn(dbSession, keys); dbSession.commit(); }
public static Set<SingleDeprecatedRuleKey> from(RulesDefinition.Rule rule) { return rule.deprecatedRuleKeys().stream() .map(r -> new SingleDeprecatedRuleKey() .setNewRepositoryKey(rule.repository().key()) .setNewRuleKey(rule.key()) .setOldRepositoryKey(r.repository()) .setOldRuleKey(r.rule())) .collect(MoreCollectors.toSet(rule.deprecatedRuleKeys().size())); }
private Optional<RuleDefinitionDto> getDbRuleFor(RulesDefinition.Rule ruleDef) { RuleKey ruleKey = RuleKey.of(ruleDef.repository().key(), ruleDef.key()); Optional<RuleDefinitionDto> res = Stream.concat(Stream.of(ruleKey), ruleDef.deprecatedRuleKeys().stream()) .map(dbRules::get) .filter(Objects::nonNull) .findFirst(); // may occur in case of plugin downgrade if (!res.isPresent()) { return Optional.ofNullable(dbRulesByDbDeprecatedKey.get(ruleKey)); } return res; }
private RuleDefinitionDto createRuleDto(RulesDefinition.Rule ruleDef, DbSession session) { RuleDefinitionDto ruleDto = new RuleDefinitionDto() .setRuleKey(RuleKey.of(ruleDef.repository().key(), ruleDef.key())) .setPluginKey(ruleDef.pluginKey()) .setIsTemplate(ruleDef.template())
private void registerRule(RegisterRulesContext context, RulesDefinition.Rule ruleDef, DbSession session) { RuleKey ruleKey = RuleKey.of(ruleDef.repository().key(), ruleDef.key());
RulesDefinition.Repository checkstyle = context.repository("checkstyle"); assertThat(checkstyle).isNotNull(); assertThat(checkstyle.key()).isEqualTo("checkstyle"); assertThat(checkstyle.name()).isEqualTo("Checkstyle"); assertThat(checkstyle.language()).isEqualTo("java");
private static Stream<String> filterInvalidDeprecatedRuleKeys(ImmutableMap<RuleKey, SingleDeprecatedRuleKey> dbDeprecatedRuleKeysByOldRuleKey, RulesDefinition.Rule rule) { return rule.deprecatedRuleKeys().stream() .map(rk -> { SingleDeprecatedRuleKey singleDeprecatedRuleKey = dbDeprecatedRuleKeysByOldRuleKey.get(rk); if (singleDeprecatedRuleKey == null) { // new deprecated rule key : OK return null; } RuleKey parentRuleKey = RuleKey.of(rule.repository().key(), rule.key()); if (parentRuleKey.equals(singleDeprecatedRuleKey.getNewRuleKeyAsRuleKey())) { // same parent : OK return null; } if (rule.deprecatedRuleKeys().contains(parentRuleKey)) { // the new rule is deprecating the old parentRuleKey : OK return null; } return format("The deprecated rule key [%s] was previously deprecated by [%s]. [%s] should be a deprecated key of [%s],", rk.toString(), singleDeprecatedRuleKey.getNewRuleKeyAsRuleKey().toString(), singleDeprecatedRuleKey.getNewRuleKeyAsRuleKey().toString(), RuleKey.of(rule.repository().key(), rule.key()).toString()); }); }
@Test public void define_repositories() { assertThat(context.repositories()).isEmpty(); context.createRepository("findbugs", "java").setName("Findbugs").done(); context.createRepository("checkstyle", "java").done(); assertThat(context.repositories()).hasSize(2); RulesDefinition.Repository findbugs = context.repository("findbugs"); assertThat(findbugs).isNotNull(); assertThat(findbugs.key()).isEqualTo("findbugs"); assertThat(findbugs.language()).isEqualTo("java"); assertThat(findbugs.name()).isEqualTo("Findbugs"); assertThat(findbugs.rules()).isEmpty(); RulesDefinition.Repository checkstyle = context.repository("checkstyle"); assertThat(checkstyle).isNotNull(); assertThat(checkstyle.key()).isEqualTo("checkstyle"); assertThat(checkstyle.language()).isEqualTo("java"); // default name is key assertThat(checkstyle.name()).isEqualTo("checkstyle"); assertThat(checkstyle.rules()).isEmpty(); assertThat(context.repository("unknown")).isNull(); // test equals() and hashCode() assertThat(findbugs).isEqualTo(findbugs).isNotEqualTo(checkstyle).isNotEqualTo("findbugs").isNotEqualTo(null); assertThat(findbugs.hashCode()).isEqualTo(findbugs.hashCode()); }
@Test public void test_creation_from_RulesDefinitionRule() { // Creation from RulesDefinition.Rule ImmutableSet<RuleKey> deprecatedRuleKeys = ImmutableSet.of( RuleKey.of(randomAlphanumeric(50), randomAlphanumeric(50)), RuleKey.of(randomAlphanumeric(50), randomAlphanumeric(50)), RuleKey.of(randomAlphanumeric(50), randomAlphanumeric(50)) ); RulesDefinition.Repository repository = mock(RulesDefinition.Repository.class); when(repository.key()).thenReturn(randomAlphanumeric(50)); RulesDefinition.Rule rule = mock(RulesDefinition.Rule.class); when(rule.key()).thenReturn(randomAlphanumeric(50)); when(rule.deprecatedRuleKeys()).thenReturn(deprecatedRuleKeys); when(rule.repository()).thenReturn(repository); Set<SingleDeprecatedRuleKey> singleDeprecatedRuleKeys = SingleDeprecatedRuleKey.from(rule); assertThat(singleDeprecatedRuleKeys).hasSize(deprecatedRuleKeys.size()); assertThat(singleDeprecatedRuleKeys) .extracting(SingleDeprecatedRuleKey::getUuid, SingleDeprecatedRuleKey::getOldRepositoryKey, SingleDeprecatedRuleKey::getOldRuleKey, SingleDeprecatedRuleKey::getNewRepositoryKey, SingleDeprecatedRuleKey::getNewRuleKey, SingleDeprecatedRuleKey::getOldRuleKeyAsRuleKey) .containsExactlyInAnyOrder( deprecatedRuleKeys.stream().map( r -> tuple(null, r.repository(), r.rule(), rule.repository().key(), rule.key(), RuleKey.of(r.repository(), r.rule())) ).collect(MoreCollectors.toArrayList(deprecatedRuleKeys.size())).toArray(new Tuple[deprecatedRuleKeys.size()]) ); }
private RepositoryImpl(NewRepositoryImpl newRepository, @Nullable Repository mergeInto) { this.key = newRepository.key; this.language = newRepository.language; this.isExternal = newRepository.isExternal; Map<String, Rule> ruleBuilder = new HashMap<>(); if (mergeInto != null) { if (!StringUtils.equals(newRepository.language, mergeInto.language()) || !StringUtils.equals(newRepository.key, mergeInto.key())) { throw new IllegalArgumentException(format("Bug - language and key of the repositories to be merged should be the sames: %s and %s", newRepository, mergeInto)); } this.name = StringUtils.defaultIfBlank(mergeInto.name(), newRepository.name); for (Rule rule : mergeInto.rules()) { if (!newRepository.key().startsWith("common-") && ruleBuilder.containsKey(rule.key())) { Loggers.get(getClass()).warn("The rule '{}' of repository '{}' is declared several times", rule.key(), mergeInto.key()); } ruleBuilder.put(rule.key(), rule); } } else { this.name = newRepository.name; } for (NewRule newRule : newRepository.newRules.values()) { newRule.validate(); ruleBuilder.put(newRule.key, new Rule(this, newRule)); } this.rulesByKey = unmodifiableMap(ruleBuilder); }
@Test public void add_rules_to_existing_repository() { RulesDefinition.NewRepository newFindbugs = context.createRepository("findbugs", "java").setName("Findbugs"); newFindbugs.createRule("NPE").setName("NPE").setHtmlDescription("NPE"); newFindbugs.done(); RulesDefinition.NewRepository newFbContrib = context.createRepository("findbugs", "java"); newFbContrib.createRule("VULNERABILITY").setName("Vulnerability").setMarkdownDescription("Detect vulnerability"); newFbContrib.done(); assertThat(context.repositories()).hasSize(1); RulesDefinition.Repository findbugs = context.repository("findbugs"); assertThat(findbugs.key()).isEqualTo("findbugs"); assertThat(findbugs.language()).isEqualTo("java"); assertThat(findbugs.name()).isEqualTo("Findbugs"); assertThat(findbugs.rules()).extracting("key").containsOnly("NPE", "VULNERABILITY"); }
private static boolean noTemplateRuleWithOrganizationsEnabled(RegisterRulesContext registerRulesContext, boolean orgsEnabled, RulesDefinition.Rule ruleDef) { if (!ruleDef.template() || !orgsEnabled) { return false; } Optional<RuleDefinitionDto> dbRule = registerRulesContext.getDbRuleFor(ruleDef); if (dbRule.isPresent() && dbRule.get().getStatus() == RuleStatus.REMOVED) { RuleDefinitionDto dto = dbRule.get(); LOG.debug("Template rule {} kept removed, because organizations are enabled.", dto.getKey()); registerRulesContext.removed(dto); } else { LOG.info("Template rule {} will not be imported, because organizations are enabled.", RuleKey.of(ruleDef.repository().key(), ruleDef.key())); } return true; }
public static Set<SingleDeprecatedRuleKey> from(RulesDefinition.Rule rule) { return rule.deprecatedRuleKeys().stream() .map(r -> new SingleDeprecatedRuleKey() .setNewRepositoryKey(rule.repository().key()) .setNewRuleKey(rule.key()) .setOldRepositoryKey(r.repository()) .setOldRuleKey(r.rule())) .collect(MoreCollectors.toSet(rule.deprecatedRuleKeys().size())); }
public ScannerMediumTester addRules(RulesDefinition rulesDefinition) { RulesDefinition.Context context = new RulesDefinition.Context(); rulesDefinition.define(context); List<Repository> repositories = context.repositories(); for (Repository repo : repositories) { for (RulesDefinition.Rule rule : repo.rules()) { this.addRule(rule.key(), rule.repository().key(), rule.internalKey(), rule.name()); } } return this; }