diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2018-11-19 11:08:59 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-01-16 09:43:02 +0100 |
commit | e4c0b858c7e6807801c6481d995ca11682c58fad (patch) | |
tree | 612e7224f9bd131076005d56964a9fc5be0d72c3 | |
parent | b6f878d8d48c55c03bcbf2ba8010526f1fa12f49 (diff) | |
download | sonarqube-e4c0b858c7e6807801c6481d995ca11682c58fad.tar.gz sonarqube-e4c0b858c7e6807801c6481d995ca11682c58fad.zip |
SONAR-11488 Stop loading module level settings in scanner
39 files changed, 343 insertions, 1464 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java index ba3c4ef0528..cc8689f5a12 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java @@ -92,11 +92,15 @@ public class XooPlugin implements Plugin { .subCategory("General") .onQualifiers(Qualifiers.PROJECT) .build(), - // Used by DuplicationsTest. If not declared it is not returned by api/settings + // Used by DuplicationsTest and IssueFilterOnCommonRulesTest. If not declared it is not returned by api/settings PropertyDefinition.builder("sonar.cpd.xoo.minimumTokens") .onQualifiers(Qualifiers.PROJECT) .type(PropertyType.INTEGER) .build(), + PropertyDefinition.builder("sonar.cpd.xoo.minimumLines") + .onQualifiers(Qualifiers.PROJECT) + .type(PropertyType.INTEGER) + .build(), Xoo.class, Xoo2.class, XooRulesDefinition.class, diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java index 3e4c6aa5a82..27bfe063894 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java @@ -40,7 +40,7 @@ public class XooPluginTest { Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); assertThat(getExtensions(context)) - .hasSize(47) + .hasSize(48) .doesNotContain(XooBuiltInQualityProfilesDefinition.class); } @@ -50,7 +50,7 @@ public class XooPluginTest { Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); assertThat(getExtensions(context)) - .hasSize(50) + .hasSize(51) .contains(XooBuiltInQualityProfilesDefinition.class); } @@ -60,7 +60,7 @@ public class XooPluginTest { Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); assertThat(getExtensions(context)) - .hasSize(54) + .hasSize(55) .contains(OneExternalIssuePerLineSensor.class); } @@ -70,7 +70,7 @@ public class XooPluginTest { Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); assertThat(getExtensions(context)) - .hasSize(55) + .hasSize(56) .contains(OneExternalIssuePerLineSensor.class); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java index a91a50f3354..04ac22cb459 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java @@ -30,7 +30,6 @@ import java.util.Map; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.api.resources.Scopes; import org.sonar.api.utils.System2; import org.sonar.api.web.UserRole; import org.sonar.db.Dao; @@ -128,10 +127,6 @@ public class PropertiesDao implements Dao { } } - public List<PropertyDto> selectEnabledDescendantModuleProperties(String moduleUuid, DbSession session) { - return getMapper(session).selectDescendantModuleProperties(moduleUuid, Scopes.PROJECT, true); - } - @CheckForNull public PropertyDto selectProjectProperty(long componentId, String propertyKey) { try (DbSession session = mybatis.openSession(false)) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java index be2215d2412..7221069be0e 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java @@ -44,9 +44,6 @@ public interface PropertiesMapper { List<PropertyDto> selectByKeyAndMatchingValue(@Param("key") String key, @Param("value") String value); - List<PropertyDto> selectDescendantModuleProperties(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope, - @Param(value = "excludeDisabled") boolean excludeDisabled); - List<Long> selectIdsByOrganizationAndUser(@Param("organizationUuid") String organizationUuid, @Param("userId") int userId); List<Long> selectIdsByOrganizationAndMatchingLogin(@Param("organizationUuid") String organizationUuid, @Param("login") String login, diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml index 246bc8090d1..f1d4344765e 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml @@ -62,17 +62,6 @@ and r.kee=#{resourceKey,jdbcType=VARCHAR} </select> - <select id="selectDescendantModuleProperties" parameterType="String" resultType="ScrapProperty"> - select - <include refid="columnsToScrapPropertyDto"/> - from - properties p - inner join (select p.id from projects p<include refid="org.sonar.db.component.ComponentMapper.modulesTreeQuery"/>) modules - on modules.id=p.resource_id - where - p.user_id is null - </select> - <select id="selectByKey" parameterType="map" resultType="ScrapProperty"> select <include refid="columnsToScrapPropertyDto"/> diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java index 0c52b4efb7e..0f508819563 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java @@ -40,9 +40,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.organization.OrganizationTesting; import org.sonar.db.user.UserDto; import static com.google.common.collect.Lists.newArrayList; @@ -286,45 +284,6 @@ public class PropertiesDaoTest { } @Test - public void selectEnabledDescendantModuleProperties() { - db.prepareDbUnit(getClass(), "select_module_properties_tree.xml"); - - List<PropertyDto> properties = underTest.selectEnabledDescendantModuleProperties("ABCD", db.getSession()); - assertThat(properties.size()).isEqualTo(4); - assertThat(properties).extracting("key").containsOnly("struts.one", "core.one", "core.two", "data.one"); - assertThat(properties).extracting("value").containsOnly("one", "two"); - - properties = underTest.selectEnabledDescendantModuleProperties("EFGH", db.getSession()); - assertThat(properties.size()).isEqualTo(3); - assertThat(properties).extracting("key").containsOnly("core.one", "core.two", "data.one"); - - properties = underTest.selectEnabledDescendantModuleProperties("FGHI", db.getSession()); - assertThat(properties.size()).isEqualTo(1); - assertThat(properties).extracting("key").containsOnly("data.one"); - - assertThat(underTest.selectEnabledDescendantModuleProperties("unknown-result.xml", db.getSession()).size()).isEqualTo(0); - } - - @Test - @UseDataProvider("allValuesForSelect") - public void selectEnabledDescendantModuleProperties_supports_all_values(String dbValue, String expected) { - String projectUuid = "A"; - ComponentDto project = ComponentTesting.newPrivateProjectDto(OrganizationTesting.newOrganizationDto(), projectUuid); - dbClient.componentDao().insert(session, project); - long projectId = project.getId(); - insertProperty("project.one", dbValue, projectId, null); - - List<PropertyDto> dtos = underTest.selectEnabledDescendantModuleProperties(projectUuid, db.getSession()); - assertThat(dtos) - .hasSize(1); - assertThatDto(dtos.iterator().next()) - .hasKey("project.one") - .hasResourceId(projectId) - .hasNoUserId() - .hasValue(expected); - } - - @Test public void select_by_query() { // global insertProperty("global.one", "one", null, null); diff --git a/server/sonar-db-dao/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml b/server/sonar-db-dao/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml deleted file mode 100644 index 74c6cd30c09..00000000000 --- a/server/sonar-db-dao/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml +++ /dev/null @@ -1,184 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" - prop_key="global.one" - resource_id="[null]" - user_id="[null]" - is_empty="[false]" - text_value="one" - created_at="1555000"/> - <properties id="2" - prop_key="global.two" - resource_id="[null]" - user_id="[null]" - is_empty="[false]" - text_value="two" - created_at="1555000"/> - - <!-- org.struts:struts --> - <properties id="3" - prop_key="struts.one" - resource_id="1" - user_id="[null]" - is_empty="[false]" - text_value="one" - created_at="1555000"/> - - <!-- org.struts:struts-core --> - <properties id="4" - prop_key="core.one" - resource_id="2" - user_id="[null]" - is_empty="[false]" - text_value="one" - created_at="1555000"/> - <properties id="7" - prop_key="core.two" - resource_id="2" - user_id="[null]" - is_empty="[false]" - text_value="two" - created_at="1555000"/> - - <!-- org.struts:struts-data --> - <properties id="8" - prop_key="data.one" - resource_id="3" - user_id="[null]" - is_empty="[false]" - text_value="one" - created_at="1555000"/> - - <!-- user --> - <properties id="5" - prop_key="user.one" - resource_id="[null]" - user_id="100" - is_empty="[false]" - text_value="one" - created_at="1555000"/> - <properties id="6" - prop_key="user.two" - resource_id="1" - user_id="102" - is_empty="[false]" - text_value="two" - created_at="1555000"/> - - - <!-- root project --> - <projects organization_uuid="org1" - uuid="ABCD" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="[null]" - module_uuid_path="." - description="the description" - private="[false]" - long_name="Apache Struts" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="[null]" - authorization_updated_at="[null]" - id="1" - root_uuid="ABCD" - scope="PRJ" - qualifier="TRK" - kee="org.struts:struts" - name="Struts"/> - - <!-- module --> - <projects organization_uuid="org1" - uuid="EFGH" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="[null]" - module_uuid_path=".ABCD." - scope="PRJ" - qualifier="BRC" - long_name="Struts Core" - description="[null]" - private="[false]" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - authorization_updated_at="[null]" - id="2" - root_uuid="ABCD" - kee="org.struts:struts-core" - name="Struts Core"/> - - <!-- sub module --> - <projects organization_uuid="org1" - uuid="FGHI" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="EFGH" - module_uuid_path=".ABCD.EFGH." - scope="PRJ" - qualifier="BRC" - long_name="Struts Data" - description="[null]" - private="[false]" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - authorization_updated_at="[null]" - id="3" - root_uuid="ABCD" - kee="org.struts:struts-data" - name="Struts Data"/> - - <!-- directory --> - <projects organization_uuid="org1" - uuid="GHIJ" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="FGHI" - module_uuid_path=".ABCD.EFGH.FGHI." - name="src/org/struts" - root_uuid="FGHI" - description="[null]" - private="[false]" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="src/org/struts" - authorization_updated_at="[null]" - long_name="org.struts" - id="4" - scope="DIR" - qualifier="DIR" - kee="org.struts:struts-core:src/org/struts"/> - - <!-- file --> - <projects organization_uuid="org1" - uuid="HIJK" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="GHIJ" - module_uuid_path=".ABCD.EFGH.FGHI." - name="RequestContext.java" - root_uuid="FGHI" - description="[null]" - private="[false]" - enabled="[true]" - language="java" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="src/org/struts/RequestContext.java" - authorization_updated_at="[null]" - long_name="org.struts.RequestContext" - id="5" - scope="FIL" - qualifier="FIL" - kee="org.struts:struts-core:src/org/struts/RequestContext.java"/> - - -</dataset> diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java index 2d6439ec78b..35d8f53b231 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java @@ -95,7 +95,7 @@ public class ProjectAction implements BatchWsAction { @Override public void handle(Request wsRequest, Response wsResponse) throws Exception { ProjectRepositories data = projectDataLoader.load(ProjectDataQuery.create() - .setModuleKey(wsRequest.mandatoryParam(PARAM_KEY)) + .setProjectKey(wsRequest.mandatoryParam(PARAM_KEY)) .setProfileName(wsRequest.param(PARAM_PROFILE)) .setIssuesMode(wsRequest.mandatoryParamAsBoolean(PARAM_ISSUES_MODE)) .setBranch(wsRequest.param(PARAM_BRANCH)) @@ -111,8 +111,6 @@ public class ProjectAction implements BatchWsAction { response.setTimestamp(data.timestamp()); response.getMutableFileDataByModuleAndPath() .putAll(buildFileDataByModuleAndPath(data)); - response.getMutableSettingsByModule() - .putAll(buildSettingsByModule(data)); return response.build(); } @@ -141,27 +139,6 @@ public class ProjectAction implements BatchWsAction { return response.build(); } - private static Map<String, WsProjectResponse.Settings> buildSettingsByModule(ProjectRepositories data) { - Map<String, WsProjectResponse.Settings> settingsByModuleResponse = new HashMap<>(); - for (Map.Entry<String, Map<String, String>> moduleSettingsEntry : data.settings().entrySet()) { - settingsByModuleResponse.put( - moduleSettingsEntry.getKey(), - toSettingsResponse(moduleSettingsEntry.getValue())); - } - - return settingsByModuleResponse; - } - - private static WsProjectResponse.Settings toSettingsResponse(Map<String, String> settings) { - WsProjectResponse.Settings.Builder settingsResponse = WsProjectResponse.Settings - .newBuilder(); - settingsResponse - .getMutableSettings() - .putAll(settings); - - return settingsResponse.build(); - } - private static WsProjectResponse.FileData toFileDataResponse(FileData fileData) { Builder fileDataBuilder = WsProjectResponse.FileData.newBuilder(); setNullable(fileData.hash(), fileDataBuilder::setHash); diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java index b00dc25c52a..7808454455a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java @@ -19,38 +19,26 @@ */ package org.sonar.server.batch; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Set; import javax.annotation.Nullable; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.Scopes; import org.sonar.api.server.ServerSide; import org.sonar.api.web.UserRole; -import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.FilePathWithHashDto; import org.sonar.db.permission.OrganizationPermission; -import org.sonar.db.property.PropertyDto; import org.sonar.scanner.protocol.input.FileData; import org.sonar.scanner.protocol.input.ProjectRepositories; import org.sonar.server.component.ComponentFinder; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.user.UserSession; -import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; import static org.sonar.api.web.UserRole.USER; -import static org.sonar.core.util.stream.MoreCollectors.index; -import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; import static org.sonar.server.ws.WsUtils.checkRequest; @ServerSide @@ -69,28 +57,20 @@ public class ProjectDataLoader { public ProjectRepositories load(ProjectDataQuery query) { try (DbSession session = dbClient.openSession(false)) { ProjectRepositories data = new ProjectRepositories(); - String moduleKey = query.getModuleKey(); + String projectKey = query.getProjectKey(); String branch = query.getBranch(); String pullRequest = query.getPullRequest(); - ComponentDto mainModule = componentFinder.getByKey(session, moduleKey); - checkRequest(isProjectOrModule(mainModule), "Key '%s' belongs to a component which is not a Project", moduleKey); - boolean hasScanPerm = userSession.hasComponentPermission(UserRole.SCAN, mainModule) || - userSession.hasPermission(OrganizationPermission.SCAN, mainModule.getOrganizationUuid()); - boolean hasBrowsePerm = userSession.hasComponentPermission(USER, mainModule); + ComponentDto project = componentFinder.getByKey(session, projectKey); + checkRequest(project.isRootProject(), "Key '%s' belongs to a component which is not a Project", projectKey); + boolean hasScanPerm = userSession.hasComponentPermission(UserRole.SCAN, project) || + userSession.hasPermission(OrganizationPermission.SCAN, project.getOrganizationUuid()); + boolean hasBrowsePerm = userSession.hasComponentPermission(USER, project); checkPermission(query.isIssuesMode(), hasScanPerm, hasBrowsePerm); - ComponentDto branchOrMainModule = (branch == null && pullRequest == null) ? mainModule - : componentFinder.getByKeyAndOptionalBranchOrPullRequest(session, moduleKey, branch, pullRequest); - - ComponentDto project = getProject(branchOrMainModule, session); - if (!project.getKey().equals(branchOrMainModule.getKey())) { - addSettings(data, branchOrMainModule.getKey(), getSettingsFromParents(branchOrMainModule, hasScanPerm, session)); - } + ComponentDto branchOrMainModule = (branch == null && pullRequest == null) ? project + : componentFinder.getByKeyAndOptionalBranchOrPullRequest(session, projectKey, branch, pullRequest); List<ComponentDto> modulesTree = dbClient.componentDao().selectEnabledDescendantModules(session, branchOrMainModule.uuid()); - List<PropertyDto> modulesTreeSettings = dbClient.propertiesDao().selectEnabledDescendantModuleProperties(mainModule.uuid(), session); - TreeModuleSettings treeModuleSettings = new TreeModuleSettings(session, modulesTree, modulesTreeSettings); - addSettingsToChildrenModules(data, moduleKey, Maps.newHashMap(), treeModuleSettings, hasScanPerm); List<FilePathWithHashDto> files = searchFilesWithHashAndRevision(session, branchOrMainModule); addFileData(data, modulesTree, files); @@ -102,13 +82,6 @@ public class ProjectDataLoader { } } - private static boolean isProjectOrModule(ComponentDto module) { - if (!Scopes.PROJECT.equals(module.scope())) { - return false; - } - return Qualifiers.PROJECT.equals(module.qualifier()) || Qualifiers.MODULE.equals(module.qualifier()); - } - private List<FilePathWithHashDto> searchFilesWithHashAndRevision(DbSession session, @Nullable ComponentDto module) { if (module == null) { return Collections.emptyList(); @@ -117,72 +90,6 @@ public class ProjectDataLoader { : dbClient.componentDao().selectEnabledDescendantFiles(session, module.uuid()); } - private ComponentDto getProject(ComponentDto module, DbSession session) { - if (!module.isRootProject()) { - return dbClient.componentDao().selectOrFailByUuid(session, module.projectUuid()); - } else { - return module; - } - } - - private Map<String, String> getSettingsFromParents(ComponentDto module, boolean hasScanPerm, DbSession session) { - List<ComponentDto> parents = newArrayList(); - aggregateParentModules(module, parents, session); - Collections.reverse(parents); - - Map<String, String> parentProperties = newHashMap(); - for (ComponentDto parent : parents) { - parentProperties.putAll(getPropertiesMap(dbClient.propertiesDao().selectProjectProperties(session, parent.getKey()), hasScanPerm)); - } - return parentProperties; - } - - private void aggregateParentModules(ComponentDto component, List<ComponentDto> parents, DbSession session) { - String moduleUuid = component.moduleUuid(); - if (moduleUuid != null) { - ComponentDto parent = dbClient.componentDao().selectOrFailByUuid(session, moduleUuid); - if (parent != null) { - parents.add(parent); - aggregateParentModules(parent, parents, session); - } - } - } - - private static void addSettingsToChildrenModules(ProjectRepositories ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings, - boolean hasScanPerm) { - 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); - } - } - - private static void addSettings(ProjectRepositories ref, String module, Map<String, String> properties) { - if (!properties.isEmpty()) { - ref.addSettings(module, properties); - } - } - - private static 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 static void addFileData(ProjectRepositories data, List<ComponentDto> moduleChildren, List<FilePathWithHashDto> files) { Map<String, String> moduleKeysByUuid = newHashMap(); for (ComponentDto module : moduleChildren) { @@ -208,29 +115,4 @@ public class ProjectDataLoader { } } - private class TreeModuleSettings { - - private Map<String, ComponentDto> modulesByKey; - private Multimap<String, PropertyDto> propertiesByModuleKey; - private Multimap<String, ComponentDto> moduleChildrenByModuleUuid; - - private TreeModuleSettings(DbSession session, List<ComponentDto> moduleChildren, List<PropertyDto> moduleChildrenSettings) { - modulesByKey = moduleChildren.stream().collect(uniqueIndex(ComponentDto::getKey)); - moduleChildrenByModuleUuid = ArrayListMultimap.create(); - - Set<Long> propertiesByComponentId = moduleChildrenSettings.stream().map(PropertyDto::getResourceId).collect(MoreCollectors.toSet()); - Map<Long, ComponentDto> componentsById = dbClient.componentDao().selectByIds(session, propertiesByComponentId).stream().collect(uniqueIndex(ComponentDto::getId)); - propertiesByModuleKey = moduleChildrenSettings.stream().collect(index(s -> componentsById.get(s.getResourceId()).getKey())); - moduleChildrenByModuleUuid = moduleChildren.stream().filter(c -> c.moduleUuid() != null).collect(index(ComponentDto::moduleUuid)); - } - - List<PropertyDto> findModuleSettings(String moduleKey) { - return ImmutableList.copyOf(propertiesByModuleKey.get(moduleKey)); - } - - List<ComponentDto> findChildrenModule(String moduleKey) { - String moduleUuid = modulesByKey.get(moduleKey).uuid(); - return ImmutableList.copyOf(moduleChildrenByModuleUuid.get(moduleUuid)); - } - } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataQuery.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataQuery.java index 1434d15e2ed..f39c878eea8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataQuery.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataQuery.java @@ -24,7 +24,7 @@ import javax.annotation.Nullable; public class ProjectDataQuery { - private String projectOrModuleKey; + private String projectKey; private String profileName; private boolean issuesMode; private String branch; @@ -53,12 +53,12 @@ public class ProjectDataQuery { return this; } - public String getModuleKey() { - return projectOrModuleKey; + public String getProjectKey() { + return projectKey; } - public ProjectDataQuery setModuleKey(String projectOrModuleKey) { - this.projectOrModuleKey = projectOrModuleKey; + public ProjectDataQuery setProjectKey(String projectKey) { + this.projectKey = projectKey; return this; } diff --git a/server/sonar-server/src/main/resources/org/sonar/server/batch/project-example.json b/server/sonar-server/src/main/resources/org/sonar/server/batch/project-example.json index dd77d81df79..2d2be1c3c90 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/batch/project-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/batch/project-example.json @@ -1,6 +1,5 @@ { "timestamp": 0, - "settingsByModule": {}, "fileDataByModuleAndPath": { "com.sonarsource:java-markdown": { "src/test/java/com/sonarsource/markdown/impl/RuleBuilderTest.java": { diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java index 92dbe864348..daa57b7d572 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java @@ -43,7 +43,6 @@ public class ProjectActionTest { String projectKey = "org.codehaus.sonar:sonar"; ProjectRepositories projectReferentials = mock(ProjectRepositories.class); - when(projectReferentials.toJson()).thenReturn("{\"settingsByModule\": {}}"); ArgumentCaptor<ProjectDataQuery> queryArgumentCaptor = ArgumentCaptor.forClass(ProjectDataQuery.class); when(projectDataLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials); @@ -54,9 +53,9 @@ public class ProjectActionTest { .setParam("profile", "Default") .setParam("preview", "false") .execute(); - assertJson(response.getInput()).isSimilarTo("{\"settingsByModule\": {}}"); + assertJson(response.getInput()).isSimilarTo("{\"fileDataByModuleAndPath\": {}}"); - assertThat(queryArgumentCaptor.getValue().getModuleKey()).isEqualTo(projectKey); + assertThat(queryArgumentCaptor.getValue().getProjectKey()).isEqualTo(projectKey); assertThat(queryArgumentCaptor.getValue().getProfileName()).isEqualTo("Default"); assertThat(queryArgumentCaptor.getValue().isIssuesMode()).isFalse(); assertThat(queryArgumentCaptor.getValue().getBranch()).isEqualTo("my_branch"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java index 4ef77f6cfc4..3b950cd23a4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java @@ -19,8 +19,6 @@ */ package org.sonar.server.batch; -import com.google.common.collect.ImmutableMap; -import java.util.Map; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -32,10 +30,8 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; import org.sonar.db.component.ResourceTypesRule; import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.property.PropertyDto; import org.sonar.db.source.FileSourceDto; import org.sonar.scanner.protocol.input.FileData; import org.sonar.scanner.protocol.input.ProjectRepositories; @@ -48,10 +44,8 @@ import org.sonar.server.tester.UserSessionRule; import static com.google.common.collect.ImmutableList.of; import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; import static org.junit.Assert.fail; import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; -import static org.sonar.db.component.ComponentDto.generateBranchKey; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newModuleDto; import static org.sonar.db.permission.OrganizationPermission.SCAN; @@ -71,448 +65,6 @@ public class ProjectDataLoaderTest { private ProjectDataLoader underTest = new ProjectDataLoader(dbClient, userSession, new ComponentFinder(dbClient, resourceTypes)); @Test - public void return_project_settings_with_global_scan_permission() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - // Project properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); - - Map<String, String> projectSettings = ref.settings(project.getKey()); - assertThat(projectSettings).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR", - "sonar.jira.login.secured", "john")); - } - - @Test - public void return_project_settings_with_project_scan_permission() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn("john").addProjectPermission(SCAN_EXECUTION, project); - - // Project properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); - - Map<String, String> projectSettings = ref.settings(project.getKey()); - assertThat(projectSettings).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR", - "sonar.jira.login.secured", "john")); - } - - @Test - public void not_returned_secured_settings_when_logged_but_no_scan_permission() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn("john").addProjectPermission(UserRole.USER, project); - - // Project properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey()).setIssuesMode(true)); - Map<String, String> projectSettings = ref.settings(project.getKey()); - assertThat(projectSettings).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR")); - } - - @Test - public void return_project_with_module_settings() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - - // Project properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - - ComponentDto module = ComponentTesting.newModuleDto(project); - dbClient.componentDao().insert(dbSession, module); - - // Module properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId())); - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId())); - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); - assertThat(ref.settings(project.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR", - "sonar.jira.login.secured", "john")); - assertThat(ref.settings(module.getKey())).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() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - - // Project properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - - ComponentDto module = ComponentTesting.newModuleDto(project); - dbClient.componentDao().insert(dbSession, module); - - // No property on module -> should have the same as project - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); - assertThat(ref.settings(project.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR", - "sonar.jira.login.secured", "john")); - assertThat(ref.settings(module.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR", - "sonar.jira.login.secured", "john")); - } - - @Test - public void return_project_with_module_with_sub_module() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - - // Project properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - - ComponentDto module = ComponentTesting.newModuleDto(project); - dbClient.componentDao().insert(dbSession, module); - - // Module properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId())); - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId())); - - ComponentDto subModule = ComponentTesting.newModuleDto(module); - dbClient.componentDao().insert(dbSession, subModule); - - // Sub module properties - dbClient.propertiesDao().saveProperty( - dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER-DAO").setResourceId(subModule.getId())); - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); - assertThat(ref.settings(project.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR", - "sonar.jira.login.secured", "john")); - assertThat(ref.settings(module.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR-SERVER", - "sonar.jira.login.secured", "john", - "sonar.coverage.exclusions", "**/*.java")); - assertThat(ref.settings(subModule.getKey())).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() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - - // Project properties - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - - ComponentDto module1 = ComponentTesting.newModuleDto(project); - dbClient.componentDao().insert(dbSession, module1); - - // Module 1 properties - dbClient.propertiesDao() - .saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module1.getId())); - // This property should not be found on the other module - dbClient.propertiesDao() - .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module1.getId())); - - ComponentDto module2 = ComponentTesting.newModuleDto(project); - dbClient.componentDao().insert(dbSession, module2); - - // Module 2 property - dbClient.propertiesDao() - .saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION").setResourceId(module2.getId())); - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); - assertThat(ref.settings(project.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR", - "sonar.jira.login.secured", "john")); - assertThat(ref.settings(module1.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR-SERVER", - "sonar.jira.login.secured", "john", - "sonar.coverage.exclusions", "**/*.java")); - assertThat(ref.settings(module2.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR-APPLICATION", - "sonar.jira.login.secured", "john")); - } - - @Test - public void return_provisioned_project_settings() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - - // Project properties - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); - assertThat(ref.settings(project.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR", - "sonar.jira.login.secured", "john")); - } - - @Test - public void return_sub_module_settings() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - // No project properties - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - // No module properties - - // Sub module properties - ComponentDto subModule = db.components().insertComponent(newModuleDto(module)); - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId())); - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId())); - dbClient.propertiesDao() - .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId())); - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getKey())); - assertThat(ref.settings(project.getKey())).isEmpty(); - assertThat(ref.settings(module.getKey())).isEmpty(); - assertThat(ref.settings(subModule.getKey())).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() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - - // Project property - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - - ComponentDto module = ComponentTesting.newModuleDto(project); - dbClient.componentDao().insert(dbSession, module); - - // Module property - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId())); - - ComponentDto subModule = ComponentTesting.newModuleDto(module); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - dbClient.componentDao().insert(dbSession, subModule); - - // Sub module properties - dbClient.propertiesDao() - .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId())); - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getKey())); - assertThat(ref.settings(project.getKey())).isEmpty(); - assertThat(ref.settings(module.getKey())).isEmpty(); - assertThat(ref.settings(subModule.getKey())).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() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - - // Project properties - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - dbClient.propertiesDao() - .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId())); - - ComponentDto module = ComponentTesting.newModuleDto(project); - dbClient.componentDao().insert(dbSession, module); - // No module property - - ComponentDto subModule = ComponentTesting.newModuleDto(module); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - dbClient.componentDao().insert(dbSession, subModule); - // No sub module property - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getKey())); - assertThat(ref.settings(project.getKey())).isEmpty(); - assertThat(ref.settings(module.getKey())).isEmpty(); - assertThat(ref.settings(subModule.getKey())).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() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - - // Project properties - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - dbClient.propertiesDao() - .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId())); - - ComponentDto module = ComponentTesting.newModuleDto(project); - dbClient.componentDao().insert(dbSession, module); - - // Module property - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId())); - - ComponentDto subModule = ComponentTesting.newModuleDto(module); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - dbClient.componentDao().insert(dbSession, subModule); - // No sub module property - - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getKey())); - assertThat(ref.settings(project.getKey())).isEmpty(); - assertThat(ref.settings(module.getKey())).isEmpty(); - assertThat(ref.settings(subModule.getKey())).isEqualTo(ImmutableMap.of( - "sonar.jira.project.key", "SONAR-SERVER", - "sonar.jira.login.secured", "john", - "sonar.coverage.exclusions", "**/*.java")); - } - - @Test - public void return_project_settings_from_project_when_using_branch_parameter() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - db.properties().insertProperties(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create() - .setModuleKey(project.getKey()) - .setBranch("my_branch")); - - assertThat(project.getKey()).isEqualTo(branch.getKey()); - assertThat(ref.settings(project.getKey())).containsExactly(entry("sonar.jira.project.key", "SONAR")); - } - - @Test - public void return_project_with_module_settings_when_using_branch_parameter() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); - ComponentDto moduleBranch = db.components().insertComponent(newModuleDto(branch).setDbKey(generateBranchKey(module.getKey(), "my_branch"))); - // Project properties - db.properties().insertProperties( - new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), - new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - // Module properties - db.properties().insertProperties( - new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()), - new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId())); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create() - .setModuleKey(project.getKey()) - .setBranch("my_branch")); - - assertThat(ref.settings(branch.getKey())).containsOnly( - entry("sonar.jira.project.key", "SONAR"), - entry("sonar.jira.login.secured", "john")); - assertThat(ref.settings(moduleBranch.getKey())).containsOnly( - entry("sonar.jira.project.key", "SONAR-SERVER"), - entry("sonar.jira.login.secured", "john"), - entry("sonar.coverage.exclusions", "**/*.java")); - } - - @Test - public void return_settings_from_project_when_module_is_only_in_branch() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); - // This module does not exist on master - ComponentDto moduleBranch = db.components().insertComponent(newModuleDto(branch)); - db.properties().insertProperties( - new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), - new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create() - .setModuleKey(project.getKey()) - .setBranch("my_branch")); - - assertThat(ref.settings(moduleBranch.getKey())).containsOnly( - entry("sonar.jira.project.key", "SONAR"), - entry("sonar.jira.login.secured", "john")); - } - - @Test - public void return_sub_module_settings_when_using_branch_parameter() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - ComponentDto subModule = db.components().insertComponent(newModuleDto(module)); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); - ComponentDto moduleBranch = db.components().insertComponent(newModuleDto(branch).setDbKey(generateBranchKey(module.getKey(), "my_branch"))); - ComponentDto subModuleBranch = db.components().insertComponent(newModuleDto(moduleBranch).setDbKey(generateBranchKey(subModule.getKey(), "my_branch"))); - // Sub module properties - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId())); - dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId())); - dbClient.propertiesDao() - .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId())); - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModuleBranch.getKey())); - - assertThat(ref.settings(branch.getKey())).isEmpty(); - assertThat(ref.settings(moduleBranch.getKey())).isEmpty(); - assertThat(ref.settings(subModuleBranch.getKey())).containsOnly( - entry("sonar.jira.project.key", "SONAR"), - entry("sonar.jira.login.secured", "john"), - entry("sonar.coverage.exclusions", "**/*.java")); - } - - @Test public void throws_NotFoundException_when_branch_does_not_exist() { OrganizationDto organizationDto = db.organizations().insert(); ComponentDto project = db.components().insertPrivateProject(organizationDto); @@ -522,7 +74,7 @@ public class ProjectDataLoaderTest { expectedException.expectMessage(format("Component '%s' on branch '%s' not found", project.getKey(), "unknown_branch")); underTest.load(ProjectDataQuery.create() - .setModuleKey(project.getKey()) + .setProjectKey(project.getKey()) .setBranch("unknown_branch")); } @@ -535,7 +87,7 @@ public class ProjectDataLoaderTest { dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(file).setSrcHash("123456")); db.commit(); - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); + ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey())); assertThat(ref.fileDataByPath(project.getKey())).hasSize(1); FileData fileData = ref.fileData(project.getKey(), file.path()); @@ -556,34 +108,13 @@ public class ProjectDataLoaderTest { dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456")); dbSession.commit(); - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); + ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey())); assertThat(ref.fileData(project.getKey(), projectFile.path()).hash()).isEqualTo("123456"); assertThat(ref.fileData(module.getKey(), moduleFile.path()).hash()).isEqualTo("789456"); } @Test - public void return_file_data_from_module() { - OrganizationDto organizationDto = db.organizations().insert(); - ComponentDto project = db.components().insertPrivateProject(organizationDto); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); - ComponentDto module = db.components().insertComponent(newModuleDto(project)); - // File on project - ComponentDto projectFile = db.components().insertComponent(newFileDto(project)); - dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456")); - // File on module - ComponentDto moduleFile = db.components().insertComponent(newFileDto(module)); - dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456")); - dbSession.commit(); - - ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(module.getKey())); - - assertThat(ref.fileData(module.getKey(), moduleFile.path()).hash()).isEqualTo("789456"); - assertThat(ref.fileData(module.getKey(), moduleFile.path()).revision()).isEqualTo("123456789"); - assertThat(ref.fileData(project.getKey(), projectFile.path())).isNull(); - } - - @Test public void return_file_data_from_branch() { OrganizationDto organizationDto = db.organizations().insert(); ComponentDto project = db.components().insertPrivateProject(organizationDto); @@ -599,7 +130,7 @@ public class ProjectDataLoaderTest { dbSession.commit(); ProjectRepositories ref = underTest.load(ProjectDataQuery.create() - .setModuleKey(project.getKey()) + .setProjectKey(project.getKey()) .setBranch("my_branch")); assertThat(ref.fileData(branch.getKey(), projectFile.path()).hash()).isEqualTo("123456"); @@ -628,27 +159,22 @@ public class ProjectDataLoaderTest { expectedException.expect(NotFoundException.class); expectedException.expectMessage("Component key 'theKey' not found"); - underTest.load(ProjectDataQuery.create().setModuleKey(key)); + underTest.load(ProjectDataQuery.create().setProjectKey(key)); } @Test - public void fails_with_BRE_if_component_is_neither_a_project_or_a_module() { + public void fails_with_BRE_if_component_is_not_a_project() { String[][] allScopesAndQualifierButProjectAndModule = { - {Scopes.PROJECT, Qualifiers.VIEW}, - {Scopes.PROJECT, Qualifiers.SUBVIEW}, - {Scopes.PROJECT, Qualifiers.APP}, - {Scopes.FILE, Qualifiers.PROJECT}, - {Scopes.DIRECTORY, Qualifiers.DIRECTORY}, - {Scopes.FILE, Qualifiers.UNIT_TEST_FILE}, - {Scopes.PROJECT, "DEV"}, - {Scopes.PROJECT, "DEV_PRJ"} + {Scopes.PROJECT, "fakeModuleUuid"}, + {Scopes.FILE, null}, + {Scopes.DIRECTORY, null} }; OrganizationDto organizationDto = db.organizations().insert(); for (String[] scopeAndQualifier : allScopesAndQualifierButProjectAndModule) { String scope = scopeAndQualifier[0]; - String qualifier = scopeAndQualifier[1]; - String key = "theKey_" + scope + "_" + qualifier; + String moduleUuid = scopeAndQualifier[1]; + String key = "theKey_" + scope + "_" + moduleUuid; String uuid = "uuid_" + uuidCounter++; dbClient.componentDao().insert(dbSession, new ComponentDto() .setOrganizationUuid(organizationDto.getUuid()) @@ -657,13 +183,13 @@ public class ProjectDataLoaderTest { .setRootUuid(uuid) .setProjectUuid(uuid) .setScope(scope) - .setQualifier(qualifier) + .setModuleUuid(moduleUuid) .setDbKey(key)); dbSession.commit(); try { - underTest.load(ProjectDataQuery.create().setModuleKey(key)); - fail(format("A NotFoundException should have been raised because scope (%s) or qualifier (%s) is not project", scope, qualifier)); + underTest.load(ProjectDataQuery.create().setProjectKey(key)); + fail("A NotFoundException should have been raised because component is not project"); } catch (BadRequestException e) { assertThat(e).hasMessage("Key '" + key + "' belongs to a component which is not a Project"); } @@ -678,7 +204,7 @@ public class ProjectDataLoaderTest { expectedException.expect(ForbiddenException.class); expectedException.expectMessage("You're not authorized to execute any SonarQube analysis"); - underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); + underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey())); } @Test @@ -689,7 +215,7 @@ public class ProjectDataLoaderTest { expectedException.expect(ForbiddenException.class); expectedException.expectMessage("You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server"); - underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey())); + underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey())); } @Test @@ -697,7 +223,7 @@ public class ProjectDataLoaderTest { ComponentDto project = db.components().insertPrivateProject(); userSession.logIn().addProjectPermission(UserRole.USER, project); - ProjectRepositories repositories = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey()).setIssuesMode(true)); + ProjectRepositories repositories = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()).setIssuesMode(true)); assertThat(repositories).isNotNull(); } @@ -710,7 +236,7 @@ public class ProjectDataLoaderTest { expectedException.expect(ForbiddenException.class); expectedException.expectMessage("You don't have the required permissions to access this project"); - underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey()).setIssuesMode(true)); + underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()).setIssuesMode(true)); } @Test @@ -719,7 +245,7 @@ public class ProjectDataLoaderTest { userSession.logIn().addPermission(SCAN, project.getOrganizationUuid()); userSession.logIn().addProjectPermission(UserRole.USER, project); - ProjectRepositories repositories = underTest.load(ProjectDataQuery.create().setModuleKey(project.getKey()).setIssuesMode(true)); + ProjectRepositories repositories = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()).setIssuesMode(true)); assertThat(repositories).isNotNull(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java index 5a51ac54179..e8f14949d0b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java @@ -97,8 +97,7 @@ public class ValuesActionTest { @Before public void setUp() throws Exception { - OrganizationDto organizationDto = db.organizations().insert(); - project = componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(organizationDto)); + project = componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert())); } @Test @@ -566,7 +565,7 @@ public class ValuesActionTest { } @Test - public void return_component_secured_settings_when_not_authenticated_but_with_scan_permission() { + public void return_component_secured_settings_when_not_authenticated_but_with_project_scan_permission() { userSession .addProjectPermission(USER, project) .addProjectPermission(SCAN_EXECUTION, project); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfiguration.java index eb5c23b442a..a9fa6e899b7 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfiguration.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalConfiguration.java @@ -21,8 +21,6 @@ package org.sonar.scanner.bootstrap; import java.util.Map; import javax.annotation.concurrent.Immutable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.api.config.Encryption; import org.sonar.api.config.PropertyDefinitions; import org.sonar.scanner.config.DefaultConfiguration; @@ -30,8 +28,6 @@ import org.sonar.scanner.config.DefaultConfiguration; @Immutable public class GlobalConfiguration extends DefaultConfiguration { - private static final Logger LOG = LoggerFactory.getLogger(GlobalConfiguration.class); - public GlobalConfiguration(PropertyDefinitions propertyDefinitions, Encryption encryption, GlobalAnalysisMode mode, Map<String, String> settings) { super(propertyDefinitions, encryption, mode, settings); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClient.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClient.java index a6def248ce2..e04de9c05d9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClient.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClient.java @@ -101,8 +101,10 @@ public class ScannerWsClient { "Please provide the values of the properties %s and %s.", CoreProperties.LOGIN, CoreProperties.PASSWORD)); } - if (code == HTTP_FORBIDDEN || code == HTTP_BAD_REQUEST) { - // SONAR-4397 Details are in response content + if (code == HTTP_FORBIDDEN) { + throw MessageException.of("You're not authorized to run analysis. Please contact the project administrator."); + } + if (code == HTTP_BAD_REQUEST) { String jsonMsg = tryParseAsJsonError(response.content()); if (jsonMsg != null) { throw MessageException.of(jsonMsg); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java index 22977f997a5..c0d091e824b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java @@ -24,7 +24,7 @@ import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.StandardOpenOption; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -43,7 +43,10 @@ import org.sonar.core.platform.PluginInfo; import org.sonar.scanner.bootstrap.GlobalServerSettings; import org.sonar.scanner.bootstrap.ScannerPluginRepository; import org.sonar.scanner.protocol.output.ScannerReportWriter; -import org.sonar.scanner.repository.ProjectRepositories; +import org.sonar.scanner.scan.ProjectServerSettings; +import org.sonar.scanner.scan.filesystem.InputComponentStore; + +import static java.util.stream.Collectors.toList; @ScannerSide public class AnalysisContextReportPublisher { @@ -56,22 +59,24 @@ public class AnalysisContextReportPublisher { private static final String SONAR_PROP_PREFIX = "sonar."; private static final int MAX_WIDTH = 1000; private final ScannerPluginRepository pluginRepo; + private final ProjectServerSettings projectServerSettings; private final AnalysisMode mode; private final System2 system; - private final ProjectRepositories projectRepos; private final GlobalServerSettings globalServerSettings; private final InputModuleHierarchy hierarchy; + private final InputComponentStore store; private ScannerReportWriter writer; - public AnalysisContextReportPublisher(AnalysisMode mode, ScannerPluginRepository pluginRepo, System2 system, - ProjectRepositories projectRepos, GlobalServerSettings globalServerSettings, InputModuleHierarchy hierarchy) { + public AnalysisContextReportPublisher(ProjectServerSettings projectServerSettings, AnalysisMode mode, ScannerPluginRepository pluginRepo, System2 system, + GlobalServerSettings globalServerSettings, InputModuleHierarchy hierarchy, InputComponentStore store) { + this.projectServerSettings = projectServerSettings; this.mode = mode; this.pluginRepo = pluginRepo; this.system = system; - this.projectRepos = projectRepos; this.globalServerSettings = globalServerSettings; this.hierarchy = hierarchy; + this.store = store; } public void init(ScannerReportWriter writer) { @@ -87,6 +92,8 @@ public class AnalysisContextReportPublisher { } writePlugins(fileWriter); writeGlobalSettings(fileWriter); + writeProjectSettings(fileWriter); + writeModulesSettings(fileWriter); } catch (IOException e) { throw new IllegalStateException("Unable to write analysis log", e); } @@ -125,30 +132,40 @@ public class AnalysisContextReportPublisher { } private void writeGlobalSettings(BufferedWriter fileWriter) throws IOException { - fileWriter.append("Global properties:\n"); + fileWriter.append("Global server settings:\n"); Map<String, String> props = globalServerSettings.properties(); for (String prop : new TreeSet<>(props.keySet())) { dumpPropIfNotSensitive(fileWriter, prop, props.get(prop)); } } - public void dumpModuleSettings(DefaultInputModule module) { - if (mode.isIssues()) { - return; + private void writeProjectSettings(BufferedWriter fileWriter) throws IOException { + fileWriter.append("Project server settings:\n"); + Map<String, String> props = projectServerSettings.properties(); + for (String prop : new TreeSet<>(props.keySet())) { + dumpPropIfNotSensitive(fileWriter, prop, props.get(prop)); } + fileWriter.append("Project scanner properties:\n"); + writeScannerProps(fileWriter, hierarchy.root().properties()); + } - File analysisLog = writer.getFileStructure().analysisLog(); - try (BufferedWriter fileWriter = Files.newBufferedWriter(analysisLog.toPath(), StandardCharsets.UTF_8, StandardOpenOption.WRITE, StandardOpenOption.APPEND)) { + private void writeModulesSettings(BufferedWriter fileWriter) throws IOException { + for (DefaultInputModule module : store.allModules()) { + if (module.equals(hierarchy.root())) { + continue; + } Map<String, String> moduleSpecificProps = collectModuleSpecificProps(module); - fileWriter.append(String.format("Settings for module: %s", module.key())).append('\n'); - for (String prop : new TreeSet<>(moduleSpecificProps.keySet())) { - if (isSystemProp(prop) || isEnvVariable(prop) || !isSqProp(prop)) { - continue; - } - dumpPropIfNotSensitive(fileWriter, prop, moduleSpecificProps.get(prop)); + fileWriter.append(String.format("Scanner properties of module: %s", module.key())).append('\n'); + writeScannerProps(fileWriter, moduleSpecificProps); + } + } + + private void writeScannerProps(BufferedWriter fileWriter, Map<String, String> props) throws IOException { + for (Map.Entry<String, String> prop : props.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).collect(toList())) { + if (isSystemProp(prop.getKey()) || isEnvVariable(prop.getKey()) || !isSqProp(prop.getKey())) { + continue; } - } catch (IOException e) { - throw new IllegalStateException("Unable to write analysis log", e); + dumpPropIfNotSensitive(fileWriter, prop.getKey(), prop.getValue()); } } @@ -161,9 +178,6 @@ public class AnalysisContextReportPublisher { */ private Map<String, String> collectModuleSpecificProps(DefaultInputModule module) { Map<String, String> moduleSpecificProps = new HashMap<>(); - if (projectRepos.moduleExists(module.getKeyWithBranch())) { - moduleSpecificProps.putAll(projectRepos.settings(module.getKeyWithBranch())); - } AbstractProjectOrModule parent = hierarchy.parent(module); if (parent == null) { moduleSpecificProps.putAll(module.properties()); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoader.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoader.java index 6a60632e65e..043264de8b3 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoader.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoader.java @@ -37,7 +37,6 @@ import org.sonar.scanner.util.ScannerUtils; import org.sonarqube.ws.Batch; import org.sonarqube.ws.Batch.WsProjectResponse; import org.sonarqube.ws.Batch.WsProjectResponse.FileDataByPath; -import org.sonarqube.ws.Batch.WsProjectResponse.Settings; import org.sonarqube.ws.client.GetRequest; import org.sonarqube.ws.client.HttpException; import org.sonarqube.ws.client.WsResponse; @@ -100,14 +99,6 @@ public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoad WsProjectResponse response = WsProjectResponse.parseFrom(is); Table<String, String, FileData> fileDataTable = HashBasedTable.create(); - Table<String, String, String> settings = HashBasedTable.create(); - - Map<String, Settings> settingsByModule = response.getSettingsByModule(); - for (Map.Entry<String, Settings> e1 : settingsByModule.entrySet()) { - for (Map.Entry<String, String> e2 : e1.getValue().getSettings().entrySet()) { - settings.put(e1.getKey(), e2.getKey(), e2.getValue()); - } - } Map<String, FileDataByPath> fileDataByModuleAndPath = response.getFileDataByModuleAndPath(); for (Map.Entry<String, FileDataByPath> e1 : fileDataByModuleAndPath.entrySet()) { @@ -117,7 +108,7 @@ public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoad } } - return new ProjectRepositories(settings, fileDataTable, new Date(response.getLastAnalysisDate())); + return new ProjectRepositories(fileDataTable, new Date(response.getLastAnalysisDate())); } catch (IOException e) { throw new IllegalStateException("Couldn't load project repository for " + projectKey, e); } finally { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositories.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositories.java index a5fb6901603..bed6c1c2c34 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositories.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositories.java @@ -29,21 +29,18 @@ import javax.annotation.concurrent.Immutable; @Immutable public class ProjectRepositories { - private final ImmutableTable<String, String, String> settingsByModule; private final ImmutableTable<String, String, FileData> fileDataByModuleAndPath; private final Date lastAnalysisDate; private final boolean exists; public ProjectRepositories() { this.exists = false; - this.settingsByModule = new ImmutableTable.Builder<String, String, String>().build(); this.fileDataByModuleAndPath = new ImmutableTable.Builder<String, String, FileData>().build(); this.lastAnalysisDate = null; } - public ProjectRepositories(Table<String, String, String> settingsByModule, Table<String, String, FileData> fileDataByModuleAndPath, - @Nullable Date lastAnalysisDate) { - this.settingsByModule = ImmutableTable.copyOf(settingsByModule); + public ProjectRepositories(Table<String, String, FileData> fileDataByModuleAndPath, + @Nullable Date lastAnalysisDate) { this.fileDataByModuleAndPath = ImmutableTable.copyOf(fileDataByModuleAndPath); this.lastAnalysisDate = lastAnalysisDate; this.exists = true; @@ -61,14 +58,6 @@ public class ProjectRepositories { return fileDataByModuleAndPath; } - public boolean moduleExists(String moduleKey) { - return settingsByModule.containsRow(moduleKey); - } - - public Map<String, String> settings(String moduleKey) { - return settingsByModule.row(moduleKey); - } - @CheckForNull public FileData fileData(String projectKeyWithBranch, String path) { return fileDataByModuleAndPath.get(projectKeyWithBranch, path); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultSettingsLoader.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultSettingsLoader.java index 8c91389eb45..504c61f5c0b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultSettingsLoader.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultSettingsLoader.java @@ -22,7 +22,9 @@ package org.sonar.scanner.repository.settings; import com.google.common.annotations.VisibleForTesting; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -38,6 +40,7 @@ import org.sonarqube.ws.Settings.FieldValues.Value; import org.sonarqube.ws.Settings.Setting; import org.sonarqube.ws.Settings.ValuesWsResponse; import org.sonarqube.ws.client.GetRequest; +import org.sonarqube.ws.client.HttpException; public class DefaultSettingsLoader implements SettingsLoader { @@ -62,8 +65,13 @@ public class DefaultSettingsLoader implements SettingsLoader { ValuesWsResponse values = ValuesWsResponse.parseFrom(is); profiler.stopInfo(); return toMap(values.getSettingsList()); + } catch (HttpException e) { + if (e.code() == HttpURLConnection.HTTP_NOT_FOUND) { + return Collections.emptyMap(); + } + throw e; } catch (IOException e) { - throw new IllegalStateException("Failed to load server settings", e); + throw new IllegalStateException("Unable to load settings", e); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java index 7f03d2cca65..556d09b9184 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java @@ -20,7 +20,6 @@ package org.sonar.scanner.scan; import java.util.ArrayList; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -30,39 +29,24 @@ import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.GlobalConfiguration; import org.sonar.scanner.report.AnalysisContextReportPublisher; -import org.sonar.scanner.repository.ProjectRepositories; public class ModuleConfigurationProvider extends ProviderAdapter { private ModuleConfiguration moduleConfiguration; - public ModuleConfiguration provide(GlobalConfiguration globalConfig, DefaultInputModule module, ProjectRepositories projectRepos, + public ModuleConfiguration provide(GlobalConfiguration globalConfig, DefaultInputModule module, ProjectServerSettings projectServerSettings, GlobalAnalysisMode analysisMode, AnalysisContextReportPublisher contextReportPublisher) { if (moduleConfiguration == null) { Map<String, String> settings = new LinkedHashMap<>(); - settings.putAll(addServerSidePropertiesIfModuleExists(projectRepos, module.definition())); + settings.putAll(projectServerSettings.properties()); addScannerSideProperties(settings, module.definition()); - contextReportPublisher.dumpModuleSettings(module); moduleConfiguration = new ModuleConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), analysisMode, settings); } return moduleConfiguration; } - private static Map<String, String> addServerSidePropertiesIfModuleExists(ProjectRepositories projectRepos, ProjectDefinition def) { - if (projectRepos.moduleExists(def.getKeyWithBranch())) { - return projectRepos.settings(def.getKeyWithBranch()); - } else { - // Module doesn't exist on server. Try to add parent server settings as inheritance. - ProjectDefinition parentDef = def.getParent(); - if (parentDef != null) { - return addServerSidePropertiesIfModuleExists(projectRepos, parentDef); - } - return Collections.emptyMap(); - } - } - private static void addScannerSideProperties(Map<String, String> settings, ProjectDefinition project) { List<ProjectDefinition> orderedProjects = getTopDownParentProjects(project); for (ProjectDefinition p : orderedProjects) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableModuleSettings.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableModuleSettings.java index 11853632ef2..e8b8ceb7864 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableModuleSettings.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableModuleSettings.java @@ -20,15 +20,9 @@ package org.sonar.scanner.scan; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Optional; -import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.Settings; -import org.sonar.api.utils.MessageException; -import org.sonar.scanner.bootstrap.GlobalConfiguration; -import org.sonar.scanner.repository.ProjectRepositories; import static java.util.Objects.requireNonNull; @@ -38,49 +32,15 @@ import static java.util.Objects.requireNonNull; @Deprecated public class MutableModuleSettings extends Settings { - private final ProjectRepositories projectRepos; - private final AnalysisMode analysisMode; private final Map<String, String> properties = new HashMap<>(); - public MutableModuleSettings(GlobalConfiguration globalConfig, ProjectDefinition moduleDefinition, ProjectRepositories projectSettingsRepo, - AnalysisMode analysisMode) { - super(globalConfig.getDefinitions(), globalConfig.getEncryption()); - this.projectRepos = projectSettingsRepo; - this.analysisMode = analysisMode; - - init(moduleDefinition, globalConfig); - } - - private MutableModuleSettings init(ProjectDefinition moduleDefinition, GlobalConfiguration globalConfig) { - addProjectProperties(moduleDefinition, globalConfig); - addBuildProperties(moduleDefinition); - return this; - } - - private void addProjectProperties(ProjectDefinition def, GlobalConfiguration globalConfig) { - addProperties(globalConfig.getProperties()); - do { - if (projectRepos.moduleExists(def.getKeyWithBranch())) { - addProperties(projectRepos.settings(def.getKeyWithBranch())); - break; - } - def = def.getParent(); - } while (def != null); - } - - private void addBuildProperties(ProjectDefinition project) { - List<ProjectDefinition> orderedProjects = ModuleConfigurationProvider.getTopDownParentProjects(project); - for (ProjectDefinition p : orderedProjects) { - addProperties(p.properties()); - } + public MutableModuleSettings(ModuleConfiguration config) { + super(config.getDefinitions(), config.getEncryption()); + addProperties(config.getProperties()); } @Override protected Optional<String> get(String key) { - if (analysisMode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) { - throw MessageException.of("Access to the secured property '" + key - + "' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode."); - } return Optional.ofNullable(properties.get(key)); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectSettings.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectSettings.java index 4d8d3f7a43d..a85e5720303 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectSettings.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/MutableProjectSettings.java @@ -22,12 +22,8 @@ package org.sonar.scanner.scan; import java.util.HashMap; import java.util.Map; import java.util.Optional; -import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.Settings; -import org.sonar.api.utils.MessageException; -import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.GlobalConfiguration; -import org.sonar.scanner.repository.ProjectRepositories; import static java.util.Objects.requireNonNull; @@ -37,23 +33,19 @@ import static java.util.Objects.requireNonNull; @Deprecated public class MutableProjectSettings extends Settings { - private final GlobalAnalysisMode mode; private final Map<String, String> properties = new HashMap<>(); - public MutableProjectSettings(ProjectReactor reactor, GlobalConfiguration globalConfig, ProjectRepositories projectRepositories, GlobalAnalysisMode mode) { + public MutableProjectSettings(GlobalConfiguration globalConfig) { super(globalConfig.getDefinitions(), globalConfig.getEncryption()); - this.mode = mode; addProperties(globalConfig.getProperties()); - addProperties(projectRepositories.settings(reactor.getRoot().getKeyWithBranch())); - addProperties(reactor.getRoot().properties()); + } + + public void complete(ProjectConfiguration projectConfig) { + addProperties(projectConfig.getProperties()); } @Override protected Optional<String> get(String key) { - if (mode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) { - throw MessageException.of("Access to the secured property '" + key - + "' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode."); - } return Optional.ofNullable(properties.get(key)); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java index 9db726d7e75..8c774902e88 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java @@ -22,26 +22,26 @@ package org.sonar.scanner.scan; import java.util.LinkedHashMap; import java.util.Map; import org.picocontainer.injectors.ProviderAdapter; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.GlobalConfiguration; import org.sonar.scanner.bootstrap.GlobalServerSettings; -import org.sonar.scanner.repository.ProjectRepositories; public class ProjectConfigurationProvider extends ProviderAdapter { private ProjectConfiguration projectConfig; - public ProjectConfiguration provide(GlobalServerSettings globalServerSettings, AbstractProjectOrModule project, - GlobalConfiguration globalConfig, ProjectRepositories projectRepositories, GlobalAnalysisMode mode) { + public ProjectConfiguration provide(DefaultInputProject project, GlobalConfiguration globalConfig, GlobalServerSettings globalServerSettings, ProjectServerSettings projectServerSettings, + GlobalAnalysisMode mode, MutableProjectSettings projectSettings) { if (projectConfig == null) { Map<String, String> settings = new LinkedHashMap<>(); settings.putAll(globalServerSettings.properties()); - settings.putAll(projectRepositories.settings(project.getKeyWithBranch())); + settings.putAll(projectServerSettings.properties()); settings.putAll(project.properties()); projectConfig = new ProjectConfiguration(globalConfig.getDefinitions(), globalConfig.getEncryption(), mode, settings); + projectSettings.complete(projectConfig); } return projectConfig; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java index 7e595179de1..0079aedb077 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java @@ -150,6 +150,7 @@ public class ProjectScanContainer extends ComponentContainer { new ProjectPullRequestsProvider(), DefaultAnalysisMode.class, new ProjectRepositoriesProvider(), + new ProjectServerSettingsProvider(), // temp new AnalysisTempFolderProvider(), diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettings.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettings.java new file mode 100644 index 00000000000..c1e096283ca --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettings.java @@ -0,0 +1,46 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.scan; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import javax.annotation.concurrent.Immutable; + +/** + * Project settings coming from the server. Does not contain global settings. + */ +@Immutable +public class ProjectServerSettings { + + private final Map<String, String> properties; + + public ProjectServerSettings(Map<String, String> properties) { + this.properties = properties; + } + + public Map<String, String> properties() { + return ImmutableMap.copyOf(properties); + } + + public String property(String key) { + return properties.get(key); + } + +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettingsProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettingsProvider.java new file mode 100644 index 00000000000..2a85f416445 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectServerSettingsProvider.java @@ -0,0 +1,38 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.scanner.scan; + +import java.util.Map; +import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.scanner.bootstrap.ScannerProperties; +import org.sonar.scanner.repository.settings.SettingsLoader; + +public class ProjectServerSettingsProvider extends ProviderAdapter { + + private ProjectServerSettings singleton; + + public ProjectServerSettings provide(SettingsLoader loader, ScannerProperties scannerProperties) { + if (singleton == null) { + Map<String, String> serverSideSettings = loader.load(scannerProperties.getKeyWithBranch()); + singleton = new ProjectServerSettings(serverSideSettings); + } + return singleton; + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfigurationProvider.java index a1c78fc65dd..ab450cbedef 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfigurationProvider.java @@ -22,7 +22,6 @@ package org.sonar.scanner.scan.branch; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; - import org.picocontainer.annotations.Nullable; import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.bootstrap.ProjectDefinition; @@ -31,7 +30,8 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.scanner.bootstrap.GlobalConfiguration; -import org.sonar.scanner.repository.settings.SettingsLoader; +import org.sonar.scanner.bootstrap.GlobalServerSettings; +import org.sonar.scanner.scan.ProjectServerSettings; public class BranchConfigurationProvider extends ProviderAdapter { @@ -41,13 +41,14 @@ public class BranchConfigurationProvider extends ProviderAdapter { private BranchConfiguration branchConfiguration = null; public BranchConfiguration provide(@Nullable BranchConfigurationLoader loader, GlobalConfiguration globalConfiguration, ProjectReactor reactor, - SettingsLoader settingsLoader, ProjectBranches branches, ProjectPullRequests pullRequests) { + GlobalServerSettings globalServerSettings, ProjectServerSettings projectServerSettings, + ProjectBranches branches, ProjectPullRequests pullRequests) { if (branchConfiguration == null) { if (loader == null) { branchConfiguration = new DefaultBranchConfiguration(); } else { Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - Supplier<Map<String, String>> settingsSupplier = createSettingsSupplier(globalConfiguration, reactor.getRoot(), settingsLoader); + Supplier<Map<String, String>> settingsSupplier = createSettingsSupplier(reactor.getRoot(), globalServerSettings, projectServerSettings); branchConfiguration = loader.load(globalConfiguration.getProperties(), settingsSupplier, branches, pullRequests); profiler.stopInfo(); } @@ -55,13 +56,14 @@ public class BranchConfigurationProvider extends ProviderAdapter { return branchConfiguration; } - private static Supplier<Map<String, String>> createSettingsSupplier(GlobalConfiguration globalConfiguration, ProjectDefinition root, SettingsLoader settingsLoader) { + private static Supplier<Map<String, String>> createSettingsSupplier(ProjectDefinition root, + GlobalServerSettings globalServerSettings, ProjectServerSettings projectServerSettings) { // we can't get ProjectConfiguration because it creates a circular dependency. // We create our own settings which will only be loaded if needed. return () -> { Map<String, String> settings = new HashMap<>(); - settings.putAll(globalConfiguration.getProperties()); - settings.putAll(settingsLoader.load(root.getKeyWithBranch())); + settings.putAll(globalServerSettings.properties()); + settings.putAll(projectServerSettings.properties()); settings.putAll(root.properties()); return settings; }; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java index 8d1071b172c..a0f7e952db9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java @@ -34,8 +34,8 @@ import java.util.stream.Stream; import javax.annotation.CheckForNull; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.FileExtensionPredicate; import org.sonar.api.scanner.fs.InputProject; import org.sonar.scanner.scan.branch.BranchConfiguration; @@ -51,7 +51,7 @@ public class InputComponentStore { private final Map<String, InputFile> globalInputFileCache = new HashMap<>(); private final Table<String, String, InputFile> inputFileByModuleCache = TreeBasedTable.create(); // indexed by key with branch - private final Map<String, AbstractProjectOrModule> inputModuleCache = new HashMap<>(); + private final Map<String, DefaultInputModule> inputModuleCache = new HashMap<>(); private final Map<String, InputComponent> inputComponents = new HashMap<>(); private final SetMultimap<String, InputFile> filesByNameCache = LinkedHashMultimap.create(); private final SetMultimap<String, InputFile> filesByExtensionCache = LinkedHashMultimap.create(); @@ -125,11 +125,11 @@ public class InputComponentStore { } @CheckForNull - public AbstractProjectOrModule getModule(String moduleKeyWithBranch) { + public DefaultInputModule getModule(String moduleKeyWithBranch) { return inputModuleCache.get(moduleKeyWithBranch); } - public void put(AbstractProjectOrModule inputModule) { + public void put(DefaultInputModule inputModule) { String key = inputModule.key(); String keyWithBranch = inputModule.getKeyWithBranch(); Preconditions.checkNotNull(inputModule); @@ -154,4 +154,8 @@ public class InputComponentStore { public SortedSet<String> getLanguages(String moduleKey) { return languagesCache.getOrDefault(moduleKey, Collections.emptySortedSet()); } + + public Collection<DefaultInputModule> allModules() { + return inputModuleCache.values(); + } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientTest.java index 8fcdeb5160e..9a9dfa0a9cd 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientTest.java @@ -116,12 +116,11 @@ public class ScannerWsClientTest { @Test public void fail_if_requires_permission() { expectedException.expect(MessageException.class); - expectedException.expectMessage("missing scan permission, missing another permission"); + expectedException.expectMessage("You're not authorized to run analysis. Please contact the project administrator."); WsRequest request = newRequest(); WsResponse response = newResponse() - .setCode(403) - .setContent("{\"errors\":[{\"msg\":\"missing scan permission\"}, {\"msg\":\"missing another permission\"}]}"); + .setCode(403); when(wsClient.wsConnector().call(request)).thenReturn(response); new ScannerWsClient(wsClient, true, new GlobalAnalysisMode(new ScannerProperties(Collections.emptyMap()))).call(request); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java index 08691f99683..eee733bc972 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java @@ -374,8 +374,7 @@ public class ScannerMediumTester extends ExternalResource { @Override public ProjectRepositories load(String projectKey, boolean isIssuesMode, @Nullable String branchBase) { - Table<String, String, String> settings = HashBasedTable.create(); - return new ProjectRepositories(settings, fileDataTable, lastAnalysisDate); + return new ProjectRepositories(fileDataTable, lastAnalysisDate); } public FakeProjectRepositoriesLoader addFileData(String moduleKey, String path, FileData fileData) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java index cbd14aa19c4..961a7dc5053 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java @@ -22,8 +22,9 @@ package org.sonar.scanner.report; import com.google.common.collect.ImmutableMap; import java.io.File; import java.nio.charset.StandardCharsets; -import java.util.Collections; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.commons.io.FileUtils; @@ -43,9 +44,11 @@ import org.sonar.core.platform.PluginInfo; import org.sonar.scanner.bootstrap.GlobalServerSettings; import org.sonar.scanner.bootstrap.ScannerPluginRepository; import org.sonar.scanner.protocol.output.ScannerReportWriter; -import org.sonar.scanner.repository.ProjectRepositories; +import org.sonar.scanner.scan.ProjectServerSettings; +import org.sonar.scanner.scan.filesystem.InputComponentStore; import org.sonar.updatecenter.common.Version; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyZeroInteractions; @@ -68,26 +71,33 @@ public class AnalysisContextReportPublisherTest { private AnalysisContextReportPublisher publisher; private AnalysisMode analysisMode = mock(AnalysisMode.class); private System2 system2; - private ProjectRepositories projectRepos; private GlobalServerSettings globalServerSettings; private InputModuleHierarchy hierarchy; + private InputComponentStore store; + private ProjectServerSettings projectServerSettings; @Before public void prepare() { logTester.setLevel(LoggerLevel.INFO); system2 = mock(System2.class); when(system2.properties()).thenReturn(new Properties()); - projectRepos = mock(ProjectRepositories.class); globalServerSettings = mock(GlobalServerSettings.class); hierarchy = mock(InputModuleHierarchy.class); - publisher = new AnalysisContextReportPublisher(analysisMode, pluginRepo, system2, projectRepos, globalServerSettings, hierarchy); + store = mock(InputComponentStore.class); + projectServerSettings = mock(ProjectServerSettings.class); + publisher = new AnalysisContextReportPublisher(projectServerSettings, analysisMode, pluginRepo, system2, globalServerSettings, hierarchy, store); } @Test public void shouldOnlyDumpPluginsByDefault() throws Exception { - when(pluginRepo.getPluginInfos()).thenReturn(Collections.singletonList(new PluginInfo("xoo").setName("Xoo").setVersion(Version.create("1.0")))); + when(pluginRepo.getPluginInfos()).thenReturn(singletonList(new PluginInfo("xoo").setName("Xoo").setVersion(Version.create("1.0")))); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder())); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); publisher.init(writer); assertThat(writer.getFileStructure().analysisLog()).exists(); @@ -102,7 +112,6 @@ public class AnalysisContextReportPublisherTest { ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); publisher.init(writer); - publisher.dumpModuleSettings(new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()))); assertThat(writer.getFileStructure().analysisLog()).doesNotExist(); } @@ -112,7 +121,12 @@ public class AnalysisContextReportPublisherTest { logTester.setLevel(LoggerLevel.DEBUG); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); when(globalServerSettings.properties()).thenReturn(ImmutableMap.of(COM_FOO, "bar", SONAR_SKIP, "true")); - + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder()) + .setProperty("sonar.projectKey", "foo")); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); publisher.init(writer); String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); @@ -121,19 +135,31 @@ public class AnalysisContextReportPublisherTest { } @Test - public void dumpServerSideModuleProps() throws Exception { + public void dumpServerSideProjectProps() throws Exception { logTester.setLevel(LoggerLevel.DEBUG); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); - publisher.init(writer); - when(projectRepos.moduleExists("foo")).thenReturn(true); - when(projectRepos.settings("foo")).thenReturn(ImmutableMap.of(COM_FOO, "bar", SONAR_SKIP, "true")); + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder()) + .setProperty("sonar.projectKey", "foo")); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); - publisher.dumpModuleSettings(new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()))); + when(projectServerSettings.properties()).thenReturn(ImmutableMap.of(COM_FOO, "bar", SONAR_SKIP, "true")); - String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); - assertThat(content).doesNotContain(COM_FOO); - assertThat(content).containsOnlyOnce(SONAR_SKIP); + publisher.init(writer); + + List<String> lines = FileUtils.readLines(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); + assertThat(lines).containsExactly("Environment variables:", + "System properties:", + "SonarQube plugins:", + "Global server settings:", + "Project server settings:", + " - com.foo=bar", + " - sonar.skip=true", + "Project scanner properties:", + " - sonar.projectKey=foo"); } @Test @@ -144,22 +170,27 @@ public class AnalysisContextReportPublisherTest { props.setProperty(COM_FOO, "bar"); props.setProperty(SONAR_SKIP, "true"); when(system2.properties()).thenReturn(props); - publisher.init(writer); - - String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); - assertThat(content).containsOnlyOnce(COM_FOO); - assertThat(content).doesNotContain(SONAR_SKIP); - - publisher.dumpModuleSettings(new DefaultInputModule(ProjectDefinition.create() + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() .setBaseDir(temp.newFolder()) .setWorkDir(temp.newFolder()) .setProperty("sonar.projectKey", "foo") .setProperty(COM_FOO, "bar") - .setProperty(SONAR_SKIP, "true"))); + .setProperty(SONAR_SKIP, "true")); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); - content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); - assertThat(content).containsOnlyOnce(COM_FOO); - assertThat(content).containsOnlyOnce(SONAR_SKIP); + publisher.init(writer); + + List<String> lines = FileUtils.readLines(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); + assertThat(lines).containsExactly("Environment variables:", + "System properties:", + " - com.foo=bar", + "SonarQube plugins:", + "Global server settings:", + "Project server settings:", + "Project scanner properties:", + " - sonar.projectKey=foo", + " - sonar.skip=true"); } @Test @@ -171,6 +202,13 @@ public class AnalysisContextReportPublisherTest { env.put(FOO, "BAR"); env.put(BIZ, "BAZ"); when(system2.envVariables()).thenReturn(env); + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder()) + .setProperty("sonar.projectKey", "foo") + .setProperty("env." + FOO, "BAR")); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); publisher.init(writer); String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); @@ -178,11 +216,6 @@ public class AnalysisContextReportPublisherTest { assertThat(content).containsOnlyOnce(BIZ); assertThat(content).containsSubsequence(BIZ, FOO); - publisher.dumpModuleSettings(new DefaultInputModule(ProjectDefinition.create() - .setBaseDir(temp.newFolder()) - .setWorkDir(temp.newFolder()) - .setProperty("sonar.projectKey", "foo") - .setProperty("env." + FOO, "BAR"))); content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); assertThat(content).containsOnlyOnce(FOO); @@ -193,18 +226,19 @@ public class AnalysisContextReportPublisherTest { @Test public void shouldNotDumpSensitiveModuleProperties() throws Exception { ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); - publisher.init(writer); - - assertThat(writer.getFileStructure().analysisLog()).exists(); - - publisher.dumpModuleSettings(new DefaultInputModule(ProjectDefinition.create() + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() .setBaseDir(temp.newFolder()) .setWorkDir(temp.newFolder()) .setProperty("sonar.projectKey", "foo") .setProperty("sonar.projectKey", "foo") .setProperty("sonar.login", "my_token") .setProperty("sonar.password", "azerty") - .setProperty("sonar.cpp.license.secured", "AZERTY"))); + .setProperty("sonar.cpp.license.secured", "AZERTY")); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); + publisher.init(writer); + + assertThat(writer.getFileStructure().analysisLog()).exists(); assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8)).containsSubsequence( "sonar.cpp.license.secured=******", @@ -217,16 +251,18 @@ public class AnalysisContextReportPublisherTest { public void shouldShortenModuleProperties() throws Exception { File baseDir = temp.newFolder(); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); - publisher.init(writer); - - assertThat(writer.getFileStructure().analysisLog()).exists(); - - publisher.dumpModuleSettings(new DefaultInputModule(ProjectDefinition.create() + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() .setBaseDir(baseDir) .setWorkDir(temp.newFolder()) .setProperty("sonar.projectKey", "foo") .setProperty("sonar.projectBaseDir", baseDir.toString()) - .setProperty("sonar.aVeryLongProp", StringUtils.repeat("abcde", 1000)))); + .setProperty("sonar.aVeryLongProp", StringUtils.repeat("abcde", 1000))); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); + publisher.init(writer); + + assertThat(writer.getFileStructure().analysisLog()).exists(); + assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8)).containsSubsequence( "sonar.aVeryLongProp=" + StringUtils.repeat("abcde", 199) + "ab...", @@ -239,7 +275,12 @@ public class AnalysisContextReportPublisherTest { public void shouldNotDumpSensitiveGlobalProperties() throws Exception { ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); when(globalServerSettings.properties()).thenReturn(ImmutableMap.of("sonar.login", "my_token", "sonar.password", "azerty", "sonar.cpp.license.secured", "AZERTY")); - + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder()) + .setProperty("sonar.projectKey", "foo")); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); publisher.init(writer); assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8)).containsSubsequence( @@ -253,7 +294,6 @@ public class AnalysisContextReportPublisherTest { public void dontDumpParentProps() throws Exception { logTester.setLevel(LoggerLevel.DEBUG); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); - publisher.init(writer); DefaultInputModule module = new DefaultInputModule(ProjectDefinition.create() .setBaseDir(temp.newFolder()) @@ -268,10 +308,22 @@ public class AnalysisContextReportPublisherTest { .setProperty(SONAR_SKIP, "true")); when(hierarchy.parent(module)).thenReturn(parent); + when(store.allModules()).thenReturn(Arrays.asList(parent, module)); + when(hierarchy.root()).thenReturn(parent); - publisher.dumpModuleSettings(module); + publisher.init(writer); - String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); - assertThat(content).doesNotContain(SONAR_SKIP); + List<String> lines = FileUtils.readLines(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); + assertThat(lines).containsExactly("Environment variables:", + "System properties:", + "SonarQube plugins:", + "Global server settings:", + "Project server settings:", + "Project scanner properties:", + " - sonar.projectKey=parent", + " - sonar.skip=true", + "Scanner properties of module: foo", + " - sonar.projectKey=foo" + ); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.java index 6e39fe912da..515c1b3873e 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesProviderTest.java @@ -55,10 +55,9 @@ public class ProjectRepositoriesProviderTest { public void setUp() { MockitoAnnotations.initMocks(this); - Table<String, String, String> t1 = HashBasedTable.create(); Table<String, String, FileData> t2 = HashBasedTable.create(); - project = new ProjectRepositories(t1, t2, new Date()); + project = new ProjectRepositories(t2, new Date()); provider = new ProjectRepositoriesProvider(); when(props.getKeyWithBranch()).thenReturn("key"); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/MutableModuleSettingsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/MutableModuleSettingsTest.java deleted file mode 100644 index 12932c33d30..00000000000 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/MutableModuleSettingsTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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. - * - * This program 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.scanner.scan; - -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableTable; -import com.google.common.collect.Table; -import java.util.List; -import java.util.Map; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.utils.MessageException; -import org.sonar.scanner.bootstrap.GlobalAnalysisMode; -import org.sonar.scanner.bootstrap.GlobalConfiguration; -import org.sonar.scanner.bootstrap.GlobalConfigurationProvider; -import org.sonar.scanner.bootstrap.GlobalServerSettings; -import org.sonar.scanner.bootstrap.ScannerProperties; -import org.sonar.scanner.repository.FileData; -import org.sonar.scanner.repository.ProjectRepositories; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class MutableModuleSettingsTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - private AnalysisMode mode; - - @Before - public void before() { - mode = mock(AnalysisMode.class); - } - - private ProjectRepositories createSettings(String module, Map<String, String> settingsMap) { - Table<String, String, FileData> fileData = ImmutableTable.of(); - Table<String, String, String> settings = HashBasedTable.create(); - - for (Map.Entry<String, String> e : settingsMap.entrySet()) { - settings.put(module, e.getKey(), e.getValue()); - } - return new ProjectRepositories(settings, fileData, null); - } - - @Test - public void testOrderedProjects() { - ProjectDefinition grandParent = ProjectDefinition.create(); - ProjectDefinition parent = ProjectDefinition.create(); - ProjectDefinition child = ProjectDefinition.create(); - grandParent.addSubProject(parent); - parent.addSubProject(child); - - List<ProjectDefinition> hierarchy = ModuleConfigurationProvider.getTopDownParentProjects(child); - assertThat(hierarchy.get(0)).isEqualTo(grandParent); - assertThat(hierarchy.get(1)).isEqualTo(parent); - assertThat(hierarchy.get(2)).isEqualTo(child); - } - - @Test - public void test_loading_of_module_settings() { - GlobalConfiguration globalConfig = newGlobalConfig(ImmutableMap.of( - "overridding", "batch", - "on-batch", "true")); - - ProjectRepositories projRepos = createSettings("struts-core", ImmutableMap.of("on-module", "true", "overridding", "module")); - - ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); - - MutableModuleSettings moduleSettings = new MutableModuleSettings(globalConfig, module, projRepos, mode); - - assertThat(moduleSettings.getString("overridding")).isEqualTo("module"); - assertThat(moduleSettings.getString("on-batch")).isEqualTo("true"); - assertThat(moduleSettings.getString("on-module")).isEqualTo("true"); - } - - // SONAR-6386 - @Test - public void test_loading_of_parent_module_settings_for_new_module() { - GlobalConfiguration globalConfig = newGlobalConfig(ImmutableMap.of( - "overridding", "batch", - "on-batch", "true")); - - ProjectRepositories projRepos = createSettings("struts", ImmutableMap.of("on-module", "true", "overridding", "module")); - - ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); - ProjectDefinition.create().setKey("struts").addSubProject(module); - - MutableModuleSettings moduleSettings = new MutableModuleSettings(globalConfig, module, projRepos, mode); - - assertThat(moduleSettings.getString("overridding")).isEqualTo("module"); - assertThat(moduleSettings.getString("on-batch")).isEqualTo("true"); - assertThat(moduleSettings.getString("on-module")).isEqualTo("true"); - } - - @Test - public void should_not_fail_when_accessing_secured_properties() { - GlobalConfiguration globalConfig = newGlobalConfig(ImmutableMap.of("sonar.foo.secured", "bar")); - - ProjectRepositories projSettingsRepo = createSettings("struts-core", ImmutableMap.of("sonar.foo.license.secured", "bar2")); - - ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); - - MutableModuleSettings moduleSettings = new MutableModuleSettings(globalConfig, module, projSettingsRepo, mode); - - assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); - assertThat(moduleSettings.getString("sonar.foo.secured")).isEqualTo("bar"); - } - - @Test - public void should_fail_when_accessing_secured_properties_in_issues() { - GlobalConfiguration globalConfig = newGlobalConfig(ImmutableMap.of( - "sonar.foo.secured", "bar")); - - ProjectRepositories projSettingsRepo = createSettings("struts-core", ImmutableMap.of("sonar.foo.license.secured", "bar2")); - - when(mode.isIssues()).thenReturn(true); - - ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); - - MutableModuleSettings moduleSettings = new MutableModuleSettings(globalConfig, module, projSettingsRepo, mode); - - assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); - - thrown.expect(MessageException.class); - thrown - .expectMessage( - "Access to the secured property 'sonar.foo.secured' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode."); - moduleSettings.getString("sonar.foo.secured"); - } - - private GlobalConfiguration newGlobalConfig(Map<String, String> props) { - ScannerProperties scannerProps = new ScannerProperties(props); - return new GlobalConfigurationProvider().provide(mock(GlobalServerSettings.class), scannerProps, new PropertyDefinitions(), - new GlobalAnalysisMode(scannerProps)); - } -} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/MutableProjectSettingsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/MutableProjectSettingsTest.java deleted file mode 100644 index 4b0ed58b948..00000000000 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/MutableProjectSettingsTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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. - * - * This program 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.scanner.scan; - -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.ImmutableTable; -import com.google.common.collect.Table; -import java.util.Collections; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.utils.MessageException; -import org.sonar.api.utils.log.LogTester; -import org.sonar.scanner.bootstrap.GlobalAnalysisMode; -import org.sonar.scanner.bootstrap.GlobalConfiguration; -import org.sonar.scanner.bootstrap.GlobalConfigurationProvider; -import org.sonar.scanner.bootstrap.GlobalServerSettings; -import org.sonar.scanner.bootstrap.ScannerProperties; -import org.sonar.scanner.repository.FileData; -import org.sonar.scanner.repository.ProjectRepositories; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class MutableProjectSettingsTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - @Rule - public LogTester logTester = new LogTester(); - - private ProjectRepositories projectRef; - private ProjectDefinition project; - private GlobalConfiguration globalConfig; - private Table<String, String, FileData> emptyFileData; - private Table<String, String, String> emptySettings; - - private GlobalAnalysisMode globalMode; - - @Before - public void prepare() { - emptyFileData = ImmutableTable.of(); - emptySettings = ImmutableTable.of(); - project = ProjectDefinition.create().setKey("struts"); - globalMode = mock(GlobalAnalysisMode.class); - globalConfig = new GlobalConfigurationProvider().provide(mock(GlobalServerSettings.class), new ScannerProperties(Collections.<String, String>emptyMap()), new PropertyDefinitions(), - globalMode); - } - - @Test - public void should_load_project_props() { - project.setProperty("project.prop", "project"); - - projectRef = new ProjectRepositories(emptySettings, emptyFileData, null); - MutableProjectSettings batchSettings = new MutableProjectSettings(new ProjectReactor(project), globalConfig, projectRef, globalMode); - - assertThat(batchSettings.getString("project.prop")).isEqualTo("project"); - } - - @Test - public void should_load_project_root_settings() { - Table<String, String, String> settings = HashBasedTable.create(); - settings.put("struts", "sonar.cpd.cross", "true"); - settings.put("struts", "sonar.java.coveragePlugin", "jacoco"); - - projectRef = new ProjectRepositories(settings, emptyFileData, null); - MutableProjectSettings batchSettings = new MutableProjectSettings(new ProjectReactor(project), globalConfig, projectRef, globalMode); - assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco"); - } - - @Test - public void should_load_project_root_settings_on_branch() { - project.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch"); - - Table<String, String, String> settings = HashBasedTable.create(); - settings.put("struts:mybranch", "sonar.cpd.cross", "true"); - settings.put("struts:mybranch", "sonar.java.coveragePlugin", "jacoco"); - - projectRef = new ProjectRepositories(settings, emptyFileData, null); - - MutableProjectSettings batchSettings = new MutableProjectSettings(new ProjectReactor(project), globalConfig, projectRef, globalMode); - - assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco"); - } - - @Test - public void should_not_fail_when_accessing_secured_properties() { - Table<String, String, String> settings = HashBasedTable.create(); - settings.put("struts", "sonar.foo.secured", "bar"); - settings.put("struts", "sonar.foo.license.secured", "bar2"); - - projectRef = new ProjectRepositories(settings, emptyFileData, null); - MutableProjectSettings batchSettings = new MutableProjectSettings(new ProjectReactor(project), globalConfig, projectRef, globalMode); - - assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); - assertThat(batchSettings.getString("sonar.foo.secured")).isEqualTo("bar"); - } - - @Test - public void should_fail_when_accessing_secured_properties_in_issues_mode() { - Table<String, String, String> settings = HashBasedTable.create(); - settings.put("struts", "sonar.foo.secured", "bar"); - settings.put("struts", "sonar.foo.license.secured", "bar2"); - - when(globalMode.isIssues()).thenReturn(true); - - projectRef = new ProjectRepositories(settings, emptyFileData, null); - MutableProjectSettings batchSettings = new MutableProjectSettings(new ProjectReactor(project), globalConfig, projectRef, globalMode); - - assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); - thrown.expect(MessageException.class); - thrown - .expectMessage( - "Access to the secured property 'sonar.foo.secured' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode."); - batchSettings.getString("sonar.foo.secured"); - } - -} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.java index 8a11e425a86..8863e9c1a35 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/BranchConfigurationProviderTest.java @@ -19,20 +19,10 @@ */ package org.sonar.scanner.scan.branch; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyMap; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; - import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -41,7 +31,16 @@ import org.mockito.MockitoAnnotations; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.scanner.bootstrap.GlobalConfiguration; -import org.sonar.scanner.repository.settings.SettingsLoader; +import org.sonar.scanner.bootstrap.GlobalServerSettings; +import org.sonar.scanner.scan.ProjectServerSettings; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class BranchConfigurationProviderTest { private BranchConfigurationProvider provider = new BranchConfigurationProvider(); @@ -52,9 +51,9 @@ public class BranchConfigurationProviderTest { private ProjectPullRequests pullRequests = mock(ProjectPullRequests.class); private ProjectReactor reactor = mock(ProjectReactor.class);; private Map<String, String> globalPropertiesMap = new HashMap<>();; - private Map<String, String> remoteProjectSettings; private ProjectDefinition root = mock(ProjectDefinition.class); - private SettingsLoader settingsLoader = mock(SettingsLoader.class); + private GlobalServerSettings globalServerSettings = mock(GlobalServerSettings.class); + private ProjectServerSettings projectServerSettings = mock(ProjectServerSettings.class); @Captor private ArgumentCaptor<Supplier<Map<String, String>>> settingsCaptor; @@ -63,21 +62,20 @@ public class BranchConfigurationProviderTest { public void setUp() { MockitoAnnotations.initMocks(this); when(globalConfiguration.getProperties()).thenReturn(globalPropertiesMap); - when(settingsLoader.load(anyString())).thenReturn(remoteProjectSettings); when(reactor.getRoot()).thenReturn(root); } @Test public void should_cache_config() { - BranchConfiguration configuration = provider.provide(null, globalConfiguration, reactor, settingsLoader, branches, pullRequests); - assertThat(provider.provide(null, globalConfiguration, reactor, settingsLoader, branches, pullRequests)).isSameAs(configuration); + BranchConfiguration configuration = provider.provide(null, globalConfiguration, reactor, globalServerSettings, projectServerSettings, branches, pullRequests); + assertThat(provider.provide(null, globalConfiguration, reactor, globalServerSettings, projectServerSettings, branches, pullRequests)).isSameAs(configuration); } @Test public void should_use_loader() { when(loader.load(eq(globalPropertiesMap), any(Supplier.class), eq(branches), eq(pullRequests))).thenReturn(config); - BranchConfiguration result = provider.provide(loader, globalConfiguration, reactor, settingsLoader, branches, pullRequests); + BranchConfiguration result = provider.provide(loader, globalConfiguration, reactor, globalServerSettings, projectServerSettings, branches, pullRequests); assertThat(result).isSameAs(config); } @@ -85,9 +83,9 @@ public class BranchConfigurationProviderTest { @Test public void settings_should_include_command_line_args_with_highest_priority() { when(globalConfiguration.getProperties()).thenReturn(Collections.singletonMap("key", "global")); - when(settingsLoader.load(anyString())).thenReturn(Collections.singletonMap("key", "settings")); + when(projectServerSettings.properties()).thenReturn(Collections.singletonMap("key", "settings")); when(root.properties()).thenReturn(Collections.singletonMap("key", "root")); - provider.provide(loader, globalConfiguration, reactor, settingsLoader, branches, pullRequests); + provider.provide(loader, globalConfiguration, reactor, globalServerSettings, projectServerSettings, branches, pullRequests); verify(loader).load(anyMap(), settingsCaptor.capture(), any(ProjectBranches.class), any(ProjectPullRequests.class)); Map<String, String> map = settingsCaptor.getValue().get(); @@ -96,7 +94,7 @@ public class BranchConfigurationProviderTest { @Test public void should_return_default_if_no_loader() { - BranchConfiguration result = provider.provide(null, globalConfiguration, reactor, settingsLoader, branches, pullRequests); + BranchConfiguration result = provider.provide(null, globalConfiguration, reactor, globalServerSettings, projectServerSettings, branches, pullRequests); assertThat(result.targetScmBranch()).isNull(); assertThat(result.branchType()).isEqualTo(BranchType.LONG); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java index 141e7ecb381..09dba259df9 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java @@ -20,7 +20,6 @@ package org.sonar.scanner.scan.filesystem; import com.google.common.collect.HashBasedTable; -import com.google.common.collect.ImmutableTable; import com.google.common.collect.Table; import java.nio.file.Paths; import java.util.Collections; @@ -41,7 +40,7 @@ import static org.mockito.Mockito.when; public class StatusDetectionTest { @Test public void detect_status() { - ProjectRepositories ref = new ProjectRepositories(ImmutableTable.of(), createTable(), null); + ProjectRepositories ref = new ProjectRepositories(createTable(), null); ScmChangedFiles changedFiles = new ScmChangedFiles(null); StatusDetection statusDetection = new StatusDetection(ref, changedFiles); @@ -52,7 +51,7 @@ public class StatusDetectionTest { @Test public void detect_status_branches_exclude() { - ProjectRepositories ref = new ProjectRepositories(ImmutableTable.of(), createTable(), null); + ProjectRepositories ref = new ProjectRepositories(createTable(), null); ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.emptyList()); StatusDetection statusDetection = new StatusDetection(ref, changedFiles); @@ -69,7 +68,7 @@ public class StatusDetectionTest { when(mockedFile.relativePath()).thenReturn("module/src/Foo.java"); when(mockedFile.path()).thenReturn(Paths.get("module", "src", "Foo.java")); - ProjectRepositories ref = new ProjectRepositories(ImmutableTable.of(), createTable(), null); + ProjectRepositories ref = new ProjectRepositories(createTable(), null); ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.singletonList(Paths.get("module", "src", "Foo.java"))); StatusDetection statusDetection = new StatusDetection(ref, changedFiles); @@ -82,7 +81,7 @@ public class StatusDetectionTest { @Test public void detect_status_branches_confirm() { - ProjectRepositories ref = new ProjectRepositories(ImmutableTable.of(), createTable(), null); + ProjectRepositories ref = new ProjectRepositories(createTable(), null); ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.singletonList(Paths.get("module", "src", "Foo.java"))); StatusDetection statusDetection = new StatusDetection(ref, changedFiles); diff --git a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/input/ProjectRepositories.java b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/input/ProjectRepositories.java index 809ac48a88d..9a557aa64cc 100644 --- a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/input/ProjectRepositories.java +++ b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/input/ProjectRepositories.java @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.Map; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.scanner.protocol.GsonHelper; /** * Container for all project data going from server to batch. @@ -34,29 +33,9 @@ import org.sonar.scanner.protocol.GsonHelper; public class ProjectRepositories { private long timestamp; - private boolean exists; - private Map<String, Map<String, String>> settingsByModule = new HashMap<>(); private Map<String, Map<String, FileData>> fileDataByModuleAndPath = new HashMap<>(); private Date lastAnalysisDate; - public Map<String, String> settings(String moduleKey) { - return settingsByModule.containsKey(moduleKey) ? settingsByModule.get(moduleKey) : Collections.<String, String>emptyMap(); - } - - public Map<String, Map<String, String>> settings() { - return settingsByModule; - } - - public ProjectRepositories addSettings(String moduleKey, Map<String, String> settings) { - Map<String, String> existingSettings = settingsByModule.computeIfAbsent(moduleKey, k -> new HashMap<>()); - existingSettings.putAll(settings); - return this; - } - - public boolean exists() { - return exists; - } - public Map<String, Map<String, FileData>> fileDataByModuleAndPath() { return fileDataByModuleAndPath; } @@ -96,12 +75,4 @@ public class ProjectRepositories { public void setLastAnalysisDate(@Nullable Date lastAnalysisDate) { this.lastAnalysisDate = lastAnalysisDate; } - - public String toJson() { - return GsonHelper.create().toJson(this); - } - - public static ProjectRepositories fromJson(String json) { - return GsonHelper.create().fromJson(json, ProjectRepositories.class); - } } diff --git a/sonar-ws/src/main/protobuf/ws-batch.proto b/sonar-ws/src/main/protobuf/ws-batch.proto index 11a696da9e8..d600acadc32 100644 --- a/sonar-ws/src/main/protobuf/ws-batch.proto +++ b/sonar-ws/src/main/protobuf/ws-batch.proto @@ -28,14 +28,9 @@ option optimize_for = SPEED; // WS batch/project message WsProjectResponse { optional int64 timestamp = 1; - map<string, Settings> settingsByModule = 2; map<string, FileDataByPath> fileDataByModuleAndPath = 3; optional int64 lastAnalysisDate = 4; - message Settings { - map<string,string> settings = 1; - } - message FileDataByPath { map<string, FileData> FileDataByPath = 1; } |