Skip to content

Commit

Permalink
SONAR-5883 /batch/project WS now returns file hashes
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien Lancelot committed Jan 14, 2015
1 parent 6a98bef commit f1f058b
Show file tree
Hide file tree
Showing 17 changed files with 241 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
import org.sonar.api.ServerComponent;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.batch.protocol.input.FileData;
import org.sonar.batch.protocol.input.ProjectReferentials;
import org.sonar.core.UtcDateUtils;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.FilePathWithHashDto;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
Expand Down Expand Up @@ -89,15 +91,20 @@ public ProjectReferentials load(ProjectRepositoryQuery query) {
projectKey = project.key();
}

List<PropertyDto> moduleSettings = dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session);
List<ComponentDto> moduleChildren = dbClient.componentDao().findChildrenModulesFromModule(session, query.getModuleKey());
moduleChildren.add(module);
Map<String, String> moduleUuidsByKey = moduleUuidsByKey(module, moduleChildren);
Map<String, Long> moduleIdsByKey = moduleIdsByKey(module, moduleChildren);

List<PropertyDto> moduleSettings = dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session);
List<PropertyDto> moduleChildrenSettings = newArrayList();
if (!moduleChildren.isEmpty()) {
moduleChildrenSettings = dbClient.propertiesDao().findChildrenModuleProperties(query.getModuleKey(), session);
}
TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleChildren, moduleChildrenSettings, module, moduleSettings);
TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleUuidsByKey, moduleIdsByKey, moduleChildren, moduleChildrenSettings, module, moduleSettings);

addSettingsToChildrenModules(ref, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm, session);
addFileData(session, ref, moduleChildren, module.key());
} else {
// Add settings of the provisioned project
addSettings(ref, query.getModuleKey(), getPropertiesMap(dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session), hasScanPerm));
Expand Down Expand Up @@ -218,6 +225,18 @@ private void addActiveRules(ProjectReferentials ref) {
}
}

private void addFileData(DbSession session, ProjectReferentials ref, List<ComponentDto> moduleChildren, String moduleKey) {
Map<String, String> moduleKeysByUuid = newHashMap();
for (ComponentDto module : moduleChildren) {
moduleKeysByUuid.put(module.uuid(), module.key());
}

for (FilePathWithHashDto file : dbClient.componentDao().findFilesFromModule(session, moduleKey)) {
FileData fileData = new FileData(file.getSrcHash(), false, null, null, null);
ref.addFileData(moduleKeysByUuid.get(file.getModuleUuid()), file.getPath(), fileData);
}
}

private void checkPermission(boolean preview) {
UserSession userSession = UserSession.get();
boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
Expand All @@ -231,44 +250,55 @@ private void checkPermission(boolean preview) {
}
}

private Map<String, String> moduleUuidsByKey(ComponentDto module, List<ComponentDto> moduleChildren) {
Map<String, String> moduleUuidsByKey = newHashMap();
for (ComponentDto componentDto : moduleChildren) {
moduleUuidsByKey.put(componentDto.key(), componentDto.uuid());
}
return moduleUuidsByKey;
}

private Map<String, Long> moduleIdsByKey(ComponentDto module, List<ComponentDto> moduleChildren) {
Map<String, Long> moduleIdsByKey = newHashMap();
for (ComponentDto componentDto : moduleChildren) {
moduleIdsByKey.put(componentDto.key(), componentDto.getId());
}
return moduleIdsByKey;
}

