]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8949 make api/rules/update organization aware
authorDaniel Schwarz <daniel.schwarz@sonarsource.com>
Wed, 5 Apr 2017 13:11:55 +0000 (15:11 +0200)
committerDaniel Schwarz <bartfastiel@users.noreply.github.com>
Fri, 14 Apr 2017 06:57:18 +0000 (08:57 +0200)
16 files changed:
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java
server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java
server/sonar-server/src/main/java/org/sonar/server/rule/RuleUpdate.java
server/sonar-server/src/main/java/org/sonar/server/rule/RuleUpdater.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleMapper.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/UpdateAction.java
server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/RuleUpdaterMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/CreateActionMediumTest/create_custom_rule.json

index 0fd44b9f5a3117958760ad923691dbe2f537692c..d5036c4e4f063e19a24593fe2e24055b62623a98 100644 (file)
@@ -36,6 +36,14 @@ import static org.sonar.db.DatabaseUtils.executeLargeInputs;
 
 public class RuleDao implements Dao {
 
+  public Optional<RuleDto> selectByKey(DbSession session, OrganizationDto organization, RuleKey key) {
+    return selectByKey(session, organization.getUuid(), key);
+  }
+
+  /**
+   * @deprecated use {@link #selectByKey(DbSession, OrganizationDto, RuleKey)}
+   */
+  @Deprecated
   public Optional<RuleDto> selectByKey(DbSession session, String organizationUuid, RuleKey key) {
     RuleDto res = mapper(session).selectByKey(organizationUuid, key);
     ensureOrganizationIsSet(organizationUuid, res);
@@ -50,12 +58,12 @@ public class RuleDao implements Dao {
     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);
+  public RuleDto selectOrFailByKey(DbSession session, OrganizationDto organization, RuleKey key) {
+    RuleDto rule = mapper(session).selectByKey(organization.getUuid(), key);
     if (rule == null) {
       throw new RowNotFoundException(String.format("Rule with key '%s' does not exist", key));
     }
-    ensureOrganizationIsSet(organizationUuid, rule);
+    ensureOrganizationIsSet(organization.getUuid(), rule);
     return rule;
   }
 
index 39001ebfa4ae30abd621db6680b0793950e9f0df..e42b757fe488e20780c6dcd16f6780b964d131cf 100644 (file)
@@ -39,6 +39,8 @@ import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 import org.sonar.db.RowNotFoundException;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.organization.OrganizationTesting;
 
 import static com.google.common.collect.Sets.newHashSet;
 import static java.util.Arrays.asList;
@@ -154,7 +156,8 @@ public class RuleDaoTest {
   public void selectOrFailByKey() {
     dbTester.prepareDbUnit(getClass(), "shared.xml");
 
-    RuleDto rule = underTest.selectOrFailByKey(dbTester.getSession(), "org-1", RuleKey.of("java", "S001"));
+    OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid("org-1");
+    RuleDto rule = underTest.selectOrFailByKey(dbTester.getSession(), organization, RuleKey.of("java", "S001"));
     assertThat(rule.getId()).isEqualTo(1);
   }
 
@@ -165,7 +168,8 @@ public class RuleDaoTest {
     thrown.expect(RowNotFoundException.class);
     thrown.expectMessage("Rule with key 'NOT:FOUND' does not exist");
 
-    underTest.selectOrFailByKey(dbTester.getSession(), "org-1", RuleKey.of("NOT", "FOUND"));
+    OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid("org-1");
+    underTest.selectOrFailByKey(dbTester.getSession(), organization, RuleKey.of("NOT", "FOUND"));
   }
 
   @Test
@@ -173,7 +177,8 @@ public class RuleDaoTest {
     dbTester.prepareDbUnit(getClass(), "shared.xml");
     String organizationUuid = "org-1";
 
-    assertThat(underTest.selectOrFailByKey(dbTester.getSession(), organizationUuid, RuleKey.of("java", "S001")).getOrganizationUuid())
+    OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid(organizationUuid);
+    assertThat(underTest.selectOrFailByKey(dbTester.getSession(), organization, RuleKey.of("java", "S001")).getOrganizationUuid())
       .isEqualTo(organizationUuid);
   }
 
@@ -415,7 +420,8 @@ public class RuleDaoTest {
     underTest.insertOrUpdate(dbTester.getSession(), metadataToUpdate);
     dbTester.getSession().commit();
 
-    RuleDto ruleDto = underTest.selectOrFailByKey(dbTester.getSession(), organizationUuid, RuleKey.of("checkstyle", "AvoidNull"));
+    OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid(organizationUuid);
+    RuleDto ruleDto = underTest.selectOrFailByKey(dbTester.getSession(), organization, RuleKey.of("checkstyle", "AvoidNull"));
     assertThat(ruleDto.getName()).isEqualTo("Avoid Null");
     assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL");
     assertThat(ruleDto.getDescriptionFormat()).isNull();
@@ -449,6 +455,7 @@ public class RuleDaoTest {
   public void update_RuleMetadataDto_updates_row_in_RULE_METADATA_if_already_exists() {
     dbTester.prepareDbUnit(getClass(), "update.xml");
     String organizationUuid = "org-1";
+    OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid(organizationUuid);
     RuleMetadataDto metadataV1 = new RuleMetadataDto()
         .setRuleId(1)
         .setOrganizationUuid(organizationUuid)
@@ -472,7 +479,7 @@ public class RuleDaoTest {
     dbTester.commit();
 
     assertThat(dbTester.countRowsOfTable("RULES_METADATA")).isEqualTo(1);
-    RuleDto ruleDto = underTest.selectOrFailByKey(dbTester.getSession(), organizationUuid, RuleKey.of("checkstyle", "AvoidNull"));
+    RuleDto ruleDto = underTest.selectOrFailByKey(dbTester.getSession(), organization, RuleKey.of("checkstyle", "AvoidNull"));
     assertThat(ruleDto.getName()).isEqualTo("Avoid Null");
     assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL");
     assertThat(ruleDto.getDescriptionFormat()).isNull();
@@ -504,7 +511,7 @@ public class RuleDaoTest {
     underTest.insertOrUpdate(dbTester.getSession(), metadataV2);
     dbTester.commit();
 
-    ruleDto = underTest.selectOrFailByKey(dbTester.getSession(), organizationUuid, RuleKey.of("checkstyle", "AvoidNull"));
+    ruleDto = underTest.selectOrFailByKey(dbTester.getSession(), organization, RuleKey.of("checkstyle", "AvoidNull"));
     assertThat(ruleDto.getName()).isEqualTo("Avoid Null");
     assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL");
     assertThat(ruleDto.getDescriptionFormat()).isNull();
index 40f0c2339c2c81337b7729512b2604212d52c682..d0c2ebf083fdfe68e1dd1678bf2fc3e47a69b5cf 100644 (file)
@@ -75,7 +75,7 @@ public class RuleCreator {
     String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid();
     OrganizationDto defaultOrganization = dbClient.organizationDao().selectByUuid(dbSession, defaultOrganizationUuid)
       .orElseThrow(() -> new IllegalStateException(String.format("Could not find default organization for uuid '%s'", defaultOrganizationUuid)));
-    RuleDto templateRule = dbClient.ruleDao().selectOrFailByKey(dbSession, defaultOrganization.getUuid(), templateKey);
+    RuleDto templateRule = dbClient.ruleDao().selectOrFailByKey(dbSession, defaultOrganization, templateKey);
     if (!templateRule.isTemplate()) {
       throw new IllegalArgumentException("This rule is not a template rule: " + templateKey.toString());
     }
index a6580038007109ec8f04047791dce2638fd8ef78..ecd955e1f73a146ed062eac16a4d3e8877640170 100644 (file)
@@ -28,6 +28,10 @@ import org.apache.commons.lang.StringUtils;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.db.organization.OrganizationDto;
+
+import static org.sonar.server.rule.RuleUpdate.RuleUpdateUseCase.CUSTOM_RULE;
+import static org.sonar.server.rule.RuleUpdate.RuleUpdateUseCase.PLUGIN_RULE;
 
 public class RuleUpdate {
 
@@ -41,7 +45,7 @@ public class RuleUpdate {
   private boolean changeSeverity = false;
   private boolean changeStatus = false;
   private boolean changeParameters = false;
-  private boolean isCustomRule;
+  private final RuleUpdateUseCase useCase;
   private Set<String> tags;
   private String markdownNote;
   private DebtRemediationFunction debtRemediationFunction;
@@ -51,9 +55,11 @@ public class RuleUpdate {
   private String severity;
   private RuleStatus status;
   private final Map<String, String> parameters = Maps.newHashMap();
+  private OrganizationDto organization;
 
-  private RuleUpdate(RuleKey ruleKey) {
+  private RuleUpdate(RuleKey ruleKey, RuleUpdateUseCase useCase) {
     this.ruleKey = ruleKey;
+    this.useCase = useCase;
   }
 
   public RuleKey getRuleKey() {
@@ -158,6 +164,11 @@ public class RuleUpdate {
     return this;
   }
 
+  public RuleUpdate setOrganization(OrganizationDto organization) {
+    this.organization = organization;
+    return this;
+  }
+
   public Map<String, String> getParameters() {
     return parameters;
   }
@@ -168,7 +179,7 @@ public class RuleUpdate {
   }
 
   boolean isCustomRule() {
-    return isCustomRule;
+    return useCase.isCustomRule;
   }
 
   public boolean isChangeTags() {
@@ -212,27 +223,37 @@ public class RuleUpdate {
   }
 
   private void checkCustomRule() {
-    if (!isCustomRule) {
+    if (useCase != CUSTOM_RULE) {
       throw new IllegalStateException("Not a custom rule");
     }
   }
 
+  public OrganizationDto getOrganization() {
+    return organization;
+  }
+
   /**
    * Use to update a rule provided by a plugin (name, description, severity, status and parameters cannot by changed)
    */
   public static RuleUpdate createForPluginRule(RuleKey ruleKey) {
-    RuleUpdate ruleUpdate = new RuleUpdate(ruleKey);
-    ruleUpdate.isCustomRule = false;
-    return ruleUpdate;
+    return new RuleUpdate(ruleKey, PLUGIN_RULE);
   }
 
   /**
    * Use to update a custom rule
    */
   public static RuleUpdate createForCustomRule(RuleKey ruleKey) {
-    RuleUpdate ruleUpdate = new RuleUpdate(ruleKey);
-    ruleUpdate.isCustomRule = true;
-    return ruleUpdate;
+    return new RuleUpdate(ruleKey, CUSTOM_RULE);
   }
 
+  public enum RuleUpdateUseCase {
+    PLUGIN_RULE(false),
+    CUSTOM_RULE(true);
+
+    public final boolean isCustomRule;
+
+    RuleUpdateUseCase(boolean isCustomRule) {
+      this.isCustomRule = isCustomRule;
+    }
+  }
 }
index 2faa6481d5713b5647210886cf7ade2d0b3f0cdc..4bde48c10fa61fad4bc57a3a1ed6fc98cc601aa4 100644 (file)
@@ -32,6 +32,7 @@ import java.util.Set;
 import java.util.function.Consumer;
 import javax.annotation.Nonnull;
 import org.apache.commons.lang.builder.EqualsBuilder;
+import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.server.ServerSide;
@@ -39,6 +40,7 @@ import org.sonar.api.server.debt.DebtRemediationFunction;
 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;
@@ -72,20 +74,7 @@ public class RuleUpdater {
   /**
    * Update manual rules and custom rules (rules instantiated from templates)
    */
-  public boolean update(RuleUpdate update, UserSession userSession) {
-    if (update.isEmpty()) {
-      return false;
-    }
-
-    try (DbSession dbSession = dbClient.openSession(false)) {
-      return update(dbSession, update, userSession);
-    }
-  }
-
-  /**
-   * Update manual rules and custom rules (rules instantiated from templates)
-   */
-  public boolean update(DbSession dbSession, RuleUpdate update, UserSession userSession) {
+  public boolean update(DbSession dbSession, RuleUpdate update, OrganizationDto organization, UserSession userSession) {
     if (update.isEmpty()) {
       return false;
     }
@@ -97,7 +86,9 @@ public class RuleUpdater {
     updateParameters(dbSession, update, rule);
     dbSession.commit();
 
-    ruleIndexer.indexRuleDefinition(rule.getKey());
+    RuleKey ruleKey = rule.getKey();
+    ruleIndexer.indexRuleDefinition(ruleKey);
+    ruleIndexer.indexRuleExtension(organization, ruleKey);
     return true;
   }
 
@@ -106,7 +97,7 @@ public class RuleUpdater {
    */
   private RuleDto getRuleDto(RuleUpdate change) {
     try (DbSession dbSession = dbClient.openSession(false)) {
-      RuleDto rule = dbClient.ruleDao().selectOrFailByKey(dbSession, defaultOrganizationProvider.get().getUuid(), change.getRuleKey());
+      RuleDto rule = dbClient.ruleDao().selectOrFailByKey(dbSession, change.getOrganization(), change.getRuleKey());
       if (RuleStatus.REMOVED == rule.getStatus()) {
         throw new IllegalArgumentException("Rule with REMOVED status cannot be updated: " + change.getRuleKey());
       }
index bab150fad9c156cd816a2c5e48e8480a4ff1936b..7effe66a7c69702cf7779b7cc5f063d462d02c40 100644 (file)
@@ -33,9 +33,7 @@ import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.rule.RuleDefinitionDto;
-import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleParamDto;
-import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.rule.NewCustomRule;
 import org.sonar.server.rule.ReactivationException;
 import org.sonar.server.rule.RuleCreator;
@@ -64,13 +62,11 @@ public class CreateAction implements RulesWsAction {
   private final DbClient dbClient;
   private final RuleCreator ruleCreator;
   private final RuleMapper ruleMapper;
-  private final DefaultOrganizationProvider defaultOrganizationProvider;
 
-  public CreateAction(DbClient dbClient, RuleCreator ruleCreator, RuleMapper ruleMapper, DefaultOrganizationProvider defaultOrganizationProvider) {
+  public CreateAction(DbClient dbClient, RuleCreator ruleCreator, RuleMapper ruleMapper) {
     this.dbClient = dbClient;
     this.ruleCreator = ruleCreator;
     this.ruleMapper = ruleMapper;
-    this.defaultOrganizationProvider = defaultOrganizationProvider;
   }
 
   @Override
@@ -150,7 +146,8 @@ public class CreateAction implements RulesWsAction {
         }
         writeResponse(dbSession, request, response, ruleCreator.create(dbSession, newRule));
       } catch (ReactivationException e) {
-        write409(dbSession, request, response, e.ruleKey());
+        response.stream().setStatus(HTTP_CONFLICT);
+        writeResponse(dbSession, request, response, e.ruleKey());
       }
     }
   }
@@ -159,14 +156,10 @@ public class CreateAction implements RulesWsAction {
     writeProtobuf(createResponse(dbSession, ruleKey), request, response);
   }
 
-  private void write409(DbSession dbSession, Request request, Response response, RuleKey ruleKey) {
-    response.stream().setStatus(HTTP_CONFLICT);
-    writeProtobuf(createResponse(dbSession, ruleKey), request, response);
-  }
-
   private Rules.CreateResponse createResponse(DbSession dbSession, RuleKey ruleKey) {
-    String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid();
-    RuleDto rule = dbClient.ruleDao().selectOrFailByKey(dbSession, defaultOrganizationUuid, ruleKey);
+    RuleDefinitionDto rule = dbClient.ruleDao().selectDefinitionByKey(dbSession, ruleKey)
+      .transform(java.util.Optional::of).or(java.util.Optional::empty)
+      .orElseThrow(() -> new IllegalStateException(String.format("Cannot load rule, that has just been created '%s'", ruleKey)));
     List<RuleDefinitionDto> templateRules = new ArrayList<>();
     if (rule.getTemplateId() != null) {
       Optional<RuleDefinitionDto> templateRule = dbClient.ruleDao().selectDefinitionById(rule.getTemplateId(), dbSession);
@@ -176,7 +169,6 @@ public class CreateAction implements RulesWsAction {
     }
     List<RuleParamDto> ruleParameters = dbClient.ruleDao().selectRuleParamsByRuleIds(dbSession, singletonList(rule.getId()));
     SearchAction.SearchResult searchResult = new SearchAction.SearchResult()
-      .setRules(singletonList(rule))
       .setRuleParameters(ruleParameters)
       .setTemplateRules(templateRules)
       .setTotal(1L);
index 93c5ecf233318a091263547786ab8882d04cce1b..be044779fdbf9c61937824d14e35cef3d1bdec00 100644 (file)
@@ -31,7 +31,7 @@ import org.sonar.api.resources.Languages;
 import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
 import org.sonar.db.rule.RuleDefinitionDto;
-import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleMetadataDto;
 import org.sonar.db.rule.RuleParamDto;
 import org.sonar.markdown.Markdown;
 import org.sonar.server.rule.ws.SearchAction.SearchResult;
@@ -79,48 +79,58 @@ public class RuleMapper {
     this.macroInterpreter = macroInterpreter;
   }
 
-  /**
-   * Convert a RuleDto to WsRule. If fieldsToReturn is empty all the fields are returned
-   */
-  public Rules.Rule toWsRule(RuleDto ruleDto, SearchResult result, Set<String> fieldsToReturn) {
+  public Rules.Rule toWsRule(RuleDefinitionDto ruleDefinitionDto, SearchResult result, Set<String> fieldsToReturn) {
     Rules.Rule.Builder ruleResponse = Rules.Rule.newBuilder();
+    applyRuleDefinition(ruleResponse, ruleDefinitionDto, result, fieldsToReturn);
+    return ruleResponse.build();
+  }
+
+  public Rules.Rule toWsRule(RuleDefinitionDto ruleDefinitionDto, SearchResult result, Set<String> fieldsToReturn, RuleMetadataDto metadata) {
+    Rules.Rule.Builder ruleResponse = Rules.Rule.newBuilder();
+    applyRuleDefinition(ruleResponse, ruleDefinitionDto, result, fieldsToReturn);
+    applyRuleMetadata(ruleResponse, metadata, fieldsToReturn);
+    setDebtRemediationFunctionFields(ruleResponse, ruleDefinitionDto, metadata, fieldsToReturn);
+    return ruleResponse.build();
+  }
+
+  public Rules.Rule.Builder applyRuleDefinition(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDefinitionDto, SearchResult result, Set<String> fieldsToReturn) {
 
     // Mandatory fields
-    ruleResponse.setKey(ruleDto.getKey().toString());
-    Common.RuleType type = Common.RuleType.valueOf(ruleDto.getType());
-    ruleResponse.setType(type);
+    ruleResponse.setKey(ruleDefinitionDto.getKey().toString());
+    ruleResponse.setType(Common.RuleType.valueOf(ruleDefinitionDto.getType()));
 
     // Optional fields
-    setRepository(ruleResponse, ruleDto, fieldsToReturn);
-    setName(ruleResponse, ruleDto, fieldsToReturn);
-    setStatus(ruleResponse, ruleDto, fieldsToReturn);
-    setTags(ruleResponse, ruleDto, fieldsToReturn);
-    setSysTags(ruleResponse, ruleDto, fieldsToReturn);
-    setParams(ruleResponse, ruleDto, result, fieldsToReturn);
-    setCreatedAt(ruleResponse, ruleDto, fieldsToReturn);
-    setDescriptionFields(ruleResponse, ruleDto, fieldsToReturn);
-    setNotesFields(ruleResponse, ruleDto, fieldsToReturn);
-    setSeverity(ruleResponse, ruleDto, fieldsToReturn);
-    setInternalKey(ruleResponse, ruleDto, fieldsToReturn);
-    setLanguage(ruleResponse, ruleDto, fieldsToReturn);
-    setLanguageName(ruleResponse, ruleDto, fieldsToReturn);
-    setIsTemplate(ruleResponse, ruleDto, fieldsToReturn);
-    setTemplateKey(ruleResponse, ruleDto, result, fieldsToReturn);
-    setDebtRemediationFunctionFields(ruleResponse, ruleDto, fieldsToReturn);
-    setDefaultDebtRemediationFunctionFields(ruleResponse, ruleDto, fieldsToReturn);
-    setIsRemediationFunctionOverloaded(ruleResponse, ruleDto, fieldsToReturn);
-    setEffortToFixDescription(ruleResponse, ruleDto, fieldsToReturn);
+    setRepository(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setName(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setStatus(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setSysTags(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setParams(ruleResponse, ruleDefinitionDto, result, fieldsToReturn);
+    setCreatedAt(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setDescriptionFields(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setSeverity(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setInternalKey(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setLanguage(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setLanguageName(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setIsTemplate(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setTemplateKey(ruleResponse, ruleDefinitionDto, result, fieldsToReturn);
+    setDefaultDebtRemediationFunctionFields(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    setEffortToFixDescription(ruleResponse, ruleDefinitionDto, fieldsToReturn);
+    return ruleResponse;
+  }
 
-    return ruleResponse.build();
+  private void applyRuleMetadata(Rules.Rule.Builder ruleResponse, RuleMetadataDto metadata, Set<String> fieldsToReturn) {
+    setTags(ruleResponse, metadata, fieldsToReturn);
+    setNotesFields(ruleResponse, metadata, fieldsToReturn);
+    setIsRemediationFunctionOverloaded(ruleResponse, metadata, fieldsToReturn);
   }
 
-  private static void setRepository(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setRepository(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_REPO)) {
       ruleResponse.setRepo(ruleDto.getKey().repository());
     }
   }
 
-  private static void setEffortToFixDescription(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setEffortToFixDescription(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if ((shouldReturnField(fieldsToReturn, FIELD_EFFORT_TO_FIX_DESCRIPTION) || shouldReturnField(fieldsToReturn, FIELD_GAP_DESCRIPTION))
       && ruleDto.getGapDescription() != null) {
       ruleResponse.setEffortToFixDescription(ruleDto.getGapDescription());
@@ -128,14 +138,14 @@ public class RuleMapper {
     }
   }
 
-  private static void setIsRemediationFunctionOverloaded(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setIsRemediationFunctionOverloaded(Rules.Rule.Builder ruleResponse, RuleMetadataDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_DEBT_OVERLOADED) || shouldReturnField(fieldsToReturn, FIELD_REM_FUNCTION_OVERLOADED)) {
       ruleResponse.setDebtOverloaded(isRemediationFunctionOverloaded(ruleDto));
       ruleResponse.setRemFnOverloaded(isRemediationFunctionOverloaded(ruleDto));
     }
   }
 
-  private static void setDefaultDebtRemediationFunctionFields(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setDefaultDebtRemediationFunctionFields(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_DEFAULT_DEBT_REM_FUNCTION) || shouldReturnField(fieldsToReturn, FIELD_DEFAULT_REM_FUNCTION)) {
       DebtRemediationFunction defaultDebtRemediationFunction = defaultDebtRemediationFunction(ruleDto);
       if (defaultDebtRemediationFunction != null) {
@@ -160,9 +170,10 @@ public class RuleMapper {
     }
   }
 
-  private static void setDebtRemediationFunctionFields(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setDebtRemediationFunctionFields(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDefinitionDto, RuleMetadataDto ruleMetadataDto,
+    Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_DEBT_REM_FUNCTION) || shouldReturnField(fieldsToReturn, FIELD_REM_FUNCTION)) {
-      DebtRemediationFunction debtRemediationFunction = debtRemediationFunction(ruleDto);
+      DebtRemediationFunction debtRemediationFunction = debtRemediationFunction(ruleDefinitionDto, ruleMetadataDto);
       if (debtRemediationFunction != null) {
         if (debtRemediationFunction.type() != null) {
           ruleResponse.setRemFnType(debtRemediationFunction.type().name());
@@ -185,31 +196,31 @@ public class RuleMapper {
     }
   }
 
-  private static void setName(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setName(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_NAME) && ruleDto.getName() != null) {
       ruleResponse.setName(ruleDto.getName());
     }
   }
 
-  private static void setStatus(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setStatus(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_STATUS) && ruleDto.getStatus() != null) {
       ruleResponse.setStatus(Common.RuleStatus.valueOf(ruleDto.getStatus().toString()));
     }
   }
 
-  private static void setTags(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setTags(Rules.Rule.Builder ruleResponse, RuleMetadataDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_TAGS)) {
       ruleResponse.getTagsBuilder().addAllTags(ruleDto.getTags());
     }
   }
 
-  private static void setSysTags(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setSysTags(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_SYSTEM_TAGS)) {
       ruleResponse.getSysTagsBuilder().addAllSysTags(ruleDto.getSystemTags());
     }
   }
 
-  private static void setParams(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, SearchResult searchResult, Set<String> fieldsToReturn) {
+  private static void setParams(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, SearchResult searchResult, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_PARAMS)) {
       List<RuleParamDto> ruleParameters = searchResult.getRuleParamsByRuleId().get(ruleDto.getId());
       ruleResponse.getParamsBuilder().addAllParams(FluentIterable.from(ruleParameters)
@@ -218,13 +229,13 @@ public class RuleMapper {
     }
   }
 
-  private static void setCreatedAt(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setCreatedAt(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_CREATED_AT)) {
       ruleResponse.setCreatedAt(formatDateTime(ruleDto.getCreatedAt()));
     }
   }
 
-  private void setDescriptionFields(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private void setDescriptionFields(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_HTML_DESCRIPTION)) {
       String description = ruleDto.getDescription();
       if (description != null) {
@@ -246,7 +257,7 @@ public class RuleMapper {
     }
   }
 
-  private void setNotesFields(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private void setNotesFields(Rules.Rule.Builder ruleResponse, RuleMetadataDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, "htmlNote") && ruleDto.getNoteData() != null) {
       ruleResponse.setHtmlNote(macroInterpreter.interpret(Markdown.convertToHtml(ruleDto.getNoteData())));
     }
@@ -258,25 +269,25 @@ public class RuleMapper {
     }
   }
 
-  private static void setSeverity(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setSeverity(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_SEVERITY) && ruleDto.getSeverityString() != null) {
       ruleResponse.setSeverity(ruleDto.getSeverityString());
     }
   }
 
-  private static void setInternalKey(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setInternalKey(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_INTERNAL_KEY) && ruleDto.getConfigKey() != null) {
       ruleResponse.setInternalKey(ruleDto.getConfigKey());
     }
   }
 
-  private static void setLanguage(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setLanguage(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_LANGUAGE) && ruleDto.getLanguage() != null) {
       ruleResponse.setLang(ruleDto.getLanguage());
     }
   }
 
-  private void setLanguageName(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private void setLanguageName(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_LANGUAGE_NAME) && ruleDto.getLanguage() != null) {
       String languageKey = ruleDto.getLanguage();
       Language language = languages.get(languageKey);
@@ -284,13 +295,13 @@ public class RuleMapper {
     }
   }
 
-  private static void setIsTemplate(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+  private static void setIsTemplate(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_IS_TEMPLATE)) {
       ruleResponse.setIsTemplate(ruleDto.isTemplate());
     }
   }
 
-  private static void setTemplateKey(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, SearchResult result, Set<String> fieldsToReturn) {
+  private static void setTemplateKey(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, SearchResult result, Set<String> fieldsToReturn) {
     if (shouldReturnField(fieldsToReturn, FIELD_TEMPLATE_KEY) && ruleDto.getTemplateId() != null) {
       RuleDefinitionDto templateRule = result.getTemplateRulesByRuleId().get(ruleDto.getTemplateId());
       if (templateRule != null) {
@@ -303,12 +314,12 @@ public class RuleMapper {
     return fieldsToReturn.isEmpty() || fieldsToReturn.contains(fieldName);
   }
 
-  private static boolean isRemediationFunctionOverloaded(RuleDto rule) {
+  private static boolean isRemediationFunctionOverloaded(RuleMetadataDto rule) {
     return rule.getRemediationFunction() != null;
   }
 
   @CheckForNull
-  private static DebtRemediationFunction defaultDebtRemediationFunction(final RuleDto ruleDto) {
+  private static DebtRemediationFunction defaultDebtRemediationFunction(final RuleDefinitionDto ruleDto) {
     final String function = ruleDto.getDefRemediationFunction();
     if (function == null || function.isEmpty()) {
       return null;
@@ -321,15 +332,15 @@ public class RuleMapper {
   }
 
   @CheckForNull
-  private static DebtRemediationFunction debtRemediationFunction(final RuleDto ruleDto) {
-    final String function = ruleDto.getRemediationFunction();
+  private static DebtRemediationFunction debtRemediationFunction(RuleDefinitionDto ruleDefinitionDto, RuleMetadataDto ruleMetadataDto) {
+    final String function = ruleMetadataDto.getRemediationFunction();
     if (function == null || function.isEmpty()) {
-      return defaultDebtRemediationFunction(ruleDto);
+      return defaultDebtRemediationFunction(ruleDefinitionDto);
     } else {
       return new DefaultDebtRemediationFunction(
         DebtRemediationFunction.Type.valueOf(function.toUpperCase(Locale.ENGLISH)),
-        ruleDto.getRemediationGapMultiplier(),
-        ruleDto.getRemediationBaseEffort());
+        ruleMetadataDto.getRemediationGapMultiplier(),
+        ruleMetadataDto.getRemediationBaseEffort());
     }
   }
 
index a9b503ab7ea94a539208bc07ddcd0458dbb59ecf..5b507347a29899e24a53974c89a8e9cdcc2f4ce3 100644 (file)
@@ -309,7 +309,7 @@ public class SearchAction implements RulesWsAction {
 
   private void writeRules(SearchResponse.Builder response, SearchResult result, SearchOptions context) {
     for (RuleDto rule : result.rules) {
-      response.addRules(mapper.toWsRule(rule, result, context.getFields()));
+      response.addRules(mapper.toWsRule(rule.getDefinition(), result, context.getFields(), rule.getMetadata()));
     }
   }
 
index 264ca51aad33af4266aaa0dfd6fca7085fb01aa8..05264eef7d32d2f0ada1c85e716b2654093a453f 100644 (file)
@@ -120,7 +120,7 @@ public class ShowAction implements RulesWsAction {
   private ShowResponse buildResponse(DbSession dbSession, Request request, SearchAction.SearchResult searchResult) {
     ShowResponse.Builder responseBuilder = ShowResponse.newBuilder();
     RuleDto rule = searchResult.getRules().get(0);
-    responseBuilder.setRule(mapper.toWsRule(rule, searchResult, Collections.emptySet()));
+    responseBuilder.setRule(mapper.toWsRule(rule.getDefinition(), searchResult, Collections.emptySet(), rule.getMetadata()));
 
     if (request.mandatoryParamAsBoolean(PARAM_ACTIVES)) {
       activeRuleCompleter.completeShow(dbSession, rule, responseBuilder);
index 061eadae71dc84c5db38e097d754932e1d272254..8bde435eef448dce9c437a32abda9c54700d402a 100644 (file)
  */
 package org.sonar.server.rule.ws;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
@@ -37,18 +37,21 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.rule.RuleDefinitionDto;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleParamDto;
+import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.rule.RuleUpdate;
 import org.sonar.server.rule.RuleUpdater;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.Rules.UpdateResponse;
 
+import static java.lang.String.format;
 import static java.util.Collections.singletonList;
+import static java.util.Optional.ofNullable;
 import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
-import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 
 public class UpdateAction implements RulesWsAction {
@@ -66,6 +69,7 @@ public class UpdateAction implements RulesWsAction {
   public static final String PARAM_DESCRIPTION = "markdown_description";
   public static final String PARAM_SEVERITY = "severity";
   public static final String PARAM_STATUS = "status";
+  public static final String PARAM_ORGANIZATION = "organization";
   public static final String PARAMS = "params";
 
   private final DbClient dbClient;
@@ -76,7 +80,7 @@ public class UpdateAction implements RulesWsAction {
   private final DefaultOrganizationProvider defaultOrganizationProvider;
 
   public UpdateAction(DbClient dbClient, RuleUpdater ruleUpdater, RuleMapper mapper, UserSession userSession,
-                      RuleWsSupport ruleWsSupport, DefaultOrganizationProvider defaultOrganizationProvider) {
+    RuleWsSupport ruleWsSupport, DefaultOrganizationProvider defaultOrganizationProvider) {
     this.dbClient = dbClient;
     this.ruleUpdater = ruleUpdater;
     this.mapper = mapper;
@@ -158,6 +162,13 @@ public class UpdateAction implements RulesWsAction {
       .setDescription("Rule status (Only when updating a custom rule)")
       .setPossibleValues(RuleStatus.values());
 
+    action.createParam(PARAM_ORGANIZATION)
+      .setDescription("Organization key")
+      .setRequired(false)
+      .setInternal(true)
+      .setExampleValue("my-org")
+      .setSince("6.4");
+
     action.createParam(PARAMS)
       .setDescription("Parameters as semi-colon list of <key>=<value>, for example 'params=key1=v1;key2=v2' (Only when updating a custom rule)");
   }
@@ -167,18 +178,25 @@ public class UpdateAction implements RulesWsAction {
     ruleWsSupport.checkQProfileAdminPermission();
 
     try (DbSession dbSession = dbClient.openSession(false)) {
-      String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid();
-      RuleUpdate update = readRequest(dbSession, request, defaultOrganizationUuid);
-      ruleUpdater.update(dbSession, update, userSession);
-      UpdateResponse updateResponse = buildResponse(dbSession, update.getRuleKey(), defaultOrganizationUuid);
+      OrganizationDto organization = getOrganization(request, dbSession);
+      RuleUpdate update = readRequest(dbSession, request, organization);
+      ruleUpdater.update(dbSession, update, organization, userSession);
+      UpdateResponse updateResponse = buildResponse(dbSession, update.getRuleKey(), organization);
 
       writeProtobuf(updateResponse, request, response);
     }
   }
 
-  private RuleUpdate readRequest(DbSession dbSession, Request request, String organizationUuid) {
+  private OrganizationDto getOrganization(Request request, DbSession dbSession) {
+    String organizationKey = ofNullable(request.param(PARAM_ORGANIZATION))
+      .orElseGet(() -> defaultOrganizationProvider.get().getKey());
+    return dbClient.organizationDao().selectByKey(dbSession, organizationKey)
+      .orElseThrow(() -> new IllegalStateException(format("Cannot load organization '%s'", organizationKey)));
+  }
+
+  private RuleUpdate readRequest(DbSession dbSession, Request request, OrganizationDto organization) {
     RuleKey key = RuleKey.parse(request.mandatoryParam(PARAM_KEY));
-    RuleUpdate update = createRuleUpdate(dbSession, key, organizationUuid);
+    RuleUpdate update = createRuleUpdate(dbSession, key, organization);
     readTags(request, update);
     readMarkdownNote(request, update);
     readDebt(request, update);
@@ -206,18 +224,18 @@ public class UpdateAction implements RulesWsAction {
     return update;
   }
 
-  private RuleUpdate createRuleUpdate(DbSession dbSession, RuleKey key, String organizationUuid) {
-    Optional<RuleDto> optionalRule = dbClient.ruleDao().selectByKey(dbSession, organizationUuid, key);
-    checkFoundWithOptional(optionalRule, "This rule does not exists : " + key);
-    RuleDto rule = optionalRule.get();
-    if (rule.getTemplateId() != null) {
-      return RuleUpdate.createForCustomRule(key);
-    } else {
-      return RuleUpdate.createForPluginRule(key);
-    }
+  private RuleUpdate createRuleUpdate(DbSession dbSession, RuleKey key, OrganizationDto organization) {
+    RuleDto rule = dbClient.ruleDao().selectByKey(dbSession, organization, key)
+      .transform(Optional::of).or(Optional::empty)
+      .orElseThrow(() -> new NotFoundException(format("This rule does not exist: %s", key)));
+    RuleUpdate ruleUpdate = ofNullable(rule.getTemplateId())
+      .map(x -> RuleUpdate.createForCustomRule(key))
+      .orElseGet(() -> RuleUpdate.createForPluginRule(key));
+    ruleUpdate.setOrganization(organization);
+    return ruleUpdate;
   }
 
-  private void readTags(Request request, RuleUpdate update) {
+  private static void readTags(Request request, RuleUpdate update) {
     String value = request.param(PARAM_TAGS);
     if (value != null) {
       if (StringUtils.isBlank(value)) {
@@ -229,7 +247,7 @@ public class UpdateAction implements RulesWsAction {
     // else do not touch this field
   }
 
-  private void readMarkdownNote(Request request, RuleUpdate update) {
+  private static void readMarkdownNote(Request request, RuleUpdate update) {
     String value = request.param(PARAM_MARKDOWN_NOTE);
     if (value != null) {
       update.setMarkdownNote(value);
@@ -237,7 +255,7 @@ public class UpdateAction implements RulesWsAction {
     // else do not touch this field
   }
 
-  private void readDebt(Request request, RuleUpdate update) {
+  private static void readDebt(Request request, RuleUpdate update) {
     String value = defaultIfEmpty(request.param(PARAM_REMEDIATION_FN_TYPE), request.param(DEPRECATED_PARAM_REMEDIATION_FN_TYPE));
     if (value != null) {
       if (StringUtils.isBlank(value)) {
@@ -252,16 +270,15 @@ public class UpdateAction implements RulesWsAction {
     }
   }
 
-  private UpdateResponse buildResponse(DbSession dbSession, RuleKey key, String organizationUuid) {
-    Optional<RuleDto> optionalRule = dbClient.ruleDao().selectByKey(dbSession, organizationUuid, key);
-    checkFoundWithOptional(optionalRule, "Rule not found: " + key);
-    RuleDto rule = optionalRule.get();
+  private UpdateResponse buildResponse(DbSession dbSession, RuleKey key, OrganizationDto organization) {
+    RuleDto rule = dbClient.ruleDao().selectByKey(dbSession, organization, key)
+      .transform(Optional::of).or(Optional::empty)
+      .orElseThrow(() -> new NotFoundException(format("Rule not found: %s", key)));
     List<RuleDefinitionDto> templateRules = new ArrayList<>(1);
     if (rule.getTemplateId() != null) {
-      Optional<RuleDefinitionDto> templateRule = dbClient.ruleDao().selectDefinitionById(rule.getTemplateId(), dbSession);
-      if (templateRule.isPresent()) {
-        templateRules.add(templateRule.get());
-      }
+      dbClient.ruleDao().selectDefinitionById(rule.getTemplateId(), dbSession)
+        .transform(Optional::of).or(Optional::empty)
+        .ifPresent(templateRules::add);
     }
     List<RuleParamDto> ruleParameters = dbClient.ruleDao().selectRuleParamsByRuleIds(dbSession, singletonList(rule.getId()));
     UpdateResponse.Builder responseBuilder = UpdateResponse.newBuilder();
@@ -270,7 +287,7 @@ public class UpdateAction implements RulesWsAction {
       .setTemplateRules(templateRules)
       .setRuleParameters(ruleParameters)
       .setTotal(1L);
-    responseBuilder.setRule(mapper.toWsRule(rule, searchResult, Collections.<String>emptySet()));
+    responseBuilder.setRule(mapper.toWsRule(rule.getDefinition(), searchResult, Collections.<String>emptySet(), rule.getMetadata()));
 
     return responseBuilder.build();
   }
index 186a8b3487070c6097e97fafcbdf64b8bf0c09a4..1067202bc24e1ac21c80a639ab9bca156ffcd7ea 100644 (file)
@@ -38,6 +38,7 @@ import org.sonar.api.server.rule.RuleParamType;
 import org.sonar.api.server.rule.RulesDefinition;
 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.ActiveRuleKey;
 import org.sonar.db.qualityprofile.ActiveRuleParamDto;
@@ -81,13 +82,15 @@ public class RegisterRulesMediumTest {
   private RuleIndex ruleIndex = TESTER.get(RuleIndex.class);
   private RuleDao ruleDao = db.ruleDao();
 
-  private String defaultOrganizationUuid;
+  private OrganizationDto defaultOrganization;
 
   @Before
   public void before() {
     TESTER.clearDbAndIndexes();
     dbSession.clearCache();
-    defaultOrganizationUuid = TESTER.get(DefaultOrganizationProvider.class).get().getUuid();
+    String defaultOrganizationUuid = TESTER.get(DefaultOrganizationProvider.class).get().getUuid();
+    defaultOrganization = db.organizationDao().selectByUuid(dbSession, defaultOrganizationUuid)
+      .orElseThrow(() -> new IllegalStateException(String.format("Cannot load default organization '%s'", defaultOrganizationUuid)));
   }
 
   @After
@@ -227,15 +230,18 @@ public class RegisterRulesMediumTest {
         repository.createRule("x1").setName("x1 name").setHtmlDescription("x1 desc").setTags("tag1");
       }
     });
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganizationUuid, RuleTesting.XOO_X1);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RuleTesting.XOO_X1);
     assertThat(rule.getSystemTags()).containsOnly("tag1");
     assertThat(rule.getTags()).isEmpty();
 
     // User adds tag
-    TESTER.get(RuleUpdater.class).update(dbSession, RuleUpdate.createForPluginRule(RuleTesting.XOO_X1).setTags(newHashSet("tag2")), userSessionRule);
+    RuleUpdate update = RuleUpdate.createForPluginRule(RuleTesting.XOO_X1)
+      .setTags(newHashSet("tag2"))
+      .setOrganization(defaultOrganization);
+    TESTER.get(RuleUpdater.class).update(dbSession, update, defaultOrganization, userSessionRule);
     dbSession.commit();
 
-    rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganizationUuid, RuleTesting.XOO_X1);
+    rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RuleTesting.XOO_X1);
     assertThat(rule.getSystemTags()).containsOnly("tag1");
     assertThat(rule.getTags()).containsOnly("tag2");
 
index 7b72f88a30f238efd079ea1b7af67e20ea0132e8..0a676943fa517752d0eab8fdf99d9d9fc930de3f 100644 (file)
@@ -36,6 +36,7 @@ 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.db.rule.RuleParamDto;
@@ -80,6 +81,7 @@ public class RegisterRulesTest {
   private RuleIndexer ruleIndexer;
   private ActiveRuleIndexer activeRuleIndexer;
   private RuleIndex ruleIndex;
+  private OrganizationDto defaultOrganization;
 
   @Before
   public void before() {
@@ -87,6 +89,7 @@ public class RegisterRulesTest {
     ruleIndexer = new RuleIndexer(esTester.client(), dbClient);
     ruleIndex = new RuleIndex(esTester.client());
     activeRuleIndexer = new ActiveRuleIndexer(system, dbClient, esTester.client());
+    defaultOrganization = dbTester.getDefaultOrganization();
   }
 
   @Test
@@ -95,7 +98,7 @@ public class RegisterRulesTest {
 
     // verify db
     assertThat(dbClient.ruleDao().selectAllDefinitions(dbTester.getSession())).hasSize(2);
-    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization().getUuid(), RULE_KEY1);
+    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization(), RULE_KEY1);
     assertThat(rule1.getName()).isEqualTo("One");
     assertThat(rule1.getDescription()).isEqualTo("Description of One");
     assertThat(rule1.getSeverityString()).isEqualTo(BLOCKER);
@@ -184,8 +187,9 @@ public class RegisterRulesTest {
     assertThat(esTester.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(RULE_KEY1.toString(), RULE_KEY2.toString());
 
     // user adds tags and sets markdown note
-    String organizationUuid = dbTester.getDefaultOrganization().getUuid();
-    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY1);
+    OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
+    String organizationUuid = defaultOrganization.getUuid();
+    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
     rule1.setTags(newHashSet("usertag1", "usertag2"));
     rule1.setNoteData("user *note*");
     rule1.setNoteUserLogin("marius");
@@ -196,7 +200,7 @@ public class RegisterRulesTest {
     execute(new FakeRepositoryV2());
 
     // rule1 has been updated
-    rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY1);
+    rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
     assertThat(rule1.getName()).isEqualTo("One v2");
     assertThat(rule1.getDescription()).isEqualTo("Description of One v2");
     assertThat(rule1.getSeverityString()).isEqualTo(INFO);
@@ -218,12 +222,12 @@ public class RegisterRulesTest {
     assertThat(param.getDefaultValue()).isEqualTo("default1 v2");
 
     // rule2 has been removed -> status set to REMOVED but db row is not deleted
-    RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY2);
+    RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
     assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED);
     assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2.getTime());
 
     // rule3 has been created
-    RuleDto rule3 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY3);
+    RuleDto rule3 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY3);
     assertThat(rule3).isNotNull();
     assertThat(rule3.getStatus()).isEqualTo(RuleStatus.READY);
 
@@ -248,8 +252,9 @@ public class RegisterRulesTest {
       }
     });
 
-    String organizationUuid = dbTester.getDefaultOrganization().getUuid();
-    RuleDto rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY1);
+    OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
+    String organizationUuid = defaultOrganization.getUuid();
+    RuleDto rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
     assertThat(rule.getSystemTags()).containsOnly("tag1");
 
     execute(new RulesDefinition() {
@@ -264,7 +269,7 @@ public class RegisterRulesTest {
       }
     });
 
-    rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY1);
+    rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
     assertThat(rule.getSystemTags()).containsOnly("tag1", "tag2");
   }
 
@@ -295,7 +300,7 @@ public class RegisterRulesTest {
     });
 
     // rule1 has been updated
-    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization().getUuid(), RuleKey.of("fake", "rule"));
+    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RuleKey.of("fake", "rule"));
     assertThat(rule1.getName()).isEqualTo("Name2");
     assertThat(rule1.getDescription()).isEqualTo("Description");
 
@@ -330,7 +335,7 @@ public class RegisterRulesTest {
     });
 
     // rule1 has been updated
-    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), dbTester.getDefaultOrganization().getUuid(), RuleKey.of("fake", "rule"));
+    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RuleKey.of("fake", "rule"));
     assertThat(rule1.getName()).isEqualTo("Name");
     assertThat(rule1.getDescription()).isEqualTo("Desc2");
 
@@ -349,7 +354,7 @@ public class RegisterRulesTest {
     execute();
 
     String organizationUuid = dbTester.getDefaultOrganization().getUuid();
-    RuleDto rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY1);
+    RuleDto rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
     assertThat(rule.getStatus()).isEqualTo(RuleStatus.REMOVED);
     assertThat(ruleIndex.search(new RuleQuery().setKey(RULE_KEY1.toString()), new SearchOptions()).getTotal()).isEqualTo(0);
 
@@ -357,7 +362,7 @@ public class RegisterRulesTest {
     when(system.now()).thenReturn(DATE3.getTime());
     execute(new FakeRepositoryV1());
 
-    rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY1);
+    rule = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
     assertThat(rule.getStatus()).isEqualTo(RuleStatus.BETA);
     assertThat(ruleIndex.search(new RuleQuery().setKey(RULE_KEY1.toString()), new SearchOptions()).getTotal()).isEqualTo(1);
   }
@@ -371,7 +376,7 @@ public class RegisterRulesTest {
     execute(new FakeRepositoryV1());
 
     String organizationUuid = dbTester.getDefaultOrganization().getUuid();
-    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY1);
+    RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1);
     assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime());
     assertThat(rule1.getUpdatedAt()).isEqualTo(DATE1.getTime());
   }
@@ -383,18 +388,18 @@ public class RegisterRulesTest {
     assertThat(esTester.getIds(RuleIndexDefinition.INDEX_TYPE_RULE)).containsOnly(RULE_KEY1.toString(), RULE_KEY2.toString());
 
     String organizationUuid = dbTester.getDefaultOrganization().getUuid();
-    RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY2);
+    RuleDto rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
     assertThat(rule2.getStatus()).isEqualTo(RuleStatus.READY);
 
     when(system.now()).thenReturn(DATE2.getTime());
     execute(new FakeRepositoryV2());
 
     // On MySQL, need to update a rule otherwise rule2 will be seen as READY, but why ???
-    dbClient.ruleDao().update(dbTester.getSession(), dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY1).getDefinition());
+    dbClient.ruleDao().update(dbTester.getSession(), dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY1).getDefinition());
     dbTester.getSession().commit();
 
     // rule2 is removed
-    rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY2);
+    rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
     assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED);
 
     assertThat(ruleIndex.search(new RuleQuery(), new SearchOptions()).getIds()).containsOnly(RULE_KEY1, RULE_KEY3);
@@ -404,7 +409,7 @@ public class RegisterRulesTest {
     dbTester.getSession().commit();
 
     // -> rule2 is still removed, but not update at DATE3
-    rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), organizationUuid, RULE_KEY2);
+    rule2 = dbClient.ruleDao().selectOrFailByKey(dbTester.getSession(), defaultOrganization, RULE_KEY2);
     assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED);
     assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2.getTime());
 
index 79664debc038a241ba5599bbaa4115fa6edc4fda..9cf911c825c2c3ecdb49a57f3f6820062ddf7373 100644 (file)
@@ -102,7 +102,7 @@ public class RuleCreatorMediumTest {
 
     dbSession.clearCache();
 
-    RuleDto rule = db.ruleDao().selectOrFailByKey(dbSession, defaultOrganization.getUuid(), customRuleKey);
+    RuleDto rule = db.ruleDao().selectOrFailByKey(dbSession, defaultOrganization, customRuleKey);
     assertThat(rule).isNotNull();
     assertThat(rule.getKey()).isEqualTo(RuleKey.of("java", "CUSTOM_RULE"));
     assertThat(rule.getTemplateId()).isEqualTo(templateRule.getId());
index 9232edb82695d24af9d7e789508aaff672047393..5a8f4ce1f0bc9220239462f7a10642400d507c13 100644 (file)
@@ -99,9 +99,11 @@ public class RuleUpdaterMediumTest {
     ruleDao.insert(dbSession, RuleTesting.newRule(RULE_KEY).setStatus(RuleStatus.REMOVED));
     dbSession.commit();
 
-    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setTags(Sets.newHashSet("java9"));
+    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
+      .setTags(Sets.newHashSet("java9"))
+      .setOrganization(defaultOrganization);
     try {
-      underTest.update(update, userSessionRule);
+      underTest.update(dbSession, update, defaultOrganization, userSessionRule);
       fail();
     } catch (IllegalArgumentException e) {
       assertThat(e).hasMessage("Rule with REMOVED status cannot be updated: squid:S001");
@@ -124,10 +126,10 @@ public class RuleUpdaterMediumTest {
 
     RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY);
     assertThat(update.isEmpty()).isTrue();
-    underTest.update(update, userSessionRule);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
 
     dbSession.clearCache();
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getNoteData()).isEqualTo("my *note*");
     assertThat(rule.getNoteUserLogin()).isEqualTo("me");
     assertThat(rule.getTags()).containsOnly("tag1");
@@ -153,12 +155,13 @@ public class RuleUpdaterMediumTest {
     ruleDao.insertOrUpdate(dbSession, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
     dbSession.commit();
 
-    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY);
-    update.setMarkdownNote("my *note*");
-    underTest.update(update, userSessionRule);
+    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
+      .setMarkdownNote("my *note*")
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
 
     dbSession.clearCache();
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getNoteData()).isEqualTo("my *note*");
     assertThat(rule.getNoteUserLogin()).isEqualTo("me");
     assertThat(rule.getNoteCreatedAt()).isNotNull();
@@ -179,11 +182,13 @@ public class RuleUpdaterMediumTest {
     ruleDao.insertOrUpdate(dbSession, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
     dbSession.commit();
 
-    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setMarkdownNote(null);
-    underTest.update(update, userSessionRule);
+    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
+      .setMarkdownNote(null)
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
 
     dbSession.clearCache();
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getNoteData()).isNull();
     assertThat(rule.getNoteUserLogin()).isNull();
     assertThat(rule.getNoteCreatedAt()).isNull();
@@ -201,9 +206,9 @@ public class RuleUpdaterMediumTest {
 
     // java8 is a system tag -> ignore
     RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setTags(Sets.newHashSet("bug", "java8"));
-    underTest.update(update, userSessionRule);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
 
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getTags()).containsOnly("bug");
     assertThat(rule.getSystemTags()).containsOnly("java8", "javadoc");
 
@@ -221,11 +226,13 @@ public class RuleUpdaterMediumTest {
     ruleDao.insertOrUpdate(dbSession, ruleDto.getMetadata());
     dbSession.commit();
 
-    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setTags(null);
-    underTest.update(update, userSessionRule);
+    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
+      .setTags(null)
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
 
     dbSession.clearCache();
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getTags()).isEmpty();
     assertThat(rule.getSystemTags()).containsOnly("java8", "javadoc");
 
@@ -244,12 +251,13 @@ public class RuleUpdaterMediumTest {
 
     DefaultDebtRemediationFunction fn = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "1min");
     RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
-      .setDebtRemediationFunction(fn);
-    underTest.update(update, userSessionRule);
+      .setDebtRemediationFunction(fn)
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
     dbSession.clearCache();
 
     // verify debt is overridden
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE.name());
     assertThat(rule.getRemediationGapMultiplier()).isNull();
     assertThat(rule.getRemediationBaseEffort()).isEqualTo("1min");
@@ -268,12 +276,13 @@ public class RuleUpdaterMediumTest {
     dbSession.commit();
 
     RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
-      .setDebtRemediationFunction(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "2d", null));
-    underTest.update(update, userSessionRule);
+      .setDebtRemediationFunction(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "2d", null))
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
     dbSession.clearCache();
 
     // verify debt is overridden
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.LINEAR.name());
     assertThat(rule.getRemediationGapMultiplier()).isEqualTo("2d");
     assertThat(rule.getRemediationBaseEffort()).isNull();
@@ -292,12 +301,13 @@ public class RuleUpdaterMediumTest {
     dbSession.commit();
 
     RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
-      .setDebtRemediationFunction(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "10min"));
-    underTest.update(update, userSessionRule);
+      .setDebtRemediationFunction(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "10min"))
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
     dbSession.clearCache();
 
     // verify debt is overridden
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE.name());
     assertThat(rule.getRemediationGapMultiplier()).isNull();
     assertThat(rule.getRemediationBaseEffort()).isEqualTo("10min");
@@ -320,12 +330,14 @@ public class RuleUpdaterMediumTest {
     ruleDao.insertOrUpdate(dbSession, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
     dbSession.commit();
 
-    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setDebtRemediationFunction(null);
-    underTest.update(update, userSessionRule);
+    RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
+      .setDebtRemediationFunction(null)
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
     dbSession.clearCache();
 
     // verify debt is coming from default values
-    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), RULE_KEY);
+    RuleDto rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, RULE_KEY);
     assertThat(rule.getDefRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.LINEAR.name());
     assertThat(rule.getDefRemediationGapMultiplier()).isEqualTo("1d");
     assertThat(rule.getDefRemediationBaseEffort()).isEqualTo("5min");
@@ -364,13 +376,14 @@ public class RuleUpdaterMediumTest {
       .setMarkdownDescription("New description")
       .setSeverity("MAJOR")
       .setStatus(RuleStatus.READY)
-      .setParameters(ImmutableMap.of("regex", "b.*"));
-    underTest.update(update, userSessionRule);
+      .setParameters(ImmutableMap.of("regex", "b.*"))
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
 
     dbSession.clearCache();
 
     // Verify custom rule is updated
-    RuleDto customRuleReloaded = ruleDao.selectOrFailByKey(dbSession, defaultOrganization.getUuid(), customRule.getKey());
+    RuleDto customRuleReloaded = ruleDao.selectOrFailByKey(dbSession, defaultOrganization, customRule.getKey());
     assertThat(customRuleReloaded).isNotNull();
     assertThat(customRuleReloaded.getName()).isEqualTo("New name");
     assertThat(customRuleReloaded.getDescription()).isEqualTo("New description");
@@ -415,8 +428,9 @@ public class RuleUpdaterMediumTest {
       .setName("New name")
       .setMarkdownDescription("New description")
       .setSeverity("MAJOR")
-      .setStatus(RuleStatus.READY);
-    underTest.update(update, userSessionRule);
+      .setStatus(RuleStatus.READY)
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
 
     dbSession.clearCache();
 
@@ -461,8 +475,9 @@ public class RuleUpdaterMediumTest {
 
     // Update custom rule parameter 'regex', add 'message' and remove 'format'
     RuleUpdate update = RuleUpdate.createForCustomRule(customRule.getKey())
-      .setParameters(ImmutableMap.of("regex", "b.*", "message", "a message"));
-    underTest.update(update, userSessionRule);
+      .setParameters(ImmutableMap.of("regex", "b.*", "message", "a message"))
+      .setOrganization(defaultOrganization);
+    underTest.update(dbSession, update, defaultOrganization, userSessionRule);
 
     dbSession.clearCache();
 
@@ -495,21 +510,22 @@ public class RuleUpdaterMediumTest {
   @Test
   public void fail_to_update_custom_rule_when_empty_name() {
     // Create template rule
-    RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001"));
-    ruleDao.insert(dbSession, templateRule.getDefinition());
+    RuleDefinitionDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")).getDefinition();
+    ruleDao.insert(dbSession, templateRule);
 
     // Create custom rule
-    RuleDto customRule = RuleTesting.newCustomRule(templateRule);
-    ruleDao.insert(dbSession, customRule.getDefinition());
+    RuleDefinitionDto customRule = RuleTesting.newCustomRule(templateRule);
+    ruleDao.insert(dbSession, customRule);
 
     dbSession.commit();
 
     // Update custom rule
     RuleUpdate update = RuleUpdate.createForCustomRule(customRule.getKey())
       .setName("")
-      .setMarkdownDescription("New desc");
+      .setMarkdownDescription("New desc")
+      .setOrganization(defaultOrganization);
     try {
-      underTest.update(update, userSessionRule);
+      underTest.update(dbSession, update, defaultOrganization, userSessionRule);
       fail();
     } catch (Exception e) {
       assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("The name is missing");
@@ -531,9 +547,10 @@ public class RuleUpdaterMediumTest {
     // Update custom rule
     RuleUpdate update = RuleUpdate.createForCustomRule(customRule.getKey())
       .setName("New name")
-      .setMarkdownDescription("");
+      .setMarkdownDescription("")
+      .setOrganization(defaultOrganization);
     try {
-      underTest.update(update, userSessionRule);
+      underTest.update(dbSession, update, defaultOrganization, userSessionRule);
       fail();
     } catch (Exception e) {
       assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("The description is missing");
index 814348442d7d33db0b1c13bbb9648f105702b1ca..148d6eaffa3b9b0e52f95f24d18724ee1ecaef5e 100644 (file)
@@ -30,13 +30,13 @@ 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.db.rule.RuleMetadataDto;
 import org.sonar.db.rule.RuleTesting;
 import org.sonar.server.es.EsClient;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.rule.RuleUpdater;
-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;
@@ -54,13 +54,17 @@ import static org.mockito.Mockito.mock;
 import static org.sonar.api.server.debt.DebtRemediationFunction.Type.LINEAR;
 import static org.sonar.api.server.debt.DebtRemediationFunction.Type.LINEAR_OFFSET;
 import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
+import static org.sonar.db.rule.RuleTesting.setSystemTags;
+import static org.sonar.db.rule.RuleTesting.setTags;
 import static org.sonar.server.rule.ws.UpdateAction.DEPRECATED_PARAM_REMEDIATION_FN_COEFF;
 import static org.sonar.server.rule.ws.UpdateAction.DEPRECATED_PARAM_REMEDIATION_FN_OFFSET;
 import static org.sonar.server.rule.ws.UpdateAction.DEPRECATED_PARAM_REMEDIATION_FN_TYPE;
 import static org.sonar.server.rule.ws.UpdateAction.PARAM_KEY;
+import static org.sonar.server.rule.ws.UpdateAction.PARAM_ORGANIZATION;
 import static org.sonar.server.rule.ws.UpdateAction.PARAM_REMEDIATION_FN_BASE_EFFORT;
 import static org.sonar.server.rule.ws.UpdateAction.PARAM_REMEDIATION_FN_GAP_MULTIPLIER;
 import static org.sonar.server.rule.ws.UpdateAction.PARAM_REMEDIATION_FN_TYPE;
+import static org.sonar.server.rule.ws.UpdateAction.PARAM_TAGS;
 import static org.sonarqube.ws.MediaTypes.PROTOBUF;
 
 public class UpdateActionTest {
@@ -87,18 +91,71 @@ public class UpdateActionTest {
   private WsActionTester actionTester = new WsActionTester(underTest);
   private OrganizationDto defaultOrganization;
 
-  private RuleIndex ruleIndex = new RuleIndex(esClient);
-
   @Before
   public void setUp() {
     defaultOrganization = dbTester.getDefaultOrganization();
     logInAsQProfileAdministrator();
   }
 
+  @Test
+  public void update_tags_for_default_organization() throws IOException {
+    doReturn("interpreted").when(macroInterpreter).interpret(anyString());
+
+    RuleDefinitionDto rule = dbTester.rules().insert(setSystemTags("stag1", "stag2"));
+    dbTester.rules().insertOrUpdateMetadata(rule, defaultOrganization, setTags("tag1", "tag2"));
+
+    TestRequest request = actionTester.newRequest().setMethod("POST")
+      .setMediaType(PROTOBUF)
+      .setParam(PARAM_KEY, rule.getKey().toString())
+      .setParam(PARAM_TAGS, "tag2,tag3");
+    TestResponse response = request.execute();
+    Rules.UpdateResponse result = Rules.UpdateResponse.parseFrom(response.getInputStream());
+
+    Rules.Rule updatedRule = result.getRule();
+    assertThat(updatedRule).isNotNull();
+
+    assertThat(updatedRule.getKey()).isEqualTo(rule.getKey().toString());
+    assertThat(updatedRule.getSysTags().getSysTagsList()).containsExactly(rule.getSystemTags().toArray(new String[0]));
+    assertThat(updatedRule.getTags().getTagsList()).containsExactly("tag2", "tag3");
+  }
+
+  @Test
+  public void update_tags_for_specific_organization() throws IOException {
+    doReturn("interpreted").when(macroInterpreter).interpret(anyString());
+
+    OrganizationDto organization = dbTester.organizations().insert();
+
+    RuleDefinitionDto rule = dbTester.rules().insert(setSystemTags("stag1", "stag2"));
+    dbTester.rules().insertOrUpdateMetadata(rule, organization, setTags("tagAlt1", "tagAlt2"));
+
+    TestRequest request = actionTester.newRequest().setMethod("POST")
+      .setMediaType(PROTOBUF)
+      .setParam(PARAM_KEY, rule.getKey().toString())
+      .setParam(PARAM_TAGS, "tag2,tag3")
+      .setParam(PARAM_ORGANIZATION, organization.getKey());
+    TestResponse response = request.execute();
+    Rules.UpdateResponse result = Rules.UpdateResponse.parseFrom(response.getInputStream());
+
+    Rules.Rule updatedRule = result.getRule();
+    assertThat(updatedRule).isNotNull();
+
+    // check response
+    assertThat(updatedRule.getKey()).isEqualTo(rule.getKey().toString());
+    assertThat(updatedRule.getSysTags().getSysTagsList()).containsExactly(rule.getSystemTags().toArray(new String[0]));
+    assertThat(updatedRule.getTags().getTagsList()).containsExactly("tag2", "tag3");
+
+    // check database
+    RuleMetadataDto metadataOfSpecificOrg = dbTester.getDbClient().ruleDao().selectMetadataByKey(dbTester.getSession(), rule.getKey(), organization)
+      .orElseThrow(() -> new IllegalStateException("Cannot load metadata"));
+    assertThat(metadataOfSpecificOrg.getTags()).containsExactly("tag2", "tag3");
+  }
+
   @Test
   public void update_rule_remediation_function() throws IOException {
     doReturn("interpreted").when(macroInterpreter).interpret(anyString());
 
+    OrganizationDto organization = dbTester.organizations().insert();
+
     RuleDefinitionDto rule = dbTester.rules().insert(
       r -> r.setDefRemediationFunction(LINEAR.toString()),
       r -> r.setDefRemediationGapMultiplier("10d"),
@@ -111,6 +168,7 @@ public class UpdateActionTest {
     TestRequest request = actionTester.newRequest().setMethod("POST")
       .setMediaType(PROTOBUF)
       .setParam("key", rule.getKey().toString())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .setParam(PARAM_REMEDIATION_FN_TYPE, newOffset)
       .setParam(PARAM_REMEDIATION_FN_GAP_MULTIPLIER, newMultiplier)
       .setParam(PARAM_REMEDIATION_FN_BASE_EFFORT, newEffort);
@@ -129,6 +187,13 @@ public class UpdateActionTest {
     assertThat(updatedRule.getRemFnType()).isEqualTo(newOffset);
     assertThat(updatedRule.getRemFnGapMultiplier()).isEqualTo(newMultiplier);
     assertThat(updatedRule.getRemFnBaseEffort()).isEqualTo(newEffort);
+
+    // check database
+    RuleMetadataDto metadataOfSpecificOrg = dbTester.getDbClient().ruleDao().selectMetadataByKey(dbTester.getSession(), rule.getKey(), organization)
+      .orElseThrow(() -> new IllegalStateException("Cannot load metadata"));
+    assertThat(metadataOfSpecificOrg.getRemediationFunction()).isEqualTo(newOffset);
+    assertThat(metadataOfSpecificOrg.getRemediationGapMultiplier()).isEqualTo(newMultiplier);
+    assertThat(metadataOfSpecificOrg.getRemediationBaseEffort()).isEqualTo(newEffort);
   }
 
   @Test
index d375d6f5a2e316ad499a0bd2eb9183db412d5c65..ecf901ae233167f3610d07f01996fc635ab0b0aa 100644 (file)
@@ -9,11 +9,7 @@
     "internalKey": "InternalKeyS001",
     "isTemplate": false,
     "templateKey": "java:S001",
-    "tags": ["tag1", "tag2"],
     "sysTags": ["systag1", "systag2"],
-    "debtRemFnType": "LINEAR_OFFSET",
-    "debtRemFnCoeff": "5d",
-    "debtRemFnOffset": "10h",
     "lang": "js",
     "params": [
       {