aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins CI <ci@sonarsource.com>2014-12-30 15:57:03 +0100
committerJenkins CI <ci@sonarsource.com>2014-12-30 15:57:03 +0100
commite0ce33f0018ab3cbf2c6e4aa55f1f19502414296 (patch)
treeac6a7cd8f0db2ffc85476ba493ba2f6d294b933a
parente6bf968753bf2ec666aff3d802fa23c40ead8832 (diff)
parent5fdff45fc6e56b5240e619d296d9975a317b94ea (diff)
downloadsonarqube-e0ce33f0018ab3cbf2c6e4aa55f1f19502414296.tar.gz
sonarqube-e0ce33f0018ab3cbf2c6e4aa55f1f19502414296.zip
Automatic merge from branch-5.0
* origin/branch-5.0: SONAR-5849 Performance issue of Project Referentials WS for project with many modules SONAR-5849 Extract logic from ProjectReferentialsAction to ProjectReferentialsLoader
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java208
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsLoader.java273
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsQuery.java67
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java7
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java438
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsLoaderMediumTest.java701
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java22
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java35
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java20
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java14
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java6
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/not_returned_secured_settings_with_only_preview_permission.json18
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/project_referentials.json (renamed from server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_active_rules.json)7
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_settings.json19
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_settings.json24
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_settings_inherited_from_project.json23
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_with_sub_module.json29
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_two_modules.json28
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_provisioned_project_profile.json14
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profile_from_default_profile.json14
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profile_from_given_profile_name.json14
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profiles.json14
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profiles_even_when_project_does_not_exists.json14
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings.json20
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_including_settings_from_parent_modules.json20
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_inherited_from_project.json20
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_inherited_from_project_and_module.json20
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/modules.xml90
-rw-r--r--sonar-core/src/main/java/org/sonar/core/component/ProjectRefentialsComponentDto.java37
-rw-r--r--sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java8
-rw-r--r--sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java3
-rw-r--r--sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java5
-rw-r--r--sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java3
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml8
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml27
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml8
-rw-r--r--sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java17
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/select_children_module_properties.xml109
46 files changed, 1497 insertions, 950 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java
index 847393b0ec2..34a51d73aba 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java
@@ -20,41 +20,13 @@
package org.sonar.server.batch;
-import com.google.common.collect.Maps;
import org.apache.commons.io.IOUtils;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Languages;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.batch.protocol.input.ProjectReferentials;
-import org.sonar.core.UtcDateUtils;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.properties.PropertiesDao;
-import org.sonar.core.properties.PropertyDto;
-import org.sonar.core.qualityprofile.db.QualityProfileDto;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.plugins.MimeTypes;
-import org.sonar.server.qualityprofile.ActiveRule;
-import org.sonar.server.qualityprofile.QProfileFactory;
-import org.sonar.server.qualityprofile.QProfileLoader;
-import org.sonar.server.rule.Rule;
-import org.sonar.server.rule.RuleService;
-import org.sonar.server.user.UserSession;
-
-import javax.annotation.Nullable;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Maps.newHashMap;
public class ProjectReferentialsAction implements RequestHandler {
@@ -62,21 +34,10 @@ public class ProjectReferentialsAction implements RequestHandler {
private static final String PARAM_PROFILE = "profile";
private static final String PARAM_PREVIEW = "preview";
- private final DbClient dbClient;
- private final PropertiesDao propertiesDao;
- private final QProfileFactory qProfileFactory;
- private final QProfileLoader qProfileLoader;
- private final RuleService ruleService;
- private final Languages languages;
+ private final ProjectReferentialsLoader projectReferentialsLoader;
- public ProjectReferentialsAction(DbClient dbClient, PropertiesDao propertiesDao, QProfileFactory qProfileFactory, QProfileLoader qProfileLoader,
- RuleService ruleService, Languages languages) {
- this.dbClient = dbClient;
- this.propertiesDao = propertiesDao;
- this.qProfileFactory = qProfileFactory;
- this.qProfileLoader = qProfileLoader;
- this.ruleService = ruleService;
- this.languages = languages;
+ public ProjectReferentialsAction(ProjectReferentialsLoader projectReferentialsLoader) {
+ this.projectReferentialsLoader = projectReferentialsLoader;
}
void define(WebService.NewController controller) {
@@ -106,162 +67,11 @@ public class ProjectReferentialsAction implements RequestHandler {
@Override
public void handle(Request request, Response response) throws Exception {
- boolean hasScanPerm = UserSession.get().hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
- boolean preview = request.mandatoryParamAsBoolean(PARAM_PREVIEW);
- checkPermission(preview);
-
- DbSession session = dbClient.openSession(false);
- try {
- ProjectReferentials ref = new ProjectReferentials();
-
- String projectOrModuleKey = request.mandatoryParam(PARAM_KEY);
- String profileName = request.param(PARAM_PROFILE);
-
- String projectKey = null;
- ComponentDto module = dbClient.componentDao().getNullableByKey(session, projectOrModuleKey);
- // Current project can be null when analysing a new project
- if (module != null) {
- ComponentDto project = dbClient.componentDao().getNullableRootProjectByKey(projectOrModuleKey, session);
- // Can be null if the given project is a provisioned one
- if (project != null) {
- if (!project.key().equals(module.key())) {
- addSettings(ref, module.getKey(), getSettingsFromParents(module.key(), hasScanPerm, session));
- }
- projectKey = project.key();
- addSettingsToChildrenModules(ref, projectOrModuleKey, Maps.<String, String>newHashMap(), hasScanPerm, session);
- } else {
- // Add settings of the provisioned project
- addSettings(ref, projectOrModuleKey, getPropertiesMap(propertiesDao.selectProjectProperties(projectOrModuleKey, session), hasScanPerm));
- projectKey = projectOrModuleKey;
- }
- }
-
- addProfiles(ref, projectKey, profileName, session);
- addActiveRules(ref);
-
- response.stream().setMediaType(MimeTypes.JSON);
- IOUtils.write(ref.toJson(), response.stream().output());
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- private Map<String, String> getSettingsFromParents(String moduleKey, boolean hasScanPerm, DbSession session) {
- List<ComponentDto> parents = newArrayList();
- aggregateParentModules(moduleKey, parents, session);
- Collections.reverse(parents);
-
- Map<String, String> parentProperties = newHashMap();
- for (ComponentDto parent : parents) {
- parentProperties.putAll(getPropertiesMap(propertiesDao.selectProjectProperties(parent.key(), session), hasScanPerm));
- }
- return parentProperties;
- }
-
- private void aggregateParentModules(String component, List<ComponentDto> parents, DbSession session){
- ComponentDto parent = dbClient.componentDao().getParentModuleByKey(component, session);
- if (parent != null) {
- parents.add(parent);
- aggregateParentModules(parent.key(), parents, session);
- }
- }
-
- private void addSettingsToChildrenModules(ProjectReferentials ref, String projectKey, Map<String, String> parentProperties, boolean hasScanPerm, DbSession session) {
- Map<String, String> currentParentProperties = newHashMap();
- currentParentProperties.putAll(parentProperties);
- currentParentProperties.putAll(getPropertiesMap(propertiesDao.selectProjectProperties(projectKey, session), hasScanPerm));
- addSettings(ref, projectKey, currentParentProperties);
-
- for (ComponentDto module : dbClient.componentDao().findModulesByProject(projectKey, session)) {
- addSettings(ref, module.key(), currentParentProperties);
- addSettingsToChildrenModules(ref, module.key(), currentParentProperties, hasScanPerm, session);
- }
+ ProjectReferentials ref = projectReferentialsLoader.load(ProjectReferentialsQuery.create()
+ .setModuleKey(request.mandatoryParam(PARAM_KEY))
+ .setProfileName(request.param(PARAM_PROFILE))
+ .setPreview(request.mandatoryParamAsBoolean(PARAM_PREVIEW)));
+ response.stream().setMediaType(MimeTypes.JSON);
+ IOUtils.write(ref.toJson(), response.stream().output());
}
-
- private void addSettings(ProjectReferentials ref, String module, Map<String, String> properties) {
- if (!properties.isEmpty()) {
- ref.addSettings(module, properties);
- }
- }
-
- private Map<String, String> getPropertiesMap(List<PropertyDto> propertyDtos, boolean hasScanPerm) {
- Map<String, String> properties = newHashMap();
- for (PropertyDto propertyDto : propertyDtos) {
- String key = propertyDto.getKey();
- String value = propertyDto.getValue();
- if (isPropertyAllowed(key, hasScanPerm)) {
- properties.put(key, value);
- }
- }
- return properties;
- }
-
- private static boolean isPropertyAllowed(String key, boolean hasScanPerm) {
- return !key.contains(".secured") || hasScanPerm;
- }
-
- private void addProfiles(ProjectReferentials ref, @Nullable String projectKey, @Nullable String profileName, DbSession session) {
- for (Language language : languages.all()) {
- String languageKey = language.getKey();
- QualityProfileDto qualityProfileDto = getProfile(languageKey, projectKey, profileName, session);
- ref.addQProfile(new org.sonar.batch.protocol.input.QProfile(
- qualityProfileDto.getKey(),
- qualityProfileDto.getName(),
- qualityProfileDto.getLanguage(),
- UtcDateUtils.parseDateTime(qualityProfileDto.getRulesUpdatedAt())));
- }
- }
-
- /**
- * First try to find a quality profile matching the given name (if provided) and current language
- * If no profile found, try to find the quality profile set on the project (if provided)
- * If still no profile found, try to find the default profile of the language
- *
- * Never return null because a default profile should always be set on ech language
- */
- private QualityProfileDto getProfile(String languageKey, @Nullable String projectKey, @Nullable String profileName, DbSession session) {
- QualityProfileDto qualityProfileDto = profileName != null ? qProfileFactory.getByNameAndLanguage(session, profileName, languageKey) : null;
- if (qualityProfileDto == null && projectKey != null) {
- qualityProfileDto = qProfileFactory.getByProjectAndLanguage(session, projectKey, languageKey);
- }
- qualityProfileDto = qualityProfileDto != null ? qualityProfileDto : qProfileFactory.getDefault(session, languageKey);
- if (qualityProfileDto != null) {
- return qualityProfileDto;
- } else {
- throw new IllegalStateException(String.format("No quality profile can been found on language '%s' for project '%s'", languageKey, projectKey));
- }
- }
-
- private void addActiveRules(ProjectReferentials ref) {
- for (org.sonar.batch.protocol.input.QProfile qProfile : ref.qProfiles()) {
- for (ActiveRule activeRule : qProfileLoader.findActiveRulesByProfile(qProfile.key())) {
- Rule rule = ruleService.getNonNullByKey(activeRule.key().ruleKey());
- org.sonar.batch.protocol.input.ActiveRule inputActiveRule = new org.sonar.batch.protocol.input.ActiveRule(
- activeRule.key().ruleKey().repository(),
- activeRule.key().ruleKey().rule(),
- rule.name(),
- activeRule.severity(),
- rule.internalKey(),
- qProfile.language());
- for (Map.Entry<String, String> entry : activeRule.params().entrySet()) {
- inputActiveRule.addParam(entry.getKey(), entry.getValue());
- }
- ref.addActiveRule(inputActiveRule);
- }
- }
- }
-
- private void checkPermission(boolean preview){
- UserSession userSession = UserSession.get();
- boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
- boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.DRY_RUN_EXECUTION);
- if (!hasPreviewPerm && !hasScanPerm) {
- throw new ForbiddenException("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
- }
- if (!preview && !hasScanPerm) {
- throw new ForbiddenException("You're only authorized to execute a local (dry run) SonarQube analysis without pushing the results to the SonarQube server. " +
- "Please contact your SonarQube administrator.");
- }
- }
-
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsLoader.java
new file mode 100644
index 00000000000..dbff7696929
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsLoader.java
@@ -0,0 +1,273 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.batch;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.resources.Language;
+import org.sonar.api.resources.Languages;
+import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.core.UtcDateUtils;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ProjectRefentialsComponentDto;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.properties.PropertyDto;
+import org.sonar.core.qualityprofile.db.QualityProfileDto;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.qualityprofile.ActiveRule;
+import org.sonar.server.qualityprofile.QProfileFactory;
+import org.sonar.server.qualityprofile.QProfileLoader;
+import org.sonar.server.rule.Rule;
+import org.sonar.server.rule.RuleService;
+import org.sonar.server.user.UserSession;
+
+import javax.annotation.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
+
+public class ProjectReferentialsLoader implements ServerComponent {
+
+ private final DbClient dbClient;
+ private final QProfileFactory qProfileFactory;
+ private final QProfileLoader qProfileLoader;
+ private final RuleService ruleService;
+ private final Languages languages;
+
+ public ProjectReferentialsLoader(DbClient dbClient, QProfileFactory qProfileFactory, QProfileLoader qProfileLoader, RuleService ruleService,
+ Languages languages) {
+ this.dbClient = dbClient;
+ this.qProfileFactory = qProfileFactory;
+ this.qProfileLoader = qProfileLoader;
+ this.ruleService = ruleService;
+ this.languages = languages;
+ }
+
+ public ProjectReferentials load(ProjectReferentialsQuery query) {
+ boolean hasScanPerm = UserSession.get().hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
+ checkPermission(query.isPreview());
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ ProjectReferentials ref = new ProjectReferentials();
+ String projectKey = query.getModuleKey();
+ ComponentDto module = dbClient.componentDao().getNullableByKey(session, query.getModuleKey());
+ // Current project/module can be null when analysing a new project
+ if (module != null) {
+ ComponentDto project = dbClient.componentDao().getNullableRootProjectByKey(query.getModuleKey(), session);
+
+ // Can be null if the given project is a provisioned one
+ if (project != null) {
+ if (!project.key().equals(module.key())) {
+ addSettings(ref, module.getKey(), getSettingsFromParents(module.key(), hasScanPerm, session));
+ projectKey = project.key();
+ }
+
+ List<PropertyDto> moduleSettings = dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session);
+ List<ProjectRefentialsComponentDto> moduleChildren = dbClient.componentDao().findChildrenModulesFromModule(session, query.getModuleKey());
+ List<PropertyDto> moduleChildrenSettings = newArrayList();
+ if (!moduleChildren.isEmpty()) {
+ moduleChildrenSettings = dbClient.propertiesDao().findChildrenModuleProperties(query.getModuleKey(), session);
+ }
+ TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleChildren, moduleChildrenSettings, module, moduleSettings);
+
+ addSettingsToChildrenModules(ref, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm, session);
+ } else {
+ // Add settings of the provisioned project
+ addSettings(ref, query.getModuleKey(), getPropertiesMap(dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session), hasScanPerm));
+ }
+ }
+
+ addProfiles(ref, projectKey, query.getProfileName(), session);
+ addActiveRules(ref);
+ return ref;
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ private Map<String, String> getSettingsFromParents(String moduleKey, boolean hasScanPerm, DbSession session) {
+ List<ComponentDto> parents = newArrayList();
+ aggregateParentModules(moduleKey, parents, session);
+ Collections.reverse(parents);
+
+ Map<String, String> parentProperties = newHashMap();
+ for (ComponentDto parent : parents) {
+ parentProperties.putAll(getPropertiesMap(dbClient.propertiesDao().selectProjectProperties(parent.key(), session), hasScanPerm));
+ }
+ return parentProperties;
+ }
+
+ private void aggregateParentModules(String component, List<ComponentDto> parents, DbSession session) {
+ ComponentDto parent = dbClient.componentDao().getParentModuleByKey(component, session);
+ if (parent != null) {
+ parents.add(parent);
+ aggregateParentModules(parent.key(), parents, session);
+ }
+ }
+
+ private void addSettingsToChildrenModules(ProjectReferentials ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings,
+ boolean hasScanPerm, DbSession session) {
+ Map<String, String> currentParentProperties = newHashMap();
+ currentParentProperties.putAll(parentProperties);
+ currentParentProperties.putAll(getPropertiesMap(treeModuleSettings.findModuleSettings(moduleKey), hasScanPerm));
+ addSettings(ref, moduleKey, currentParentProperties);
+
+ for (ComponentDto childModule : treeModuleSettings.findChildrenModule(moduleKey)) {
+ addSettings(ref, childModule.getKey(), currentParentProperties);
+ addSettingsToChildrenModules(ref, childModule.getKey(), currentParentProperties, treeModuleSettings, hasScanPerm, session);
+ }
+ }
+
+ private void addSettings(ProjectReferentials ref, String module, Map<String, String> properties) {
+ if (!properties.isEmpty()) {
+ ref.addSettings(module, properties);
+ }
+ }
+
+ private Map<String, String> getPropertiesMap(List<? extends PropertyDto> propertyDtos, boolean hasScanPerm) {
+ Map<String, String> properties = newHashMap();
+ for (PropertyDto propertyDto : propertyDtos) {
+ String key = propertyDto.getKey();
+ String value = propertyDto.getValue();
+ if (isPropertyAllowed(key, hasScanPerm)) {
+ properties.put(key, value);
+ }
+ }
+ return properties;
+ }
+
+ private static boolean isPropertyAllowed(String key, boolean hasScanPerm) {
+ return !key.contains(".secured") || hasScanPerm;
+ }
+
+ private void addProfiles(ProjectReferentials ref, @Nullable String projectKey, @Nullable String profileName, DbSession session) {
+ for (Language language : languages.all()) {
+ String languageKey = language.getKey();
+ QualityProfileDto qualityProfileDto = getProfile(languageKey, projectKey, profileName, session);
+ ref.addQProfile(new org.sonar.batch.protocol.input.QProfile(
+ qualityProfileDto.getKey(),
+ qualityProfileDto.getName(),
+ qualityProfileDto.getLanguage(),
+ UtcDateUtils.parseDateTime(qualityProfileDto.getRulesUpdatedAt())));
+ }
+ }
+
+ /**
+ * First try to find a quality profile matching the given name (if provided) and current language
+ * If no profile found, try to find the quality profile set on the project (if provided)
+ * If still no profile found, try to find the default profile of the language
+ * <p/>
+ * Never return null because a default profile should always be set on ech language
+ */
+ private QualityProfileDto getProfile(String languageKey, @Nullable String projectKey, @Nullable String profileName, DbSession session) {
+ QualityProfileDto qualityProfileDto = profileName != null ? qProfileFactory.getByNameAndLanguage(session, profileName, languageKey) : null;
+ if (qualityProfileDto == null && projectKey != null) {
+ qualityProfileDto = qProfileFactory.getByProjectAndLanguage(session, projectKey, languageKey);
+ }
+ qualityProfileDto = qualityProfileDto != null ? qualityProfileDto : qProfileFactory.getDefault(session, languageKey);
+ if (qualityProfileDto != null) {
+ return qualityProfileDto;
+ } else {
+ throw new IllegalStateException(String.format("No quality profile can been found on language '%s' for project '%s'", languageKey, projectKey));
+ }
+ }
+
+ private void addActiveRules(ProjectReferentials ref) {
+ for (org.sonar.batch.protocol.input.QProfile qProfile : ref.qProfiles()) {
+ for (ActiveRule activeRule : qProfileLoader.findActiveRulesByProfile(qProfile.key())) {
+ Rule rule = ruleService.getNonNullByKey(activeRule.key().ruleKey());
+ org.sonar.batch.protocol.input.ActiveRule inputActiveRule = new org.sonar.batch.protocol.input.ActiveRule(
+ activeRule.key().ruleKey().repository(),
+ activeRule.key().ruleKey().rule(),
+ rule.name(),
+ activeRule.severity(),
+ rule.internalKey(),
+ qProfile.language());
+ for (Map.Entry<String, String> entry : activeRule.params().entrySet()) {
+ inputActiveRule.addParam(entry.getKey(), entry.getValue());
+ }
+ ref.addActiveRule(inputActiveRule);
+ }
+ }
+ }
+
+ private void checkPermission(boolean preview) {
+ UserSession userSession = UserSession.get();
+ boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
+ boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.DRY_RUN_EXECUTION);
+ if (!hasPreviewPerm && !hasScanPerm) {
+ throw new ForbiddenException("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
+ }
+ if (!preview && !hasScanPerm) {
+ throw new ForbiddenException("You're only authorized to execute a local (dry run) SonarQube analysis without pushing the results to the SonarQube server. " +
+ "Please contact your SonarQube administrator.");
+ }
+ }
+
+ private static class TreeModuleSettings {
+
+ private Map<String, Long> moduleIdsByKey;
+ private Multimap<Long, PropertyDto> propertiesByModuleId;
+ private Multimap<String, ProjectRefentialsComponentDto> moduleChildrenByModuleKey;
+
+ private TreeModuleSettings(List<ProjectRefentialsComponentDto> moduleChildren, List<PropertyDto> moduleChildrenSettings, ComponentDto module, List<PropertyDto> moduleSettings) {
+ propertiesByModuleId = ArrayListMultimap.create();
+ for (PropertyDto settings : moduleChildrenSettings) {
+ propertiesByModuleId.put(settings.getResourceId(), settings);
+ }
+ propertiesByModuleId.putAll(module.getId(), moduleSettings);
+ moduleIdsByKey = newHashMap();
+ for (ProjectRefentialsComponentDto componentDto : moduleChildren) {
+ moduleIdsByKey.put(componentDto.key(), componentDto.getId());
+ }
+ moduleIdsByKey.put(module.key(), module.getId());
+ moduleChildrenByModuleKey = ArrayListMultimap.create();
+ for (ProjectRefentialsComponentDto componentDto : moduleChildren) {
+ String parentModuleKey = componentDto.getParentModuleKey();
+ if (parentModuleKey != null) {
+ moduleChildrenByModuleKey.put(parentModuleKey, componentDto);
+ } else {
+ moduleChildrenByModuleKey.put(module.key(), componentDto);
+ }
+ }
+ }
+
+ private List<PropertyDto> findModuleSettings(String moduleKey) {
+ Long moduleId = moduleIdsByKey.get(moduleKey);
+ return newArrayList(propertiesByModuleId.get(moduleId));
+ }
+
+ private List<? extends ComponentDto> findChildrenModule(String moduleKey) {
+ return newArrayList(moduleChildrenByModuleKey.get(moduleKey));
+ }
+
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsQuery.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsQuery.java
new file mode 100644
index 00000000000..301e2b0862d
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsQuery.java
@@ -0,0 +1,67 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.batch;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class ProjectReferentialsQuery {
+
+ private String projectOrModuleKey;
+ private String profileName;
+ private boolean preview;
+
+ private ProjectReferentialsQuery() {
+ // No direct call
+ }
+
+ public boolean isPreview() {
+ return preview;
+ }
+
+ public ProjectReferentialsQuery setPreview(boolean preview) {
+ this.preview = preview;
+ return this;
+ }
+
+ @CheckForNull
+ public String getProfileName() {
+ return profileName;
+ }
+
+ public ProjectReferentialsQuery setProfileName(@Nullable String profileName) {
+ this.profileName = profileName;
+ return this;
+ }
+
+ public String getModuleKey() {
+ return projectOrModuleKey;
+ }
+
+ public ProjectReferentialsQuery setModuleKey(String projectOrModuleKey) {
+ this.projectOrModuleKey = projectOrModuleKey;
+ return this;
+ }
+
+ public static ProjectReferentialsQuery create(){
+ return new ProjectReferentialsQuery();
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java b/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java
index c9e7f27e771..69e3ec3dfa8 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java
@@ -17,12 +17,14 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
package org.sonar.server.component.db;
import com.google.common.collect.Lists;
import org.sonar.api.ServerComponent;
import org.sonar.api.utils.System2;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ProjectRefentialsComponentDto;
import org.sonar.core.component.db.ComponentMapper;
import org.sonar.core.persistence.DaoComponent;
import org.sonar.core.persistence.DbSession;
@@ -113,6 +115,10 @@ public class ComponentDao extends BaseDao<ComponentMapper, ComponentDto, String>
return mapper(session).findSubProjectsByComponentUuids(keys);
}
+ public List<ProjectRefentialsComponentDto> findChildrenModulesFromModule(DbSession session, String moduleKey) {
+ return mapper(session).findChildrenModulesFromModule(moduleKey);
+ }
+
public List<ComponentDto> getByUuids(DbSession session, Collection<String> uuids) {
if (uuids.isEmpty()) {
return Collections.emptyList();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java b/server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java
index 5379396bcae..213467f8903 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java
@@ -66,6 +66,13 @@ public class SnapshotDao extends BaseDao<SnapshotMapper, SnapshotDto, Long> impl
return mapper(session).selectSnapshotAndChildrenOfScope(snapshot.getId(), Scopes.PROJECT);
}
+ /**
+ * Return all snapshots children (not returning itself) from a module key
+ */
+ public List<SnapshotDto> findChildrenModulesFromModule(DbSession session, String moduleKey) {
+ return mapper(session).selectChildrenModulesFromModule(moduleKey);
+ }
+
public int updateSnapshotAndChildrenLastFlagAndStatus(DbSession session, SnapshotDto snapshot, boolean isLast, String status) {
Long rootId = snapshot.getId();
String path = snapshot.getPath() + snapshot.getId() + ".%";
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
index 374b8174cc6..1b9ac67a02b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
@@ -354,6 +354,7 @@ class ServerComponents {
pico.addSingleton(BatchIndex.class);
pico.addSingleton(GlobalReferentialsAction.class);
pico.addSingleton(ProjectReferentialsAction.class);
+ pico.addSingleton(ProjectReferentialsLoader.class);
pico.addSingleton(UploadReportAction.class);
pico.addSingleton(BatchWs.class);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java
index bf762d18a7a..48add354214 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java
@@ -28,14 +28,10 @@ import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.resources.Languages;
import org.sonar.core.properties.PropertiesDao;
import org.sonar.server.computation.AnalysisReportQueue;
import org.sonar.server.computation.AnalysisReportTaskLauncher;
import org.sonar.server.db.DbClient;
-import org.sonar.server.qualityprofile.QProfileFactory;
-import org.sonar.server.qualityprofile.QProfileLoader;
-import org.sonar.server.rule.RuleService;
import org.sonar.server.ws.WsTester;
import java.io.File;
@@ -63,8 +59,7 @@ public class BatchWsTest {
public void before() throws IOException {
tester = new WsTester(new BatchWs(batchIndex,
new GlobalReferentialsAction(mock(DbClient.class), mock(PropertiesDao.class)),
- new ProjectReferentialsAction(mock(DbClient.class), mock(PropertiesDao.class), mock(QProfileFactory.class), mock(QProfileLoader.class), mock(RuleService.class),
- mock(Languages.class)),
+ new ProjectReferentialsAction(mock(ProjectReferentialsLoader.class)),
new UploadReportAction(mock(AnalysisReportQueue.class), mock(AnalysisReportTaskLauncher.class))));
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java
index 0f6972c1ab6..d9114192c76 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java
@@ -20,38 +20,15 @@
package org.sonar.server.batch;
-import com.google.common.collect.ImmutableMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.Severity;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.properties.PropertiesDao;
-import org.sonar.core.properties.PropertyDto;
-import org.sonar.core.qualityprofile.db.ActiveRuleKey;
-import org.sonar.core.qualityprofile.db.QualityProfileDto;
-import org.sonar.server.component.db.ComponentDao;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.qualityprofile.ActiveRule;
-import org.sonar.server.qualityprofile.QProfileFactory;
-import org.sonar.server.qualityprofile.QProfileLoader;
-import org.sonar.server.rule.Rule;
-import org.sonar.server.rule.RuleService;
-import org.sonar.server.user.MockUserSession;
+import org.sonar.batch.protocol.input.ProjectReferentials;
import org.sonar.server.ws.WsTester;
-import java.util.Collections;
-
-import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -60,416 +37,35 @@ import static org.mockito.Mockito.when;
public class ProjectReferentialsActionTest {
@Mock
- DbSession session;
-
- @Mock
- ComponentDao componentDao;
-
- @Mock
- PropertiesDao propertiesDao;
-
- @Mock
- QProfileFactory qProfileFactory;
-
- @Mock
- QProfileLoader qProfileLoader;
-
- @Mock
- RuleService ruleService;
-
- @Mock
- Languages languages;
-
- @Mock
- Language language;
+ ProjectReferentialsLoader projectReferentialsLoader;
WsTester tester;
- ComponentDto project;
- ComponentDto module;
- ComponentDto subModule;
-
@Before
public void setUp() throws Exception {
- DbClient dbClient = mock(DbClient.class);
- when(dbClient.openSession(false)).thenReturn(session);
- when(dbClient.componentDao()).thenReturn(componentDao);
-
- project = new ComponentDto().setKey("org.codehaus.sonar:sonar").setQualifier(Qualifiers.PROJECT);
- module = new ComponentDto().setKey("org.codehaus.sonar:sonar-server").setQualifier(Qualifiers.MODULE);
- subModule = new ComponentDto().setKey("org.codehaus.sonar:sonar-server-dao").setQualifier(Qualifiers.MODULE);
-
- when(componentDao.getNullableByKey(session, project.key())).thenReturn(project);
- when(componentDao.getNullableByKey(session, module.key())).thenReturn(module);
- when(componentDao.getNullableByKey(session, subModule.key())).thenReturn(subModule);
-
- when(language.getKey()).thenReturn("java");
- when(languages.all()).thenReturn(new Language[] {language});
-
- when(qProfileFactory.getDefault(session, "java")).thenReturn(
- QualityProfileDto.createFor("abcd").setName("Default").setLanguage("java").setRulesUpdatedAt("2014-01-14T14:00:00+0200")
- );
-
tester = new WsTester(new BatchWs(mock(BatchIndex.class), mock(GlobalReferentialsAction.class),
- new ProjectReferentialsAction(dbClient, propertiesDao, qProfileFactory, qProfileLoader, ruleService, languages), mock(UploadReportAction.class)));
- }
-
- @Test
- public void return_project_settings() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- // Project without modules
- when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project);
- when(componentDao.findModulesByProject(project.key(), session)).thenReturn(Collections.<ComponentDto>emptyList());
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john")
- ));
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key());
- request.execute().assertJson(getClass(), "return_project_settings.json");
- }
-
- @Test
- public void not_returned_secured_settings_with_only_preview_permission() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION);
-
- // Project without modules
- when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project);
- when(componentDao.findModulesByProject(project.key(), session)).thenReturn(Collections.<ComponentDto>emptyList());
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john")
- ));
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key()).setParam("preview", "true");
- request.execute().assertJson(getClass(), "not_returned_secured_settings_with_only_preview_permission.json");
- }
-
- @Test
- public void return_project_with_module_settings() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project);
- when(componentDao.findModulesByProject(project.key(), session)).thenReturn(newArrayList(module));
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john")
- ));
-
- when(propertiesDao.selectProjectProperties(module.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER"),
- new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java")
- ));
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key());
- request.execute().assertJson(getClass(), "return_project_with_module_settings.json");
- }
-
- @Test
- public void return_project_with_module_settings_inherited_from_project() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project);
- when(componentDao.findModulesByProject(project.key(), session)).thenReturn(newArrayList(module));
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john")
- ));
- // No property on module -> should have the same than project
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key());
- request.execute().assertJson(getClass(), "return_project_with_module_settings_inherited_from_project.json");
- }
-
- @Test
- public void return_project_with_module_with_sub_module() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project);
- when(componentDao.findModulesByProject(project.key(), session)).thenReturn(newArrayList(module));
- when(componentDao.findModulesByProject(module.key(), session)).thenReturn(newArrayList(subModule));
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john")
- ));
-
- when(propertiesDao.selectProjectProperties(module.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER"),
- new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java")
- ));
-
- when(propertiesDao.selectProjectProperties(subModule.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER-DAO")
- ));
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key());
- request.execute().assertJson(getClass(), "return_project_with_module_with_sub_module.json");
- }
-
- @Test
- public void return_project_with_two_modules() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- ComponentDto module2 = new ComponentDto().setKey("org.codehaus.sonar:sonar-application").setQualifier(Qualifiers.MODULE);
-
- when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project);
- when(componentDao.findModulesByProject(project.key(), session)).thenReturn(newArrayList(module, module2));
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john")
- ));
-
- when(propertiesDao.selectProjectProperties(module.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER"),
- // This property should not be found on the other module
- new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java")
- ));
-
- when(propertiesDao.selectProjectProperties(module2.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION")
- ));
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key());
- request.execute().assertJson(getClass(), "return_project_with_two_modules.json");
- }
-
- @Test
- public void return_provisioned_project_settings() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- // No root project will be found on provisioned project
- when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(null);
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john")
- ));
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key());
- request.execute().assertJson(getClass(), "return_project_settings.json");
- }
-
- @Test
- public void return_provisioned_project_profile() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- // No root project will be found on provisioned project
- when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(null);
-
- when(qProfileFactory.getByProjectAndLanguage(session, project.key(), "java")).thenReturn(
- QualityProfileDto.createFor("abcd").setName("SonarQube way").setLanguage("java").setRulesUpdatedAt("2014-01-14T14:00:00+0200")
- );
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key());
- request.execute().assertJson(getClass(), "return_provisioned_project_profile.json");
- }
-
- @Test
- public void return_sub_module_settings() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- when(componentDao.getNullableRootProjectByKey(subModule.key(), session)).thenReturn(project);
- when(componentDao.getParentModuleByKey(module.key(), session)).thenReturn(project);
- when(componentDao.getParentModuleByKey(subModule.key(), session)).thenReturn(module);
-
- when(propertiesDao.selectProjectProperties(subModule.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john"),
- new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java")
- ));
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", subModule.key());
- request.execute().assertJson(getClass(), "return_sub_module_settings.json");
- }
-
- @Test
- public void return_sub_module_settings_including_settings_from_parent_modules() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- when(componentDao.getNullableRootProjectByKey(subModule.key(), session)).thenReturn(project);
- when(componentDao.getParentModuleByKey(module.key(), session)).thenReturn(project);
- when(componentDao.getParentModuleByKey(subModule.key(), session)).thenReturn(module);
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR")
- ));
-
- when(propertiesDao.selectProjectProperties(module.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john")
- ));
-
- when(propertiesDao.selectProjectProperties(subModule.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java")
- ));
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", subModule.key());
- request.execute().assertJson(getClass(), "return_sub_module_settings_including_settings_from_parent_modules.json");
- }
-
- @Test
- public void return_sub_module_settings_only_inherited_from_project() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- when(componentDao.getNullableRootProjectByKey(subModule.key(), session)).thenReturn(project);
- when(componentDao.getParentModuleByKey(module.key(), session)).thenReturn(project);
- when(componentDao.getParentModuleByKey(subModule.key(), session)).thenReturn(module);
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"),
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john"),
- new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java")
- ));
- // No settings on module or sub module -> All setting should come from the project
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", subModule.key());
- request.execute().assertJson(getClass(), "return_sub_module_settings_inherited_from_project.json");
- }
-
- @Test
- public void return_sub_module_settings_inherited_from_project_and_module() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- when(componentDao.getNullableRootProjectByKey(subModule.key(), session)).thenReturn(project);
- when(componentDao.getParentModuleByKey(module.key(), session)).thenReturn(project);
- when(componentDao.getParentModuleByKey(subModule.key(), session)).thenReturn(module);
-
- when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.login.secured").setValue("john"),
- new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java")
- ));
-
- when(propertiesDao.selectProjectProperties(module.key(), session)).thenReturn(newArrayList(
- new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER")
- ));
-
- // No settings on sub module -> All setting should come from the project and the module
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", subModule.key());
- request.execute().assertJson(getClass(), "return_sub_module_settings_inherited_from_project_and_module.json");
- }
-
- @Test
- public void return_quality_profiles() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
- String projectKey = "org.codehaus.sonar:sonar";
-
- when(qProfileFactory.getByProjectAndLanguage(session, projectKey, "java")).thenReturn(
- QualityProfileDto.createFor("abcd").setName("SonarQube way").setLanguage("java").setRulesUpdatedAt("2014-01-14T14:00:00+0200")
- );
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", projectKey);
- request.execute().assertJson(getClass(), "return_quality_profiles.json");
- }
-
- @Test
- public void fail_when_quality_profile_for_a_language() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", "org.codehaus.sonar:sonar");
-
- try {
- request.execute();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("No quality profile can been found on language 'java' for project 'org.codehaus.sonar:sonar'");
- }
+ new ProjectReferentialsAction(projectReferentialsLoader), mock(UploadReportAction.class)));
}
@Test
- public void return_quality_profile_from_default_profile() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ public void project_referentials() throws Exception {
String projectKey = "org.codehaus.sonar:sonar";
- when(qProfileFactory.getDefault(session, "java")).thenReturn(
- QualityProfileDto.createFor("abcd").setName("Default").setLanguage("java").setRulesUpdatedAt("2014-01-14T14:00:00+0200")
- );
+ ProjectReferentials projectReferentials = mock(ProjectReferentials.class);
+ when(projectReferentials.toJson()).thenReturn("{\"settingsByModule\": {}}");
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", projectKey);
- request.execute().assertJson(getClass(), "return_quality_profile_from_default_profile.json");
- }
-
- @Test
- public void return_quality_profile_from_given_profile_name() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
- String projectKey = "org.codehaus.sonar:sonar";
-
- when(qProfileFactory.getByNameAndLanguage(session, "Default", "java")).thenReturn(
- QualityProfileDto.createFor("abcd").setName("Default").setLanguage("java").setRulesUpdatedAt("2014-01-14T14:00:00+0200")
- );
+ ArgumentCaptor<ProjectReferentialsQuery> queryArgumentCaptor = ArgumentCaptor.forClass(ProjectReferentialsQuery.class);
+ when(projectReferentialsLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials);
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", projectKey).setParam("profile", "Default");
- request.execute().assertJson(getClass(), "return_quality_profile_from_given_profile_name.json");
- }
-
- @Test
- public void return_quality_profiles_even_when_project_does_not_exists() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
- String projectKey = "org.codehaus.sonar:sonar";
- when(componentDao.getNullableByKey(session, projectKey)).thenReturn(null);
-
- when(qProfileFactory.getDefault(session, "java")).thenReturn(
- QualityProfileDto.createFor("abcd").setName("Default").setLanguage("java").setRulesUpdatedAt("2014-01-14T14:00:00+0200")
- );
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", projectKey);
- request.execute().assertJson(getClass(), "return_quality_profiles_even_when_project_does_not_exists.json");
- }
-
- @Test
- public void return_active_rules() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
- String projectKey = "org.codehaus.sonar:sonar";
-
- when(qProfileFactory.getByProjectAndLanguage(session, projectKey, "java")).thenReturn(
- QualityProfileDto.createFor("abcd").setName("Default").setLanguage("java").setRulesUpdatedAt("2014-01-14T14:00:00+0200")
- );
-
- RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
- ActiveRule activeRule = mock(ActiveRule.class);
- when(activeRule.key()).thenReturn(ActiveRuleKey.of("abcd", ruleKey));
- when(activeRule.severity()).thenReturn(Severity.MINOR);
- when(activeRule.params()).thenReturn(ImmutableMap.of("max", "2"));
- when(qProfileLoader.findActiveRulesByProfile("abcd")).thenReturn(newArrayList(activeRule));
-
- Rule rule = mock(Rule.class);
- when(rule.name()).thenReturn("Avoid Cycle");
- when(rule.internalKey()).thenReturn("squid-1");
- when(ruleService.getNonNullByKey(ruleKey)).thenReturn(rule);
-
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", projectKey);
- request.execute().assertJson(getClass(), "return_active_rules.json");
- }
-
- @Test
- public void fail_if_no_permission() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions();
-
- try {
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key());
- request.execute();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
- }
- }
-
- @Test
- public void fail_when_not_preview_and_only_dry_run_permission() throws Exception {
- MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION);
+ WsTester.TestRequest request = tester.newGetRequest("batch", "project")
+ .setParam("key", projectKey)
+ .setParam("profile", "Default")
+ .setParam("preview", "false");
+ request.execute().assertJson("{\"settingsByModule\": {}}");
- try {
- WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key()).setParam("preview", "false");
- request.execute();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage(
- "You're only authorized to execute a local (dry run) SonarQube analysis without pushing the results to the SonarQube server. " +
- "Please contact your SonarQube administrator.");
- }
+ assertThat(queryArgumentCaptor.getValue().getModuleKey()).isEqualTo(projectKey);
+ assertThat(queryArgumentCaptor.getValue().getProfileName()).isEqualTo("Default");
+ assertThat(queryArgumentCaptor.getValue().isPreview()).isFalse();
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsLoaderMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsLoaderMediumTest.java
new file mode 100644
index 00000000000..3eae77a6be7
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsLoaderMediumTest.java
@@ -0,0 +1,701 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.batch;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.rule.RuleParamType;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.batch.protocol.input.ActiveRule;
+import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.QProfile;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.SnapshotDto;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.properties.PropertyDto;
+import org.sonar.core.qualityprofile.db.QualityProfileDto;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.core.rule.RuleParamDto;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.component.SnapshotTesting;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.qualityprofile.QProfileName;
+import org.sonar.server.qualityprofile.QProfileTesting;
+import org.sonar.server.qualityprofile.RuleActivation;
+import org.sonar.server.qualityprofile.RuleActivator;
+import org.sonar.server.rule.RuleTesting;
+import org.sonar.server.tester.ServerTester;
+import org.sonar.server.user.MockUserSession;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+
+public class ProjectReferentialsLoaderMediumTest {
+
+ @ClassRule
+ public static ServerTester tester = new ServerTester().addXoo();
+
+ DbSession dbSession;
+
+ ProjectReferentialsLoader loader;
+
+ @Before
+ public void before() {
+ tester.clearDbAndIndexes();
+ dbSession = tester.get(DbClient.class).openSession(false);
+ loader = tester.get(ProjectReferentialsLoader.class);
+ }
+
+ @After
+ public void after() {
+ dbSession.close();
+ }
+
+ @Test
+ public void return_project_settings() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project));
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()),
+ dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()),
+ dbSession);
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ Map<String, String> projectSettings = ref.settings(project.key());
+ assertThat(projectSettings).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john"
+ ));
+ }
+
+ @Test
+ public void not_returned_secured_settings_with_only_preview_permission() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project));
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()),
+ dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()),
+ dbSession);
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()).setPreview(true));
+ Map<String, String> projectSettings = ref.settings(project.key());
+ assertThat(projectSettings).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR"
+ ));
+ }
+
+ @Test
+ public void return_project_with_module_settings() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
+
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(module, project, projectSnapshot));
+
+ // Module properties
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john"
+ ));
+ assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR-SERVER",
+ "sonar.jira.login.secured", "john",
+ "sonar.coverage.exclusions", "**/*.java"
+ ));
+ }
+
+ @Test
+ public void return_project_with_module_settings_inherited_from_project() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
+
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(module, project, projectSnapshot));
+
+ // No property on module -> should have the same as project
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john"
+ ));
+ assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john"
+ ));
+ }
+
+ @Test
+ public void return_project_with_module_with_sub_module() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
+
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module);
+ SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, project, projectSnapshot);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, moduleSnapshot);
+
+ // Module properties
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()), dbSession);
+
+ ComponentDto subModule = ComponentTesting.newModuleDto(module);
+ tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(subModule, module, moduleSnapshot));
+
+ // Sub module properties
+ tester.get(DbClient.class).propertiesDao().setProperty(
+ new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER-DAO").setResourceId(subModule.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john"
+ ));
+ assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR-SERVER",
+ "sonar.jira.login.secured", "john",
+ "sonar.coverage.exclusions", "**/*.java"
+ ));
+ assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR-SERVER-DAO",
+ "sonar.jira.login.secured", "john",
+ "sonar.coverage.exclusions", "**/*.java"
+ ));
+ }
+
+ @Test
+ public void return_project_with_two_modules() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
+
+ ComponentDto module1 = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module1);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(module1, project, projectSnapshot));
+
+ // Module 1 properties
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module1.getId()), dbSession);
+ // This property should not be found on the other module
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module1.getId()), dbSession);
+
+ ComponentDto module2 = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module2);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(module2, project, projectSnapshot));
+
+ // Module 2 property
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION").setResourceId(module2.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john"
+ ));
+ assertThat(ref.settings(module1.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR-SERVER",
+ "sonar.jira.login.secured", "john",
+ "sonar.coverage.exclusions", "**/*.java"
+ ));
+ assertThat(ref.settings(module2.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR-APPLICATION",
+ "sonar.jira.login.secured", "john"
+ ));
+ }
+
+ @Test
+ public void return_provisioned_project_settings() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ // No snapshot attached on the project -> provisioned project
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john"
+ ));
+ }
+
+ @Test
+ public void return_sub_module_settings() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
+ addDefaultProfile();
+ // No project properties
+
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module);
+ SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, project, projectSnapshot);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, moduleSnapshot);
+ // No module properties
+
+ ComponentDto subModule = ComponentTesting.newModuleDto(module);
+ tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(subModule, module, moduleSnapshot));
+
+ // Sub module properties
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(subModule.key()));
+ assertThat(ref.settings(project.key())).isEmpty();
+ assertThat(ref.settings(module.key())).isEmpty();
+ assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john",
+ "sonar.coverage.exclusions", "**/*.java"
+ ));
+ }
+
+ @Test
+ public void return_sub_module_settings_including_settings_from_parent_modules() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
+ addDefaultProfile();
+
+ // Project property
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
+
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module);
+ SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, project, projectSnapshot);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, moduleSnapshot);
+
+ // Module property
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId()), dbSession);
+
+ ComponentDto subModule = ComponentTesting.newModuleDto(module);
+ tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(subModule, module, moduleSnapshot));
+
+ // Sub module properties
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(subModule.key()));
+ assertThat(ref.settings(project.key())).isEmpty();
+ assertThat(ref.settings(module.key())).isEmpty();
+ assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john",
+ "sonar.coverage.exclusions", "**/*.java"
+ ));
+ }
+
+ @Test
+ public void return_sub_module_settings_only_inherited_from_project() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()), dbSession);
+
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module);
+ SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, project, projectSnapshot);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, moduleSnapshot);
+ // No module property
+
+ ComponentDto subModule = ComponentTesting.newModuleDto(module);
+ tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(subModule, module, moduleSnapshot));
+ // No sub module property
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(subModule.key()));
+ assertThat(ref.settings(project.key())).isEmpty();
+ assertThat(ref.settings(module.key())).isEmpty();
+ assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john",
+ "sonar.coverage.exclusions", "**/*.java"
+ ));
+ }
+
+ @Test
+ public void return_sub_module_settings_inherited_from_project_and_module() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()), dbSession);
+
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ tester.get(DbClient.class).componentDao().insert(dbSession, module);
+ SnapshotDto moduleSnapshot = SnapshotTesting.createForComponent(module, project, projectSnapshot);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, moduleSnapshot);
+
+ // Module property
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()), dbSession);
+
+ ComponentDto subModule = ComponentTesting.newModuleDto(module);
+ tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(subModule, module, moduleSnapshot));
+ // No sub module property
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(subModule.key()));
+ assertThat(ref.settings(project.key())).isEmpty();
+ assertThat(ref.settings(module.key())).isEmpty();
+ assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR-SERVER",
+ "sonar.jira.login.secured", "john",
+ "sonar.coverage.exclusions", "**/*.java"
+ ));
+ }
+
+ @Test
+ public void return_quality_profile_from_project_profile() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ Date ruleUpdatedAt = DateUtils.parseDateTime("2014-01-14T13:00:00+0100");
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project));
+
+ QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(DateUtils.formatDateTime(ruleUpdatedAt));
+ tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way").setResourceId(project.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ List<QProfile> profiles = newArrayList(ref.qProfiles());
+ assertThat(profiles).hasSize(1);
+ assertThat(profiles.get(0).key()).isEqualTo("abcd");
+ assertThat(profiles.get(0).name()).isEqualTo("SonarQube way");
+ assertThat(profiles.get(0).language()).isEqualTo("xoo");
+ assertThat(profiles.get(0).rulesUpdatedAt()).isEqualTo(ruleUpdatedAt);
+ }
+
+ @Test
+ public void return_quality_profile_from_default_profile() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ Date ruleUpdatedAt = DateUtils.parseDateTime("2014-01-14T13:00:00+0100");
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project));
+
+ QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(DateUtils.formatDateTime(ruleUpdatedAt));
+ tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ List<QProfile> profiles = newArrayList(ref.qProfiles());
+ assertThat(profiles).hasSize(1);
+ assertThat(profiles.get(0).key()).isEqualTo("abcd");
+ assertThat(profiles.get(0).name()).isEqualTo("SonarQube way");
+ assertThat(profiles.get(0).language()).isEqualTo("xoo");
+ assertThat(profiles.get(0).rulesUpdatedAt()).isEqualTo(ruleUpdatedAt);
+ }
+
+ @Test
+ public void return_quality_profile_from_given_profile_name() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ Date ruleUpdatedAt = DateUtils.parseDateTime("2014-01-14T13:00:00+0100");
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project));
+
+ QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(DateUtils.formatDateTime(ruleUpdatedAt));
+ tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()).setProfileName("SonarQube way"));
+ List<QProfile> profiles = newArrayList(ref.qProfiles());
+ assertThat(profiles).hasSize(1);
+ assertThat(profiles.get(0).key()).isEqualTo("abcd");
+ assertThat(profiles.get(0).name()).isEqualTo("SonarQube way");
+ assertThat(profiles.get(0).language()).isEqualTo("xoo");
+ assertThat(profiles.get(0).rulesUpdatedAt()).isEqualTo(ruleUpdatedAt);
+ }
+
+ @Test
+ public void return_quality_profiles_even_when_project_does_not_exists() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ Date ruleUpdatedAt = DateUtils.parseDateTime("2014-01-14T13:00:00+0100");
+
+ QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(DateUtils.formatDateTime(ruleUpdatedAt));
+ tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey("project"));
+ List<QProfile> profiles = newArrayList(ref.qProfiles());
+ assertThat(profiles).hasSize(1);
+ assertThat(profiles.get(0).key()).isEqualTo("abcd");
+ assertThat(profiles.get(0).name()).isEqualTo("SonarQube way");
+ assertThat(profiles.get(0).language()).isEqualTo("xoo");
+ assertThat(profiles.get(0).rulesUpdatedAt()).isEqualTo(ruleUpdatedAt);
+ }
+
+
+ @Test
+ public void return_provisioned_project_profile() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ Date ruleUpdatedAt = DateUtils.parseDateTime("2014-01-14T13:00:00+0100");
+
+ // No snapshot attached on the project -> provisioned project
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+
+ QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(DateUtils.formatDateTime(ruleUpdatedAt));
+ tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way").setResourceId(project.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ List<QProfile> profiles = newArrayList(ref.qProfiles());
+ assertThat(profiles).hasSize(1);
+ assertThat(profiles.get(0).key()).isEqualTo("abcd");
+ assertThat(profiles.get(0).name()).isEqualTo("SonarQube way");
+ assertThat(profiles.get(0).language()).isEqualTo("xoo");
+ assertThat(profiles.get(0).rulesUpdatedAt()).isEqualTo(ruleUpdatedAt);
+ }
+
+ @Test
+ public void fail_when_no_quality_profile_for_a_language() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto().setKey("org.codehaus.sonar:sonar");
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ dbSession.commit();
+
+ try {
+ loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("No quality profile can been found on language 'xoo' for project 'org.codehaus.sonar:sonar'");
+ }
+ }
+
+ @Test
+ public void return_active_rules() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ Date ruleUpdatedAt = DateUtils.parseDateTime("2014-01-14T13:00:00+0100");
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForProject(project));
+
+ QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(DateUtils.formatDateTime(ruleUpdatedAt));
+ tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession);
+
+ RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
+ RuleDto rule = RuleTesting.newDto(ruleKey).setName("Avoid Cycle").setConfigKey("squid-1").setLanguage(ServerTester.Xoo.KEY);
+ tester.get(DbClient.class).ruleDao().insert(dbSession, rule);
+ tester.get(DbClient.class).ruleDao().addRuleParam(dbSession, rule, RuleParamDto.createFor(rule)
+ .setName("max").setDefaultValue("10").setType(RuleParamType.INTEGER.type()));
+
+ RuleActivation activation = new RuleActivation(ruleKey);
+ activation.setSeverity(Severity.MINOR);
+ activation.setParameter("max", "2");
+ tester.get(RuleActivator.class).activate(dbSession, activation, profileDto.getKey());
+
+ dbSession.commit();
+
+ ProjectReferentials ref = loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ List<ActiveRule> activeRules = newArrayList(ref.activeRules());
+ assertThat(activeRules).hasSize(1);
+ assertThat(activeRules.get(0).repositoryKey()).isEqualTo("squid");
+ assertThat(activeRules.get(0).ruleKey()).isEqualTo("AvoidCycle");
+ assertThat(activeRules.get(0).name()).isEqualTo("Avoid Cycle");
+ assertThat(activeRules.get(0).language()).isEqualTo("xoo");
+ assertThat(activeRules.get(0).severity()).isEqualTo("MINOR");
+ assertThat(activeRules.get(0).internalKey()).isEqualTo("squid-1");
+ assertThat(activeRules.get(0).language()).isEqualTo("xoo");
+ assertThat(activeRules.get(0).params()).isEqualTo(ImmutableMap.of("max", "2"));
+ }
+
+ @Test
+ public void fail_if_no_permission() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions();
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ dbSession.commit();
+
+ try {
+ loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()));
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
+ }
+ }
+
+ @Test
+ public void fail_when_not_preview_and_only_dry_run_permission() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION);
+
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ dbSession.commit();
+
+ try {
+ loader.load(ProjectReferentialsQuery.create().setModuleKey(project.key()).setPreview(false));
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage(
+ "You're only authorized to execute a local (dry run) SonarQube analysis without pushing the results to the SonarQube server. " +
+ "Please contact your SonarQube administrator.");
+ }
+ }
+
+ private void addDefaultProfile() {
+ QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(DateUtils.formatDateTime(new Date()));
+ tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession);
+ }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java
index 4f1da87acaf..3376773d2a4 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java
@@ -62,14 +62,15 @@ public class ComponentTesting {
}
public static ComponentDto newModuleDto(ComponentDto subProjectOrProject) {
+ String uuid = Uuids.create();
return new ComponentDto()
.setUuid(Uuids.create())
.setProjectUuid(subProjectOrProject.projectUuid())
.setModuleUuid(subProjectOrProject.uuid())
- .setModuleUuidPath(subProjectOrProject.moduleUuidPath() == null ? subProjectOrProject.uuid() : subProjectOrProject.moduleUuidPath() + "." + subProjectOrProject.uuid())
- .setKey("module")
- .setName("Module")
- .setLongName("Module")
+ .setModuleUuidPath(subProjectOrProject.moduleUuidPath() == null ? subProjectOrProject.uuid() + "." : subProjectOrProject.moduleUuidPath() + subProjectOrProject.uuid() + ".")
+ .setKey("KEY_" + uuid)
+ .setName("NAME_" + uuid)
+ .setLongName("LONG_NAME_" + uuid)
.setParentProjectId(subProjectOrProject.getId())
.setScope(Scopes.PROJECT)
.setQualifier(Qualifiers.MODULE)
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java b/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java
index eb27722379a..1b174c9a11f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java
@@ -24,16 +24,26 @@ import org.sonar.api.utils.DateUtils;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.SnapshotDto;
+import java.util.Date;
+
public class SnapshotTesting {
/**
- * When project is null, that means that the component is a project
+ * Can be used for modules and files
*/
- public static SnapshotDto createForComponent(ComponentDto component, ComponentDto project) {
+ public static SnapshotDto createForComponent(ComponentDto component, ComponentDto parentProject, SnapshotDto parentSnapshot) {
+ Long parentRootId = parentSnapshot.getRootId();
return new SnapshotDto()
.setResourceId(component.getId())
- .setRootProjectId(project.getId())
- .setLast(true);
+ .setRootProjectId(parentSnapshot.getRootProjectId())
+ .setRootId(parentRootId != null ? parentRootId : parentSnapshot.getId())
+ .setStatus(SnapshotDto.STATUS_PROCESSED)
+ .setQualifier(component.qualifier())
+ .setScope(component.scope())
+ .setParentId(parentSnapshot.getId())
+ .setPath(parentSnapshot.getPath() == null ? Long.toString(parentSnapshot.getId()) + "." : parentSnapshot.getPath() + Long.toString(parentSnapshot.getId()) + ".")
+ .setLast(true)
+ .setBuildDate(new Date());
}
public static SnapshotDto createForProject(ComponentDto project) {
@@ -43,7 +53,9 @@ public class SnapshotTesting {
.setStatus(SnapshotDto.STATUS_PROCESSED)
.setQualifier(project.qualifier())
.setScope(project.scope())
- .setLast(true);
+ .setPath("")
+ .setLast(true)
+ .setBuildDate(new Date());
}
public static SnapshotDto defaultSnapshot() {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
index ca50790fe13..b49a2009645 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
package org.sonar.server.component.db;
import org.apache.ibatis.exceptions.PersistenceException;
@@ -26,6 +27,7 @@ import org.junit.Test;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ProjectRefentialsComponentDto;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.exceptions.NotFoundException;
@@ -330,6 +332,27 @@ public class ComponentDaoTest extends AbstractDaoTestCase {
}
@Test
+ public void find_children_modules_from_module() throws Exception {
+ setupData("multi-modules");
+
+ // From root project
+ List<ProjectRefentialsComponentDto> modules = dao.findChildrenModulesFromModule(session, "org.struts:struts");
+ assertThat(modules).hasSize(2);
+ assertThat(modules).onProperty("id").containsOnly(2L, 3L);
+ assertThat(modules).onProperty("parentModuleKey").containsOnly("org.struts:struts", "org.struts:struts-core");
+
+ // From module
+ modules = dao.findChildrenModulesFromModule(session, "org.struts:struts-core");
+ assertThat(modules).hasSize(1);
+ assertThat(modules).onProperty("id").containsOnly(3L);
+ assertThat(modules).onProperty("parentModuleKey").containsOnly("org.struts:struts-core");
+
+ // From sub module
+ modules = dao.findChildrenModulesFromModule(session, "org.struts:struts-data");
+ assertThat(modules).isEmpty();
+ }
+
+ @Test
public void insert() {
when(system2.now()).thenReturn(DateUtils.parseDate("2014-06-18").getTime());
setupData("empty");
@@ -391,9 +414,9 @@ public class ComponentDaoTest extends AbstractDaoTestCase {
@Test(expected = IllegalStateException.class)
public void update() {
dao.update(session, new ComponentDto()
- .setId(1L)
- .setKey("org.struts:struts-core:src/org/struts/RequestContext.java")
- );
+ .setId(1L)
+ .setKey("org.struts:struts-core:src/org/struts/RequestContext.java")
+ );
}
@Test
@@ -401,9 +424,9 @@ public class ComponentDaoTest extends AbstractDaoTestCase {
setupData("shared");
dao.delete(session, new ComponentDto()
- .setId(1L)
- .setKey("org.struts:struts-core:src/org/struts/RequestContext.java")
- );
+ .setId(1L)
+ .setKey("org.struts:struts-core:src/org/struts/RequestContext.java")
+ );
session.commit();
checkTable("delete", "projects");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java
index f799082745f..3308afc1515 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java
@@ -186,6 +186,26 @@ public class SnapshotDaoTest extends AbstractDaoTestCase {
}
@Test
+ public void find_children_modules() {
+ setupData("modules");
+
+ // From root project
+ List<SnapshotDto> snapshots = sut.findChildrenModulesFromModule(session, "org.struts:struts");
+ assertThat(snapshots).hasSize(2);
+ assertThat(snapshots).onProperty("id").containsOnly(2L, 3L);
+ assertThat(snapshots).onProperty("last").containsOnly(true);
+
+ // From module
+ snapshots = sut.findChildrenModulesFromModule(session, "org.struts:struts-core");
+ assertThat(snapshots).hasSize(1);
+ assertThat(snapshots).onProperty("id").containsOnly(3L);
+
+ // From sub module
+ snapshots = sut.findChildrenModulesFromModule(session, "org.struts:struts-data");
+ assertThat(snapshots).isEmpty();
+ }
+
+ @Test
public void set_snapshot_and_children_to_false_and_status_processed() {
setupData("snapshots");
SnapshotDto snapshot = defaultSnapshot().setId(1L);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java
index 345c68639f7..b741d9638dc 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java
@@ -30,6 +30,7 @@ import org.sonar.api.issue.Issue;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.SnapshotDto;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
@@ -84,11 +85,12 @@ public class IssueBulkChangeServiceMediumTest {
project = ComponentTesting.newProjectDto().setKey("MyProject");
tester.get(ComponentDao.class).insert(session, project);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForProject(project));
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(SnapshotDao.class).insert(session, projectSnapshot);
file = ComponentTesting.newFileDto(project).setKey("MyComponent");
tester.get(ComponentDao.class).insert(session, file);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project));
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project, projectSnapshot));
// project can be seen by anyone
session.commit();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java
index 1b1fa83bcdf..1d017d3ea1f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java
@@ -31,6 +31,7 @@ import org.sonar.api.rule.RuleStatus;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.SnapshotDto;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
@@ -81,11 +82,12 @@ public class IssueCommentServiceMediumTest {
project = ComponentTesting.newProjectDto();
tester.get(ComponentDao.class).insert(session, project);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForProject(project));
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(SnapshotDao.class).insert(session, projectSnapshot);
file = ComponentTesting.newFileDto(project);
tester.get(ComponentDao.class).insert(session, file);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project));
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project, projectSnapshot));
// project can be seen by anyone
session.commit();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
index a94bdba0846..2605c0b76c2 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
@@ -33,6 +33,7 @@ import org.sonar.api.rule.Severity;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.SnapshotDto;
import org.sonar.core.issue.db.ActionPlanDto;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.issue.workflow.Transition;
@@ -96,11 +97,12 @@ public class IssueServiceMediumTest {
project = ComponentTesting.newProjectDto();
tester.get(ComponentDao.class).insert(session, project);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForProject(project));
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ tester.get(SnapshotDao.class).insert(session, projectSnapshot);
file = ComponentTesting.newFileDto(project);
tester.get(ComponentDao.class).insert(session, file);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project));
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project, projectSnapshot));
// workaround for the test to have sufficient privileges
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
index 79485339107..b70ecbb5a12 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
@@ -32,11 +32,8 @@ import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.issue.db.ActionPlanDao;
-import org.sonar.core.issue.db.ActionPlanDto;
-import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDto;
+import org.sonar.core.component.SnapshotDto;
+import org.sonar.core.issue.db.*;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.rule.RuleDto;
@@ -421,7 +418,8 @@ public class SearchActionMediumTest {
public void components_contains_sub_projects() throws Exception {
ComponentDto project = ComponentTesting.newProjectDto().setKey("ProjectHavingModule");
db.componentDao().insert(session, project);
- db.snapshotDao().insert(session, SnapshotTesting.createForProject(project));
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ db.snapshotDao().insert(session, projectSnapshot);
session.commit();
// project can be seen by anyone
@@ -431,11 +429,11 @@ public class SearchActionMediumTest {
.setScope("PRJ")
.setParentProjectId(project.getId());
db.componentDao().insert(session, module);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(module, project));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(module, project, projectSnapshot));
ComponentDto file = ComponentTesting.newFileDto(module).setKey("FileLinkedToModule");
db.componentDao().insert(session, file);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file, project));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file, project, projectSnapshot));
IssueDto issue = IssueTesting.newDto(rule, file, project);
db.issueDao().insert(session, issue);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java
index 755fc4bbb75..b1d3a66077d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java
@@ -27,6 +27,7 @@ import org.junit.Test;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.SnapshotDto;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
@@ -75,11 +76,12 @@ public class BackendCleanupMediumTest {
project = ComponentTesting.newProjectDto().setKey("MyProject");
tester.get(ComponentDao.class).insert(session, project);
- db.snapshotDao().insert(session, SnapshotTesting.createForProject(project));
+ SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+ db.snapshotDao().insert(session, projectSnapshot);
file = ComponentTesting.newFileDto(project).setKey("MyComponent");
tester.get(ComponentDao.class).insert(session, file);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file, project));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file, project, projectSnapshot));
session.commit();
// project can be seen by anyone
MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/not_returned_secured_settings_with_only_preview_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/not_returned_secured_settings_with_only_preview_permission.json
deleted file mode 100644
index 1704720a4f1..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/not_returned_secured_settings_with_only_preview_permission.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar": {
- "sonar.jira.project.key": "SONAR"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_active_rules.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/project_referentials.json
index 03e475b2afa..ff04061219e 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_active_rules.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/project_referentials.json
@@ -21,6 +21,11 @@
}
}
],
- "settingsByModule": {},
+ "settingsByModule": {
+ "org.codehaus.sonar:sonar": {
+ "sonar.jira.project.key": "SONAR",
+ "sonar.jira.login.secured": "john"
+ }
+ },
"fileDataByModuleAndPath": {}
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_settings.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_settings.json
deleted file mode 100644
index c7ac51a9af3..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_settings.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_settings.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_settings.json
deleted file mode 100644
index 7aaec4b5483..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_settings.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john"
- },
- "org.codehaus.sonar:sonar-server": {
- "sonar.jira.project.key": "SONAR-SERVER",
- "sonar.jira.login.secured": "john",
- "sonar.coverage.exclusions": "**/*.java"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_settings_inherited_from_project.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_settings_inherited_from_project.json
deleted file mode 100644
index 65da3016c6a..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_settings_inherited_from_project.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john"
- },
- "org.codehaus.sonar:sonar-server": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_with_sub_module.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_with_sub_module.json
deleted file mode 100644
index ccaaedd13f0..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_module_with_sub_module.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john"
- },
- "org.codehaus.sonar:sonar-server": {
- "sonar.jira.project.key": "SONAR-SERVER",
- "sonar.jira.login.secured": "john",
- "sonar.coverage.exclusions": "**/*.java"
- },
- "org.codehaus.sonar:sonar-server-dao": {
- "sonar.jira.project.key": "SONAR-SERVER-DAO",
- "sonar.jira.login.secured": "john",
- "sonar.coverage.exclusions": "**/*.java"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_two_modules.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_two_modules.json
deleted file mode 100644
index 85b6e165fca..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_project_with_two_modules.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john"
- },
- "org.codehaus.sonar:sonar-server": {
- "sonar.jira.project.key": "SONAR-SERVER",
- "sonar.jira.login.secured": "john",
- "sonar.coverage.exclusions": "**/*.java"
- },
- "org.codehaus.sonar:sonar-application": {
- "sonar.jira.project.key": "SONAR-APPLICATION",
- "sonar.jira.login.secured": "john"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_provisioned_project_profile.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_provisioned_project_profile.json
deleted file mode 100644
index 5e435288c7b..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_provisioned_project_profile.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "SonarQube way",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {},
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profile_from_default_profile.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profile_from_default_profile.json
deleted file mode 100644
index ef28667d07f..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profile_from_default_profile.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {},
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profile_from_given_profile_name.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profile_from_given_profile_name.json
deleted file mode 100644
index ef28667d07f..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profile_from_given_profile_name.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {},
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profiles.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profiles.json
deleted file mode 100644
index 5e435288c7b..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profiles.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "SonarQube way",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {},
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profiles_even_when_project_does_not_exists.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profiles_even_when_project_does_not_exists.json
deleted file mode 100644
index ef28667d07f..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_quality_profiles_even_when_project_does_not_exists.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {},
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings.json
deleted file mode 100644
index a43f52bcbdf..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar-server-dao": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john",
- "sonar.coverage.exclusions": "**/*.java"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_including_settings_from_parent_modules.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_including_settings_from_parent_modules.json
deleted file mode 100644
index a43f52bcbdf..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_including_settings_from_parent_modules.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar-server-dao": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john",
- "sonar.coverage.exclusions": "**/*.java"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_inherited_from_project.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_inherited_from_project.json
deleted file mode 100644
index a43f52bcbdf..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_inherited_from_project.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar-server-dao": {
- "sonar.jira.project.key": "SONAR",
- "sonar.jira.login.secured": "john",
- "sonar.coverage.exclusions": "**/*.java"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_inherited_from_project_and_module.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_inherited_from_project_and_module.json
deleted file mode 100644
index 93ed2b510c0..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/return_sub_module_settings_inherited_from_project_and_module.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "timestamp": 0,
- "qprofilesByLanguage": {
- "java": {
- "key": "abcd",
- "name": "Default",
- "language": "java",
- "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
- }
- },
- "activeRules": [],
- "settingsByModule": {
- "org.codehaus.sonar:sonar-server-dao": {
- "sonar.jira.project.key": "SONAR-SERVER",
- "sonar.jira.login.secured": "john",
- "sonar.coverage.exclusions": "**/*.java"
- }
- },
- "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/modules.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/modules.xml
new file mode 100644
index 00000000000..8bc9decea38
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/modules.xml
@@ -0,0 +1,90 @@
+<dataset>
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="[null]" />
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+ <snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-01 13:58:00.00" build_date="2008-12-01 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD."
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+ <!-- sub module -->
+ <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data"
+ uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH."
+ scope="PRJ" qualifier="BRC" long_name="Struts Data"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
+ <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2."/>
+
+ <!-- directory -->
+ <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI."
+ name="src/org/struts" root_id="3"
+ description="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" />
+ <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3."/>
+
+ <!-- file -->
+ <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="HIJK" project_uuid="ABCD" module_uuid="GHIJ" module_uuid_path="ABCD.EFGH.FGHI.GHIJ."
+ name="RequestContext.java" root_id="3"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" />
+
+ <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3.4."/>
+
+</dataset>
diff --git a/sonar-core/src/main/java/org/sonar/core/component/ProjectRefentialsComponentDto.java b/sonar-core/src/main/java/org/sonar/core/component/ProjectRefentialsComponentDto.java
new file mode 100644
index 00000000000..e531993ce5d
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/component/ProjectRefentialsComponentDto.java
@@ -0,0 +1,37 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.core.component;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class ProjectRefentialsComponentDto extends ComponentDto {
+
+ private String parentModuleKey;
+
+ @CheckForNull
+ public String getParentModuleKey() {
+ return parentModuleKey;
+ }
+
+ public void setParentModuleKey(@Nullable String parentModuleKey) {
+ this.parentModuleKey = parentModuleKey;
+ }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java
index 37c0a894ae8..789af967e65 100644
--- a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java
+++ b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java
@@ -17,10 +17,12 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
package org.sonar.core.component.db;
import org.apache.ibatis.annotations.Param;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ProjectRefentialsComponentDto;
import javax.annotation.CheckForNull;
@@ -72,12 +74,16 @@ public interface ComponentMapper {
* Warning, projectId are always null
*/
List<ComponentDto> findByUuids(@Param("uuids") Collection<String> uuids);
-
/**
* Return all project (PRJ/TRK) uuids
*/
List<String> findProjectUuids();
+ /**
+ * Return all modules children (not returning itself) from a module key
+ */
+ List<ProjectRefentialsComponentDto> findChildrenModulesFromModule(@Param("moduleKey") String moduleKey);
+
long countById(long id);
void insert(ComponentDto rule);
diff --git a/sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java b/sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java
index fd9d1c1188b..31f1167a686 100644
--- a/sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java
+++ b/sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java
@@ -43,6 +43,8 @@ public interface SnapshotMapper {
List<SnapshotDto> selectSnapshotAndChildrenOfScope(@Param(value = "snapshot") Long resourceId, @Param(value = "scope") String scope);
+ List<SnapshotDto> selectChildrenModulesFromModule(@Param(value = "moduleKey") String moduleKey);
+
int updateSnapshotAndChildrenLastFlagAndStatus(@Param(value = "root") Long rootId, @Param(value = "pathRootId") Long pathRootId,
@Param(value = "path") String path, @Param(value = "isLast") boolean isLast, @Param(value = "status") String status);
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
index ea38fbd742f..1c252ef40f7 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
package org.sonar.core.persistence;
import ch.qos.logback.classic.Level;
@@ -35,6 +36,7 @@ import org.sonar.core.activity.db.ActivityDto;
import org.sonar.core.activity.db.ActivityMapper;
import org.sonar.core.cluster.WorkQueue;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ProjectRefentialsComponentDto;
import org.sonar.core.component.SnapshotDto;
import org.sonar.core.component.db.ComponentMapper;
import org.sonar.core.component.db.SnapshotMapper;
@@ -129,6 +131,7 @@ public class MyBatis implements BatchComponent, ServerComponent {
loadAlias(conf, "ActiveDashboard", ActiveDashboardDto.class);
loadAlias(conf, "Author", AuthorDto.class);
loadAlias(conf, "Component", ComponentDto.class);
+ loadAlias(conf, "ProjectRefentialsComponent", ProjectRefentialsComponentDto.class);
loadAlias(conf, "Dashboard", DashboardDto.class);
loadAlias(conf, "Dependency", DependencyDto.class);
loadAlias(conf, "DuplicationUnit", DuplicationUnitDto.class);
diff --git a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java
index 9ba8f2468fa..4fa7f90797e 100644
--- a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java
+++ b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
package org.sonar.core.properties;
import com.google.common.base.Preconditions;
@@ -121,6 +122,10 @@ public class PropertiesDao implements BatchComponent, ServerComponent, DaoCompon
}
}
+ public List<PropertyDto> findChildrenModuleProperties(String moduleKey, SqlSession session) {
+ return session.getMapper(PropertiesMapper.class).selectChildrenModuleProperties(moduleKey);
+ }
+
public PropertyDto selectProjectProperty(long resourceId, String propertyKey) {
SqlSession session = mybatis.openSession(false);
PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
diff --git a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java
index 10f298b53c3..3fc4311c509 100644
--- a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java
+++ b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
package org.sonar.core.properties;
import org.apache.ibatis.annotations.Param;
@@ -43,6 +44,8 @@ public interface PropertiesMapper {
List<PropertyDto> selectByQuery(@Param("query") PropertyQuery query);
+ List<PropertyDto> selectChildrenModuleProperties(@Param("moduleKey") String moduleKey);
+
void update(PropertyDto property);
void insert(PropertyDto property);
diff --git a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml
index 685f8e42d40..2af4bfc0438 100644
--- a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml
@@ -132,6 +132,14 @@
</where>
</select>
+ <select id="findChildrenModulesFromModule" parameterType="String" resultType="ProjectRefentialsComponent">
+ SELECT <include refid="componentColumns"/>, parent.kee as parentModuleKey
+ FROM projects p
+ INNER JOIN (<include refid="org.sonar.core.component.db.SnapshotMapper.selectChildrenModulesFromModuleQuery" />) snapshotModules on snapshotModules.resourceId=p.id
+ LEFT OUTER JOIN snapshots parent_snapshot on parent_snapshot.id = snapshotModules.parentId
+ LEFT OUTER JOIN projects parent on parent.id = parent_snapshot.project_id
+ </select>
+
<select id="findProjectUuids" resultType="String">
SELECT p.uuid
FROM projects p
diff --git a/sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml b/sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml
index c0112194bcf..0aeb697a2c3 100644
--- a/sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml
@@ -68,6 +68,33 @@
AND (s.id = #{snapshot} or s.root_snapshot_id = #{snapshot})
</select>
+ <select id="selectChildrenModulesFromModule" parameterType="map" resultType="Snapshot">
+ <include refid="selectChildrenModulesFromModuleQuery" />
+ </select>
+
+ <sql id="selectChildrenModulesFromModuleQuery">
+ SELECT <include refid="org.sonar.core.component.db.SnapshotMapper.snapshotColumns"/>
+ FROM snapshots s
+ INNER JOIN snapshots root_snapshot ON root_snapshot.id = s.root_snapshot_id AND root_snapshot.islast = ${_true}
+ INNER JOIN snapshots current_snapshot ON current_snapshot.root_project_id = root_snapshot.project_id AND s.islast = ${_true}
+ INNER JOIN projects module ON module.id = current_snapshot.project_id AND module.enabled = ${_true} AND module.kee = #{moduleKey}
+ <where>
+ AND s.islast = ${_true}
+ AND s.scope = 'PRJ'
+ AND <choose>
+ <when test="_databaseId == 'mssql'">
+ s.path LIKE current_snapshot.path + CAST(current_snapshot.id AS varchar(15)) + '.%'
+ </when>
+ <when test="_databaseId == 'mysql'">
+ s.path LIKE concat(current_snapshot.path, current_snapshot.id, '.%')
+ </when>
+ <otherwise>
+ s.path LIKE current_snapshot.path || current_snapshot.id || '.%'
+ </otherwise>
+ </choose>
+ </where>
+ </sql>
+
<sql id="insertColumns">
(parent_snapshot_id, root_snapshot_id, root_project_id, project_id, created_at, build_date, status, purge_status,
islast, scope, qualifier, version, path, depth,
diff --git a/sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml b/sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml
index dedc3d19362..d86d22e817c 100644
--- a/sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/properties/PropertiesMapper.xml
@@ -45,6 +45,14 @@
where p.resource_id=#{resourceId} and p.user_id is null
</select>
+ <select id="selectChildrenModuleProperties" parameterType="String" resultType="Property">
+ SELECT prop.id as id, prop.prop_key as "key", prop.text_value as value, prop.resource_id as resourceId, prop.user_id as userId
+ FROM properties prop
+ INNER JOIN (<include refid="org.sonar.core.component.db.SnapshotMapper.selectChildrenModulesFromModuleQuery" />) snapshotModules on snapshotModules.resourceId=prop.resource_id
+ INNER JOIN projects p on p.id = prop.resource_id
+ WHERE prop.user_id IS NULL
+ </select>
+
<select id="selectSetOfResourceProperties" parameterType="map" resultType="Property">
select p.id as id, p.prop_key as "key", p.text_value as value, p.resource_id as resourceId, p.user_id as userId
from properties p
diff --git a/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java b/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java
index 454ba2829c2..12aae6b86ee 100644
--- a/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/properties/PropertiesDaoTest.java
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
package org.sonar.core.properties;
import com.google.common.collect.ImmutableMap;
@@ -153,6 +154,22 @@ public class PropertiesDaoTest extends AbstractDaoTestCase {
}
@Test
+ public void select_children_module_properties() throws Exception {
+ setupData("select_children_module_properties");
+
+ List<PropertyDto> properties = dao.findChildrenModuleProperties("org.struts:struts", session);
+ assertThat(properties.size(), is(3));
+ assertThat(properties).onProperty("key").containsOnly("core.one", "core.two", "data.one");
+ assertThat(properties).onProperty("value").containsOnly("one", "two");
+
+ properties = dao.findChildrenModuleProperties("org.struts:struts-core", session);
+ assertThat(properties.size(), is(1));
+ assertThat(properties).onProperty("key").containsOnly("data.one");
+
+ assertThat(dao.findChildrenModuleProperties("org.struts:struts-data", session).size(), is(0));
+ }
+
+ @Test
public void selectProjectProperty() {
setupData("selectProjectProperties");
PropertyDto property = dao.selectProjectProperty(11L, "commonslang.one");
diff --git a/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/select_children_module_properties.xml b/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/select_children_module_properties.xml
new file mode 100644
index 00000000000..5aec43d9315
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/properties/PropertiesDaoTest/select_children_module_properties.xml
@@ -0,0 +1,109 @@
+<dataset>
+
+ <!-- global -->
+ <properties id="1" prop_key="global.one" text_value="one" resource_id="[null]" user_id="[null]"/>
+ <properties id="2" prop_key="global.two" text_value="two" resource_id="[null]" user_id="[null]"/>
+
+ <!-- org.struts:struts -->
+ <properties id="3" prop_key="struts.one" text_value="one" resource_id="1" user_id="[null]"/>
+
+ <!-- org.struts:struts-core -->
+ <properties id="4" prop_key="core.one" text_value="one" resource_id="2" user_id="[null]"/>
+ <properties id="7" prop_key="core.two" text_value="two" resource_id="2" user_id="[null]"/>
+
+ <!-- org.struts:struts-data -->
+ <properties id="8" prop_key="data.one" text_value="one" resource_id="3" user_id="[null]"/>
+
+ <!-- user -->
+ <properties id="5" prop_key="user.one" text_value="one" resource_id="[null]" user_id="100"/>
+ <properties id="6" prop_key="user.two" text_value="two" resource_id="1" user_id="102"/>
+
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="[null]"
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="[null]" />
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path=""/>
+ <snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-01 13:58:00.00" build_date="2008-12-01 13:58:00.00"
+ version="[null]" path=""/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD."
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1."/>
+
+ <!-- sub module -->
+ <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data"
+ uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH."
+ scope="PRJ" qualifier="BRC" long_name="Struts Data"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
+ <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2."/>
+
+ <!-- directory -->
+ <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI."
+ name="src/org/struts" root_id="3"
+ description="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" />
+ <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3."/>
+
+ <!-- file -->
+ <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="HIJK" project_uuid="ABCD" module_uuid="GHIJ" module_uuid_path="ABCD.EFGH.FGHI.GHIJ."
+ name="RequestContext.java" root_id="3"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" />
+
+ <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+ version="[null]" path="1.2.3.4."/>
+
+</dataset>