private static class TreeModuleSettings {

private Map<String, Long> moduleIdsByKey;
private Map<String, String> moduleUuidsByKey;
private Multimap<Long, PropertyDto> propertiesByModuleId;
private Multimap<String, ComponentDto> moduleChildrenByModuleUuid;

private TreeModuleSettings(List<ComponentDto> moduleChildren, List<PropertyDto> moduleChildrenSettings, ComponentDto module, List<PropertyDto> moduleSettings) {
private TreeModuleSettings(Map<String, String> moduleUuidsByKey, Map<String, Long> moduleIdsByKey, List<ComponentDto> moduleChildren,
List<PropertyDto> moduleChildrenSettings, ComponentDto module, List<PropertyDto> moduleSettings) {
this.moduleIdsByKey = moduleIdsByKey;
this.moduleUuidsByKey = moduleUuidsByKey;
propertiesByModuleId = ArrayListMultimap.create();
moduleIdsByKey = newHashMap();
moduleUuidsByKey = newHashMap();
moduleChildrenByModuleUuid = ArrayListMultimap.create();

for (PropertyDto settings : moduleChildrenSettings) {
propertiesByModuleId.put(settings.getResourceId(), settings);
}
propertiesByModuleId.putAll(module.getId(), moduleSettings);

moduleIdsByKey.put(module.key(), module.getId());
moduleUuidsByKey.put(module.key(), module.uuid());
for (ComponentDto componentDto : moduleChildren) {
moduleIdsByKey.put(componentDto.key(), componentDto.getId());
moduleUuidsByKey.put(componentDto.key(), componentDto.uuid());
String moduleUuid = componentDto.moduleUuid();
if (moduleUuid != null) {
moduleChildrenByModuleUuid.put(moduleUuid, componentDto);
} else {
moduleChildrenByModuleUuid.put(module.uuid(), componentDto);
}
}
}

private List<PropertyDto> findModuleSettings(String moduleKey) {
List<PropertyDto> findModuleSettings(String moduleKey) {
Long moduleId = moduleIdsByKey.get(moduleKey);
return newArrayList(propertiesByModuleId.get(moduleId));
}

private List<ComponentDto> findChildrenModule(String moduleKey) {
List<ComponentDto> findChildrenModule(String moduleKey) {
String moduleUuid = moduleUuidsByKey.get(moduleKey);
return newArrayList(moduleChildrenByModuleUuid.get(moduleUuid));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@

import com.google.common.collect.Lists;
import org.sonar.api.ServerComponent;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.System2;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.FilePathWithHashDto;
import org.sonar.core.component.db.ComponentMapper;
import org.sonar.core.persistence.DaoComponent;
import org.sonar.core.persistence.DbSession;
Expand Down Expand Up @@ -115,7 +117,11 @@ public List<ComponentDto> findSubProjectsByComponentUuids(DbSession session, Col
}

public List<ComponentDto> findChildrenModulesFromModule(DbSession session, String moduleKey) {
return mapper(session).findChildrenModulesFromModule(moduleKey);
return mapper(session).findChildrenModulesFromModule(moduleKey, Scopes.PROJECT);
}

public List<FilePathWithHashDto> findFilesFromModule(DbSession session, String moduleKey) {
return mapper(session).findFilesFromModule(moduleKey, Scopes.FILE);
}

public List<ComponentDto> getByUuids(DbSession session, Collection<String> uuids) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public List<SnapshotDto> findSnapshotAndChildrenOfProjectScope(DbSession session
* Return all snapshots children (not returning itself) from a module key
*/
public List<SnapshotDto> findChildrenModulesFromModule(DbSession session, String moduleKey) {
return mapper(session).selectChildrenModulesFromModule(moduleKey);
return mapper(session).selectChildrenModulesFromModule(moduleKey, Scopes.PROJECT);
}

public int updateSnapshotAndChildrenLastFlagAndStatus(DbSession session, SnapshotDto snapshot, boolean isLast, String status) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.utils.DateUtils;
import org.sonar.batch.protocol.input.ActiveRule;
import org.sonar.batch.protocol.input.FileData;
import org.sonar.batch.protocol.input.ProjectReferentials;
import org.sonar.batch.protocol.input.QProfile;
import org.sonar.core.component.ComponentDto;
Expand All @@ -40,6 +41,8 @@
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.core.source.db.FileSourceDao;
import org.sonar.core.source.db.FileSourceDto;
import org.sonar.server.component.ComponentTesting;
import org.sonar.server.component.SnapshotTesting;
import org.sonar.server.db.DbClient;
Expand Down Expand Up @@ -698,6 +701,38 @@ public void fail_when_not_preview_and_only_dry_run_permission() throws Exception
}
}

@Test
public void add_file_data() throws Exception {
MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);

ComponentDto project = ComponentTesting.newProjectDto();
tester.get(DbClient.class).componentDao().insert(dbSession, project);
SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot);
addDefaultProfile();

ComponentDto file = ComponentTesting.newFileDto(project, "file");
tester.get(DbClient.class).componentDao().insert(dbSession, file);
tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(file, projectSnapshot));
tester.get(FileSourceDao.class).insert(new FileSourceDto()
.setFileUuid(file.uuid())
.setProjectUuid(project.uuid())
.setData(",,,,,,,,,,,,,,,unchanged&#13;&#10;,,,,,,,,,,,,,,,content&#13;&#10;")
.setDataHash("0263047cd758c68c27683625f072f010")
.setLineHashes("8d7b3d6b83c0a517eac07e1aac94b773")
.setCreatedAt(new Date().getTime())
.setUpdatedAt(new Date().getTime())
.setSrcHash("123456")
);

dbSession.commit();

ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
assertThat(ref.fileDataByPath(project.key())).hasSize(1);
FileData fileData = ref.fileData(project.key(), file.path());
assertThat(fileData.hash()).isEqualTo("123456");
}

private void addDefaultProfile() {
QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
DateUtils.formatDateTime(new Date()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.FilePathWithHashDto;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.exceptions.NotFoundException;
Expand Down Expand Up @@ -336,17 +337,46 @@ public void find_children_modules_from_module() throws Exception {

// From root project
List<ComponentDto> modules = dao.findChildrenModulesFromModule(session, "org.struts:struts");
assertThat(modules).extracting("id").containsOnly(2L, 3L);
assertThat(modules).extracting("uuid").containsOnly("EFGH", "FGHI");

// From module
modules = dao.findChildrenModulesFromModule(session, "org.struts:struts-core");
assertThat(modules).extracting("id").containsOnly(3L);
assertThat(modules).extracting("uuid").containsOnly("FGHI");

// From sub module
modules = dao.findChildrenModulesFromModule(session, "org.struts:struts-data");
assertThat(modules).isEmpty();
}

@Test
public void findFilesFromModule() throws Exception {
setupData("multi-modules", "files_hashes");

// From root project
List<FilePathWithHashDto> files = dao.findFilesFromModule(session, "org.struts:struts");
assertThat(files).extracting("uuid").containsOnly("HIJK");
assertThat(files).extracting("moduleUuid").containsOnly("FGHI");
assertThat(files).extracting("srcHash").containsOnly("123456");
assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java");

// From module
files = dao.findFilesFromModule(session, "org.struts:struts-core");
assertThat(files).extracting("uuid").containsOnly("HIJK");
assertThat(files).extracting("moduleUuid").containsOnly("FGHI");
assertThat(files).extracting("srcHash").containsOnly("123456");
assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java");

// From sub module
files = dao.findFilesFromModule(session, "org.struts:struts-data");
assertThat(files).extracting("uuid").containsOnly("HIJK");
assertThat(files).extracting("moduleUuid").containsOnly("FGHI");
assertThat(files).extracting("srcHash").containsOnly("123456");
assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java");

// From unknown
assertThat(dao.findFilesFromModule(session, "unknown")).isEmpty();
}

@Test
public void insert() {
when(system2.now()).thenReturn(DateUtils.parseDate("2014-06-18").getTime());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<dataset>

<file_sources id="101" project_uuid="ABCD" file_uuid="HIJK"
data=",,,,,,,,,,,,,,,unchanged&#13;&#10;,,,,,,,,,,,,,,,content&#13;&#10;"
line_hashes="8d7b3d6b83c0a517eac07e1aac94b773&#10;9a0364b9e99bb480dd25e1f0284c8555"
data_hash="0263047cd758c68c27683625f072f010"
src_hash="123456"
created_at="1412952242000" updated_at="1412952242000"/>

</dataset>
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

<!-- module -->
<projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD."
uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD"
scope="PRJ" qualifier="BRC" long_name="Struts Core"
description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
<snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
Expand All @@ -45,7 +45,7 @@

<!-- sub module -->
<projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data"
uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH."
uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH"
scope="PRJ" qualifier="BRC" long_name="Struts Data"
description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
<snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
Expand All @@ -60,7 +60,7 @@

<!-- directory -->
<projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI."
uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI"
name="src/org/struts" root_id="3"
description="[null]"
enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" />
Expand All @@ -76,7 +76,7 @@

<!-- file -->
<projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
uuid="HIJK" project_uuid="ABCD" module_uuid="GHIJ" module_uuid_path="ABCD.EFGH.FGHI.GHIJ."
uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI"
name="RequestContext.java" root_id="3"
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

<!-- module -->
<projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD."
uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD"
scope="PRJ" qualifier="BRC" long_name="Struts Core"
description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
<snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
Expand All @@ -41,7 +41,7 @@

<!-- sub module -->
<projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data"
uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH."
uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH"
scope="PRJ" qualifier="BRC" long_name="Struts Data"
description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
<snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
Expand All @@ -56,7 +56,7 @@

<!-- directory -->
<projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI."
uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI"
name="src/org/struts" root_id="3"
description="[null]"
enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" />
Expand All @@ -72,7 +72,7 @@

<!-- file -->
<projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
uuid="HIJK" project_uuid="ABCD" module_uuid="GHIJ" module_uuid_path="ABCD.EFGH.FGHI.GHIJ."
uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI"
name="RequestContext.java" root_id="3"
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" />
Expand Down
Loading

0 comments on commit f1f058b

Please sign in to comment.