Skip to content

Commit

Permalink
SONAR-6680 RuleRepository now load all rules at first call
Browse files Browse the repository at this point in the history
RuleRepository now implements a stonger contract (which is documented)
method hasKey(RuleKey) is replaced by method findByKey(RuleKey) which returns an Optional (saves using two methods in a row when Rule exists)
methods getById(int) and findById(int) added to be able to replace Views' specific RuleRepository with the one from the Compute Engine
  • Loading branch information
sns-seb committed Oct 20, 2015
1 parent 7b7e956 commit a9d76b1
Show file tree
Hide file tree
Showing 11 changed files with 325 additions and 181 deletions.
Expand Up @@ -48,7 +48,6 @@
import org.sonar.server.computation.issue.LoadComponentUuidsHavingOpenIssuesVisitor; import org.sonar.server.computation.issue.LoadComponentUuidsHavingOpenIssuesVisitor;
import org.sonar.server.computation.issue.NewDebtAggregator; import org.sonar.server.computation.issue.NewDebtAggregator;
import org.sonar.server.computation.issue.NewDebtCalculator; import org.sonar.server.computation.issue.NewDebtCalculator;
import org.sonar.server.computation.issue.RuleCacheLoader;
import org.sonar.server.computation.issue.RuleRepositoryImpl; import org.sonar.server.computation.issue.RuleRepositoryImpl;
import org.sonar.server.computation.issue.RuleTagsCopier; import org.sonar.server.computation.issue.RuleTagsCopier;
import org.sonar.server.computation.issue.ScmAccountToUser; import org.sonar.server.computation.issue.ScmAccountToUser;
Expand Down Expand Up @@ -140,7 +139,6 @@ private static List componentClasses() {
ScmInfoRepositoryImpl.class, ScmInfoRepositoryImpl.class,


// issues // issues
RuleCacheLoader.class,
RuleRepositoryImpl.class, RuleRepositoryImpl.class,
ScmAccountToUserLoader.class, ScmAccountToUserLoader.class,
ScmAccountToUser.class, ScmAccountToUser.class,
Expand Down

This file was deleted.

Expand Up @@ -19,11 +19,29 @@
*/ */
package org.sonar.server.computation.issue; package org.sonar.server.computation.issue;


import com.google.common.base.Optional;
import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleKey;


/**
* Repository of every rule in DB (including manual rules) whichever their status.
*/
public interface RuleRepository { public interface RuleRepository {


/**
* @throws NullPointerException if {@code key} is {@code null}
* @throws IllegalArgumentException when there is no Rule for the specified RuleKey in the repository
*/
Rule getByKey(RuleKey key); Rule getByKey(RuleKey key);


boolean hasKey(RuleKey key); /**
* @throws IllegalArgumentException when there is no Rule for the specified RuleKey in the repository
*/
Rule getById(int id);

/**
* @throws NullPointerException if {@code key} is {@code null}
*/
Optional<Rule> findByKey(RuleKey key);

Optional<Rule> findById(int id);
} }
Expand Up @@ -19,24 +19,92 @@
*/ */
package org.sonar.server.computation.issue; package org.sonar.server.computation.issue;


import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javax.annotation.CheckForNull;
import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleKey;
import org.sonar.server.util.cache.MemoryCache; import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.rule.RuleDto;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;


public class RuleRepositoryImpl implements RuleRepository { public class RuleRepositoryImpl implements RuleRepository {


private final MemoryCache<RuleKey, Rule> cache; @CheckForNull
private Map<RuleKey, Rule> rulesByKey;
@CheckForNull
private Map<Integer, Rule> rulesById;

private final DbClient dbClient;


public RuleRepositoryImpl(RuleCacheLoader cacheLoader) { public RuleRepositoryImpl(DbClient dbClient) {
this.cache = new MemoryCache<>(cacheLoader); this.dbClient = dbClient;
} }


@Override @Override
public Rule getByKey(RuleKey key) { public Rule getByKey(RuleKey key) {
return cache.get(key); verifyKeyArgument(key);

ensureInitialized();

Rule rule = rulesByKey.get(key);
checkArgument(rule != null, "Can not find rule for key %s. This rule does not exist in DB", key);
return rule;
} }


@Override @Override
public boolean hasKey(RuleKey key) { public Optional<Rule> findByKey(RuleKey key) {
return cache.getNullable(key) != null; verifyKeyArgument(key);

ensureInitialized();

return Optional.fromNullable(rulesByKey.get(key));
} }

@Override
public Rule getById(int id) {
ensureInitialized();

Rule rule = rulesById.get(id);
checkArgument(rule != null, "Can not find rule for id %s. This rule does not exist in DB", id);
return rule;
}

@Override
public Optional<Rule> findById(int id) {
ensureInitialized();

return Optional.fromNullable(rulesById.get(id));
}

private static void verifyKeyArgument(RuleKey key) {
requireNonNull(key, "RuleKey can not be null");
}

private void ensureInitialized() {
if (rulesByKey == null) {
DbSession dbSession = dbClient.openSession(false);
try {
loadRulesFromDb(dbSession);
} finally {
dbClient.closeSession(dbSession);
}
}
}

private void loadRulesFromDb(DbSession dbSession) {
ImmutableMap.Builder<RuleKey, Rule> rulesByKeyBuilder = ImmutableMap.builder();
ImmutableMap.Builder<Integer, Rule> rulesByIdBuilder = ImmutableMap.builder();
for (RuleDto ruleDto : dbClient.ruleDao().selectAll(dbSession)) {
Rule rule = new RuleImpl(ruleDto);
rulesByKeyBuilder.put(ruleDto.getKey(), rule);
rulesByIdBuilder.put(ruleDto.getId(), rule);
}
this.rulesByKey = rulesByKeyBuilder.build();
this.rulesById = rulesByIdBuilder.build();
}

} }
Expand Up @@ -19,6 +19,7 @@
*/ */
package org.sonar.server.computation.step; package org.sonar.server.computation.step;


import com.google.common.base.Optional;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
Expand Down Expand Up @@ -66,11 +67,8 @@ public void execute() {
private class IsValid implements Predicate<ActiveRule> { private class IsValid implements Predicate<ActiveRule> {
@Override @Override
public boolean apply(@Nonnull ActiveRule input) { public boolean apply(@Nonnull ActiveRule input) {
if (ruleRepository.hasKey(input.getRuleKey())) { Optional<Rule> rule = ruleRepository.findByKey(input.getRuleKey());
Rule rule = ruleRepository.getByKey(input.getRuleKey()); return rule.isPresent() && rule.get().getStatus() != RuleStatus.REMOVED;
return rule.getStatus() != RuleStatus.REMOVED;
}
return false;
} }
} }


Expand Down
Expand Up @@ -39,6 +39,7 @@ public class DumbRule implements Rule {


public DumbRule(RuleKey key) { public DumbRule(RuleKey key) {
this.key = key; this.key = key;
this.id = key.hashCode();
} }


@Override @Override
Expand Down

This file was deleted.

0 comments on commit a9d76b1

Please sign in to comment.