]> source.dussan.org Git - sonarqube.git/blob
39e30067fd6c35a323742321efbd4049a3d8d187
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.server.computation.task.projectanalysis.step;
21
22 import com.google.common.base.Optional;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 import java.util.function.Consumer;
26 import java.util.stream.Stream;
27 import javax.annotation.Nullable;
28 import org.junit.Before;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.sonar.api.utils.DateUtils;
32 import org.sonar.api.utils.System2;
33 import org.sonar.core.component.ComponentKeys;
34 import org.sonar.db.DbClient;
35 import org.sonar.db.DbTester;
36 import org.sonar.db.component.BranchType;
37 import org.sonar.db.component.ComponentDto;
38 import org.sonar.db.component.ComponentTesting;
39 import org.sonar.scanner.protocol.output.ScannerReport;
40 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
41 import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
42 import org.sonar.server.computation.task.projectanalysis.analysis.Project;
43 import org.sonar.server.computation.task.projectanalysis.component.BranchPersister;
44 import org.sonar.server.computation.task.projectanalysis.component.Component;
45 import org.sonar.server.computation.task.projectanalysis.component.FileAttributes;
46 import org.sonar.server.computation.task.projectanalysis.component.DefaultBranchImpl;
47 import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepositoryRule;
48 import org.sonar.server.computation.task.projectanalysis.component.MutableDisabledComponentsHolder;
49 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
50 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
51 import org.sonar.server.computation.task.step.ComputationStep;
52
53 import static org.apache.commons.lang.StringUtils.isEmpty;
54 import static org.apache.commons.lang.StringUtils.trimToNull;
55 import static org.assertj.core.api.Assertions.assertThat;
56 import static org.assertj.guava.api.Assertions.assertThat;
57 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
58 import static org.mockito.Mockito.mock;
59 import static org.mockito.Mockito.when;
60 import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
61 import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
62 import static org.sonar.db.component.ComponentTesting.newDirectory;
63 import static org.sonar.db.component.ComponentTesting.newModuleDto;
64 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY;
65 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE;
66 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
67 import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder;
68
69 public class ReportPersistComponentsStepTest extends BaseStepTest {
70
71   private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
72   private static final String PROJECT_KEY = "PROJECT_KEY";
73   private static final String MODULE_KEY = "MODULE_KEY";
74   private static final String ORGANIZATION_UUID = "org1";
75
76   @Rule
77   public DbTester db = DbTester.create(System2.INSTANCE);
78   @Rule
79   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
80   @Rule
81   public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.create(treeRootHolder);
82   @Rule
83   public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
84     .setOrganizationUuid(ORGANIZATION_UUID);
85
86   private System2 system2 = mock(System2.class);
87   private DbClient dbClient = db.getDbClient();
88   private Date now;
89   private MutableDisabledComponentsHolder disabledComponentsHolder = mock(MutableDisabledComponentsHolder.class, RETURNS_DEEP_STUBS);
90   private PersistComponentsStep underTest;
91   private BranchPersister branchPersister;
92
93   @Before
94   public void setup() throws Exception {
95     now = DATE_FORMAT.parse("2015-06-02");
96     when(system2.now()).thenReturn(now.getTime());
97
98     db.organizations().insertForUuid(ORGANIZATION_UUID);
99     branchPersister = mock(BranchPersister.class);
100     underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder, branchPersister);
101   }
102
103   @Override
104   protected ComputationStep step() {
105     return underTest;
106   }
107
108   @Test
109   public void persist_components() {
110     ComponentDto projectDto = prepareProject();
111     Component file = builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java")
112       .setPath("src/main/java/dir/Foo.java")
113       .setFileAttributes(new FileAttributes(false, "java", 1))
114       .build();
115     Component directory = builder(DIRECTORY, 3).setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir")
116       .setPath("src/main/java/dir")
117       .addChildren(file)
118       .build();
119     Component module = builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
120       .setPath("module")
121       .setName("Module")
122       .setDescription("Module description")
123       .addChildren(directory)
124       .build();
125     Component treeRoot = asTreeRoot(projectDto)
126       .addChildren(module)
127       .build();
128     treeRootHolder.setRoot(treeRoot);
129
130     underTest.execute();
131
132     assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
133
134     ComponentDto moduleDto = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
135     assertThat(moduleDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
136     assertThat(moduleDto.name()).isEqualTo("Module");
137     assertThat(moduleDto.description()).isEqualTo("Module description");
138     assertThat(moduleDto.path()).isEqualTo("module");
139     assertThat(moduleDto.uuid()).isEqualTo("BCDE");
140     assertThat(moduleDto.getUuidPath()).isEqualTo(projectDto.getUuidPath() + projectDto.uuid() + UUID_PATH_SEPARATOR);
141     assertThat(moduleDto.moduleUuid()).isEqualTo(projectDto.uuid());
142     assertThat(moduleDto.moduleUuidPath()).isEqualTo(projectDto.moduleUuidPath() + moduleDto.uuid() + ".");
143     assertThat(moduleDto.getMainBranchProjectUuid()).isNull();
144     assertThat(moduleDto.projectUuid()).isEqualTo(projectDto.uuid());
145     assertThat(moduleDto.qualifier()).isEqualTo("BRC");
146     assertThat(moduleDto.scope()).isEqualTo("PRJ");
147     assertThat(moduleDto.getRootUuid()).isEqualTo(projectDto.uuid());
148     assertThat(moduleDto.getCreatedAt()).isEqualTo(now);
149
150     ComponentDto directoryDto = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
151     assertThat(directoryDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
152     assertThat(directoryDto.name()).isEqualTo("src/main/java/dir");
153     assertThat(directoryDto.description()).isNull();
154     assertThat(directoryDto.path()).isEqualTo("src/main/java/dir");
155     assertThat(directoryDto.uuid()).isEqualTo("CDEF");
156     assertThat(directoryDto.getUuidPath()).isEqualTo(moduleDto.getUuidPath() + moduleDto.uuid() + UUID_PATH_SEPARATOR);
157     assertThat(directoryDto.moduleUuid()).isEqualTo(moduleDto.uuid());
158     assertThat(directoryDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
159     assertThat(directoryDto.getMainBranchProjectUuid()).isNull();
160     assertThat(directoryDto.projectUuid()).isEqualTo(projectDto.uuid());
161     assertThat(directoryDto.qualifier()).isEqualTo("DIR");
162     assertThat(directoryDto.scope()).isEqualTo("DIR");
163     assertThat(directoryDto.getRootUuid()).isEqualTo(moduleDto.uuid());
164     assertThat(directoryDto.getCreatedAt()).isEqualTo(now);
165
166     ComponentDto fileDto = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
167     assertThat(fileDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
168     assertThat(fileDto.name()).isEqualTo("Foo.java");
169     assertThat(fileDto.description()).isNull();
170     assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java");
171     assertThat(fileDto.language()).isEqualTo("java");
172     assertThat(fileDto.uuid()).isEqualTo("DEFG");
173     assertThat(fileDto.getUuidPath()).isEqualTo(directoryDto.getUuidPath() + directoryDto.uuid() + UUID_PATH_SEPARATOR);
174     assertThat(fileDto.moduleUuid()).isEqualTo(moduleDto.uuid());
175     assertThat(fileDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
176     assertThat(fileDto.getMainBranchProjectUuid()).isNull();
177     assertThat(fileDto.projectUuid()).isEqualTo(projectDto.uuid());
178     assertThat(fileDto.qualifier()).isEqualTo("FIL");
179     assertThat(fileDto.scope()).isEqualTo("FIL");
180     assertThat(fileDto.getRootUuid()).isEqualTo(moduleDto.uuid());
181     assertThat(fileDto.getCreatedAt()).isEqualTo(now);
182
183     assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId());
184     assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId());
185     assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId());
186   }
187
188   @Test
189   public void persist_components_of_existing_branch() {
190     ComponentDto project = prepareBranch("feature/foo");
191     Component file = builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java")
192       .setPath("src/main/java/dir/Foo.java")
193       .setFileAttributes(new FileAttributes(false, "java", 1))
194       .build();
195     Component directory = builder(DIRECTORY, 3).setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir")
196       .setPath("src/main/java/dir")
197       .addChildren(file)
198       .build();
199     Component module = builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
200       .setPath("module")
201       .setName("Module")
202       .setDescription("Module description")
203       .addChildren(directory)
204       .build();
205     Component treeRoot = asTreeRoot(project)
206       .addChildren(module)
207       .build();
208     treeRootHolder.setRoot(treeRoot);
209
210     underTest.execute();
211
212     assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
213
214     ComponentDto moduleDto = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
215     assertThat(moduleDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
216     assertThat(moduleDto.name()).isEqualTo("Module");
217     assertThat(moduleDto.description()).isEqualTo("Module description");
218     assertThat(moduleDto.path()).isEqualTo("module");
219     assertThat(moduleDto.uuid()).isEqualTo("BCDE");
220     assertThat(moduleDto.getUuidPath()).isEqualTo(project.getUuidPath() + project.uuid() + UUID_PATH_SEPARATOR);
221     assertThat(moduleDto.moduleUuid()).isEqualTo(project.uuid());
222     assertThat(moduleDto.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + moduleDto.uuid() + ".");
223     assertThat(moduleDto.getMainBranchProjectUuid()).isEqualTo(project.uuid());
224     assertThat(moduleDto.projectUuid()).isEqualTo(project.uuid());
225     assertThat(moduleDto.qualifier()).isEqualTo("BRC");
226     assertThat(moduleDto.scope()).isEqualTo("PRJ");
227     assertThat(moduleDto.getRootUuid()).isEqualTo(project.uuid());
228     assertThat(moduleDto.getCreatedAt()).isEqualTo(now);
229
230     ComponentDto directoryDto = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
231     assertThat(directoryDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
232     assertThat(directoryDto.name()).isEqualTo("src/main/java/dir");
233     assertThat(directoryDto.description()).isNull();
234     assertThat(directoryDto.path()).isEqualTo("src/main/java/dir");
235     assertThat(directoryDto.uuid()).isEqualTo("CDEF");
236     assertThat(directoryDto.getUuidPath()).isEqualTo(moduleDto.getUuidPath() + moduleDto.uuid() + UUID_PATH_SEPARATOR);
237     assertThat(directoryDto.moduleUuid()).isEqualTo(moduleDto.uuid());
238     assertThat(directoryDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
239     assertThat(directoryDto.getMainBranchProjectUuid()).isEqualTo(project.uuid());
240     assertThat(directoryDto.projectUuid()).isEqualTo(project.uuid());
241     assertThat(directoryDto.qualifier()).isEqualTo("DIR");
242     assertThat(directoryDto.scope()).isEqualTo("DIR");
243     assertThat(directoryDto.getRootUuid()).isEqualTo(moduleDto.uuid());
244     assertThat(directoryDto.getCreatedAt()).isEqualTo(now);
245
246     ComponentDto fileDto = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
247     assertThat(fileDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
248     assertThat(fileDto.name()).isEqualTo("Foo.java");
249     assertThat(fileDto.description()).isNull();
250     assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java");
251     assertThat(fileDto.language()).isEqualTo("java");
252     assertThat(fileDto.uuid()).isEqualTo("DEFG");
253     assertThat(fileDto.getUuidPath()).isEqualTo(directoryDto.getUuidPath() + directoryDto.uuid() + UUID_PATH_SEPARATOR);
254     assertThat(fileDto.moduleUuid()).isEqualTo(moduleDto.uuid());
255     assertThat(fileDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
256     assertThat(fileDto.getMainBranchProjectUuid()).isEqualTo(project.uuid());
257     assertThat(fileDto.projectUuid()).isEqualTo(project.uuid());
258     assertThat(fileDto.qualifier()).isEqualTo("FIL");
259     assertThat(fileDto.scope()).isEqualTo("FIL");
260     assertThat(fileDto.getRootUuid()).isEqualTo(moduleDto.uuid());
261     assertThat(fileDto.getCreatedAt()).isEqualTo(now);
262
263     assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId());
264     assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId());
265     assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId());
266   }
267
268   @Test
269   public void persist_file_directly_attached_on_root_directory() {
270     ComponentDto projectDto = prepareProject();
271     treeRootHolder.setRoot(
272       asTreeRoot(projectDto)
273         .addChildren(
274           builder(DIRECTORY, 2).setUuid("CDEF").setKey(projectDto.getDbKey() + ":/").setPath("/")
275             .addChildren(
276               builder(FILE, 3).setUuid("DEFG").setKey(projectDto.getDbKey() + ":pom.xml").setPath("pom.xml")
277                 .build())
278             .build())
279         .build());
280
281     underTest.execute();
282
283     ComponentDto directory = dbClient.componentDao().selectByKey(db.getSession(), projectDto.getDbKey() + ":/").get();
284     assertThat(directory.name()).isEqualTo("/");
285     assertThat(directory.path()).isEqualTo("/");
286
287     ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), projectDto.getDbKey() + ":pom.xml").get();
288     assertThat(file.name()).isEqualTo("pom.xml");
289     assertThat(file.path()).isEqualTo("pom.xml");
290   }
291
292   @Test
293   public void persist_unit_test() {
294     ComponentDto projectDto = prepareProject();
295     treeRootHolder.setRoot(
296       asTreeRoot(projectDto)
297         .addChildren(
298           builder(DIRECTORY, 2).setUuid("CDEF").setKey(PROJECT_KEY + ":src/test/java/dir")
299             .setPath("src/test/java/dir")
300             .addChildren(
301               builder(FILE, 3).setUuid("DEFG").setKey(PROJECT_KEY + ":src/test/java/dir/FooTest.java")
302                 .setPath("src/test/java/dir/FooTest.java")
303                 .setFileAttributes(new FileAttributes(true, null, 1))
304                 .build())
305             .build())
306         .build());
307
308     underTest.execute();
309
310     ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), PROJECT_KEY + ":src/test/java/dir/FooTest.java").get();
311     assertThat(file.name()).isEqualTo("FooTest.java");
312     assertThat(file.path()).isEqualTo("src/test/java/dir/FooTest.java");
313     assertThat(file.qualifier()).isEqualTo("UTS");
314     assertThat(file.scope()).isEqualTo("FIL");
315   }
316
317   @Test
318   public void persist_only_new_components() {
319     // Project and module already exists
320     ComponentDto project = prepareProject();
321     ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module");
322     dbClient.componentDao().insert(db.getSession(), module);
323     db.getSession().commit();
324
325     treeRootHolder.setRoot(
326       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
327         .setName("Project")
328         .addChildren(
329           builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
330             .setName("Module")
331             .addChildren(
332               builder(DIRECTORY, 3).setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir")
333                 .setPath("src/main/java/dir")
334                 .addChildren(
335                   builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java")
336                     .setPath("src/main/java/dir/Foo.java")
337                     .build())
338                 .build())
339             .build())
340         .build());
341
342     underTest.execute();
343
344     assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
345
346     ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
347     assertThat(projectReloaded.getId()).isEqualTo(project.getId());
348     assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
349     assertThat(projectReloaded.getUuidPath()).isEqualTo(UUID_PATH_OF_ROOT);
350     assertThat(projectReloaded.getMainBranchProjectUuid()).isNull();
351
352     ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
353     assertThat(moduleReloaded.getId()).isEqualTo(module.getId());
354     assertThat(moduleReloaded.uuid()).isEqualTo(module.uuid());
355     assertThat(moduleReloaded.getUuidPath()).isEqualTo(module.getUuidPath());
356     assertThat(moduleReloaded.moduleUuid()).isEqualTo(module.moduleUuid());
357     assertThat(moduleReloaded.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
358     assertThat(moduleReloaded.projectUuid()).isEqualTo(module.projectUuid());
359     assertThat(moduleReloaded.getRootUuid()).isEqualTo(module.getRootUuid());
360     assertThat(moduleReloaded.getMainBranchProjectUuid()).isNull();
361
362     ComponentDto directory = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
363     assertThat(directory.getUuidPath()).isEqualTo(directory.getUuidPath());
364     assertThat(directory.moduleUuid()).isEqualTo(module.uuid());
365     assertThat(directory.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
366     assertThat(directory.projectUuid()).isEqualTo(project.uuid());
367     assertThat(directory.getRootUuid()).isEqualTo(module.uuid());
368     assertThat(directory.getMainBranchProjectUuid()).isNull();
369
370     ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
371     assertThat(file.getUuidPath()).isEqualTo(file.getUuidPath());
372     assertThat(file.moduleUuid()).isEqualTo(module.uuid());
373     assertThat(file.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
374     assertThat(file.projectUuid()).isEqualTo(project.uuid());
375     assertThat(file.getRootUuid()).isEqualTo(module.uuid());
376     assertThat(file.getMainBranchProjectUuid()).isNull();
377   }
378
379   @Test
380   public void compute_root_uuid() {
381     ComponentDto project = prepareProject();
382     treeRootHolder.setRoot(
383       asTreeRoot(project)
384         .addChildren(
385           builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
386             .setName("Module")
387             .addChildren(
388               builder(Component.Type.MODULE, 3).setUuid("CDEF").setKey("SUB_MODULE_1_KEY")
389                 .setName("Sub Module 1")
390                 .addChildren(
391                   builder(Component.Type.MODULE, 4).setUuid("DEFG").setKey("SUB_MODULE_2_KEY")
392                     .setName("Sub Module 2")
393                     .addChildren(
394                       builder(DIRECTORY, 5).setUuid("EFGH").setKey("SUB_MODULE_2_KEY:src/main/java/dir")
395                         .setPath("src/main/java/dir")
396                         .build())
397                     .build())
398                 .build())
399             .build())
400         .build());
401
402     underTest.execute();
403
404     assertThat(db.countRowsOfTable("projects")).isEqualTo(5);
405
406     Optional<ComponentDto> module = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY);
407     assertThat(module).isPresent();
408     assertThat(module.get().getRootUuid()).isEqualTo(project.uuid());
409
410     Optional<ComponentDto> subModule1 = dbClient.componentDao().selectByKey(db.getSession(), "SUB_MODULE_1_KEY");
411     assertThat(subModule1).isPresent();
412     assertThat(subModule1.get().getRootUuid()).isEqualTo(project.uuid());
413
414     Optional<ComponentDto> subModule2 = dbClient.componentDao().selectByKey(db.getSession(), "SUB_MODULE_2_KEY");
415     assertThat(subModule2).isPresent();
416     assertThat(subModule2.get().getRootUuid()).isEqualTo(project.uuid());
417
418     Optional<ComponentDto> directory = dbClient.componentDao().selectByKey(db.getSession(), "SUB_MODULE_2_KEY:src/main/java/dir");
419     assertThat(directory).isPresent();
420     assertThat(directory.get().getRootUuid()).isEqualTo(subModule2.get().uuid());
421   }
422
423   @Test
424   public void persist_multi_modules() {
425     ComponentDto project = prepareProject();
426     treeRootHolder.setRoot(
427       asTreeRoot(project)
428         .setName("Project")
429         .addChildren(
430           builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey("MODULE_A")
431             .setName("Module A")
432             .addChildren(
433               builder(Component.Type.MODULE, 3).setUuid("DEFG").setKey("SUB_MODULE_A")
434                 .setName("Sub Module A")
435                 .build())
436             .build(),
437           builder(Component.Type.MODULE, 4).setUuid("CDEF").setKey("MODULE_B")
438             .setName("Module B")
439             .build())
440         .build());
441
442     underTest.execute();
443
444     assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
445
446     ComponentDto moduleA = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_A").get();
447     assertThat(moduleA.getUuidPath()).isEqualTo(project.getUuidPath() + project.uuid() + UUID_PATH_SEPARATOR);
448     assertThat(moduleA.moduleUuid()).isEqualTo(project.uuid());
449     assertThat(moduleA.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + moduleA.uuid() + ".");
450     assertThat(moduleA.getRootUuid()).isEqualTo(project.uuid());
451
452     ComponentDto subModuleA = dbClient.componentDao().selectByKey(db.getSession(), "SUB_MODULE_A").get();
453     assertThat(subModuleA.getUuidPath()).isEqualTo(moduleA.getUuidPath() + moduleA.uuid() + UUID_PATH_SEPARATOR);
454     assertThat(subModuleA.moduleUuid()).isEqualTo(moduleA.uuid());
455     assertThat(subModuleA.moduleUuidPath()).isEqualTo(moduleA.moduleUuidPath() + subModuleA.uuid() + ".");
456     assertThat(subModuleA.getRootUuid()).isEqualTo(project.uuid());
457
458     ComponentDto moduleB = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_B").get();
459     assertThat(moduleB.getUuidPath()).isEqualTo(project.getUuidPath() + project.uuid() + UUID_PATH_SEPARATOR);
460     assertThat(moduleB.moduleUuid()).isEqualTo(project.uuid());
461     assertThat(moduleB.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + moduleB.uuid() + ".");
462     assertThat(moduleB.getRootUuid()).isEqualTo(project.uuid());
463   }
464
465   @Test
466   public void nothing_to_persist() {
467     ComponentDto project = prepareProject();
468     ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module");
469     dbClient.componentDao().insert(db.getSession(), module);
470     ComponentDto directory = ComponentTesting.newDirectory(module, "src/main/java/dir").setUuid("CDEF").setDbKey("MODULE_KEY:src/main/java/dir");
471     ComponentDto file = ComponentTesting.newFileDto(module, directory, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java")
472       .setDbKey("MODULE_KEY:src/main/java/dir/Foo.java");
473     dbClient.componentDao().insert(db.getSession(), directory, file);
474     db.getSession().commit();
475
476     treeRootHolder.setRoot(
477       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
478         .setName("Project")
479         .addChildren(
480           builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
481             .setName("Module")
482             .addChildren(
483               builder(DIRECTORY, 3).setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir")
484                 .setPath("src/main/java/dir")
485                 .addChildren(
486                   builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java")
487                     .setPath("src/main/java/dir/Foo.java")
488                     .build())
489                 .build())
490             .build())
491         .build());
492
493     underTest.execute();
494
495     assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
496     assertThat(dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get().getId()).isEqualTo(project.getId());
497     assertThat(dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get().getId()).isEqualTo(module.getId());
498     assertThat(dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get().getId()).isEqualTo(directory.getId());
499     assertThat(dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get().getId()).isEqualTo(file.getId());
500
501     ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
502     assertThat(projectReloaded.getId()).isEqualTo(project.getId());
503     assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
504     assertThat(projectReloaded.moduleUuid()).isEqualTo(project.moduleUuid());
505     assertThat(projectReloaded.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
506     assertThat(projectReloaded.projectUuid()).isEqualTo(project.projectUuid());
507     assertThat(projectReloaded.getRootUuid()).isEqualTo(project.getRootUuid());
508
509     ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
510     assertThat(moduleReloaded.getId()).isEqualTo(module.getId());
511     assertThat(moduleReloaded.uuid()).isEqualTo(module.uuid());
512     assertThat(moduleReloaded.getUuidPath()).isEqualTo(module.getUuidPath());
513     assertThat(moduleReloaded.moduleUuid()).isEqualTo(module.moduleUuid());
514     assertThat(moduleReloaded.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
515     assertThat(moduleReloaded.projectUuid()).isEqualTo(module.projectUuid());
516     assertThat(moduleReloaded.getRootUuid()).isEqualTo(module.getRootUuid());
517
518     ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
519     assertThat(directoryReloaded.uuid()).isEqualTo(directory.uuid());
520     assertThat(directoryReloaded.getUuidPath()).isEqualTo(directory.getUuidPath());
521     assertThat(directoryReloaded.moduleUuid()).isEqualTo(directory.moduleUuid());
522     assertThat(directoryReloaded.moduleUuidPath()).isEqualTo(directory.moduleUuidPath());
523     assertThat(directoryReloaded.projectUuid()).isEqualTo(directory.projectUuid());
524     assertThat(directoryReloaded.getRootUuid()).isEqualTo(directory.getRootUuid());
525     assertThat(directoryReloaded.name()).isEqualTo(directory.name());
526     assertThat(directoryReloaded.path()).isEqualTo(directory.path());
527
528     ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
529     assertThat(fileReloaded.uuid()).isEqualTo(file.uuid());
530     assertThat(fileReloaded.getUuidPath()).isEqualTo(file.getUuidPath());
531     assertThat(fileReloaded.moduleUuid()).isEqualTo(file.moduleUuid());
532     assertThat(fileReloaded.moduleUuidPath()).isEqualTo(file.moduleUuidPath());
533     assertThat(fileReloaded.projectUuid()).isEqualTo(file.projectUuid());
534     assertThat(fileReloaded.getRootUuid()).isEqualTo(file.getRootUuid());
535     assertThat(fileReloaded.name()).isEqualTo(file.name());
536     assertThat(fileReloaded.path()).isEqualTo(file.path());
537   }
538
539   @Test
540   public void update_module_name_and_description() {
541     ComponentDto project = prepareProject(p -> p.setName("Project").setDescription("Project description"));
542     ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module");
543     dbClient.componentDao().insert(db.getSession(), module);
544     db.getSession().commit();
545
546     treeRootHolder.setRoot(
547       builder(PROJECT, 1)
548         .setUuid(project.uuid())
549         .setKey(project.getDbKey())
550         .setName("New Project")
551         .setDescription("New project description")
552         .addChildren(
553           builder(Component.Type.MODULE, 2)
554             .setUuid("BCDE")
555             .setKey(MODULE_KEY)
556             .setName("New Module")
557             .setDescription("New module description")
558             .build())
559         .build());
560
561     underTest.execute();
562
563     // functional transaction not finished, "A-fields" are not updated yet
564     assertNameAndDescription(project.getDbKey(), "Project", "Project description");
565     assertNameAndDescription(MODULE_KEY, "Module", null);
566
567     // commit functional transaction -> copies B-fields to A-fields
568     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
569     assertNameAndDescription(project.getDbKey(), "New Project", "New project description");
570     assertNameAndDescription(MODULE_KEY, "New Module", "New module description");
571   }
572
573   private void assertNameAndDescription(String key, String expectedName, String expectedDescription) {
574     ComponentDto dto = dbClient.componentDao().selectByKey(db.getSession(), key).get();
575     assertThat(dto.name()).isEqualTo(expectedName);
576     assertThat(dto.description()).isEqualTo(expectedDescription);
577   }
578
579   @Test
580   public void update_module_path() {
581     ComponentDto project = prepareProject();
582     ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module").setPath("path");
583     dbClient.componentDao().insert(db.getSession(), module);
584     db.getSession().commit();
585
586     treeRootHolder.setRoot(
587       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
588         .setName("Project")
589         .addChildren(
590           builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
591             .setName("Module")
592             .setPath("New path")
593             .build())
594         .build());
595
596     underTest.execute();
597
598     assertThat(dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get().path()).isEqualTo("path");
599
600     // commit the functional transaction
601     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
602     assertThat(dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get().path()).isEqualTo("New path");
603   }
604
605   @Test
606   public void update_module_uuid_when_moving_a_module() {
607     ComponentDto project = prepareProject();
608     ComponentDto moduleA = ComponentTesting.newModuleDto("EDCB", project)
609       .setDbKey("MODULE_A")
610       .setName("Module A");
611     ComponentDto moduleB = ComponentTesting.newModuleDto("BCDE", project)
612       .setDbKey("MODULE_B")
613       .setName("Module B");
614     dbClient.componentDao().insert(db.getSession(), moduleA, moduleB);
615     ComponentDto directory = ComponentTesting.newDirectory(moduleB, "src/main/java/dir").setUuid("CDEF").setDbKey("MODULE_B:src/main/java/dir");
616     ComponentDto file = ComponentTesting.newFileDto(moduleB, directory, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java")
617       .setDbKey("MODULE_B:src/main/java/dir/Foo.java");
618     dbClient.componentDao().insert(db.getSession(), directory, file);
619     db.getSession().commit();
620
621     treeRootHolder.setRoot(
622       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
623         .setName("Project")
624         .addChildren(
625           builder(Component.Type.MODULE, 2).setUuid("EDCB").setKey("MODULE_A")
626             .setName("Module A")
627             .addChildren(
628               builder(Component.Type.MODULE, 3).setUuid("BCDE").setKey("MODULE_B")
629                 .setName("Module B")
630                 .addChildren(
631                   builder(DIRECTORY, 4).setUuid("CDEF").setKey("MODULE_B:src/main/java/dir")
632                     .setPath("src/main/java/dir")
633                     .addChildren(
634                       builder(FILE, 5).setUuid("DEFG").setKey("MODULE_B:src/main/java/dir/Foo.java")
635                         .setPath("src/main/java/dir/Foo.java")
636                         .build())
637                     .build())
638                 .build())
639             .build())
640         .build());
641
642     underTest.execute();
643
644     // commit the functional transaction
645     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
646     db.commit();
647
648     assertThat(db.countRowsOfTable("projects")).isEqualTo(5);
649
650     ComponentDto moduleAreloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_A").get();
651
652     ComponentDto moduleBReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_B").get();
653     assertThat(moduleBReloaded).isNotNull();
654     assertThat(moduleBReloaded.uuid()).isEqualTo(moduleB.uuid());
655     assertThat(moduleBReloaded.getUuidPath()).isEqualTo(moduleBReloaded.getUuidPath());
656     assertThat(moduleBReloaded.moduleUuid()).isEqualTo(moduleAreloaded.uuid());
657     assertThat(moduleBReloaded.moduleUuidPath()).isEqualTo(moduleAreloaded.moduleUuidPath() + moduleBReloaded.uuid() + ".");
658     assertThat(moduleBReloaded.projectUuid()).isEqualTo(project.uuid());
659     assertThat(moduleBReloaded.getRootUuid()).isEqualTo(project.uuid());
660
661     ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_B:src/main/java/dir").get();
662     assertThat(directoryReloaded).isNotNull();
663     assertThat(directoryReloaded.uuid()).isEqualTo(directory.uuid());
664     assertThat(directoryReloaded.getUuidPath()).isEqualTo(directoryReloaded.getUuidPath());
665     assertThat(directoryReloaded.moduleUuid()).isEqualTo(moduleBReloaded.uuid());
666     assertThat(directoryReloaded.moduleUuidPath()).isEqualTo(moduleBReloaded.moduleUuidPath());
667     assertThat(directoryReloaded.projectUuid()).isEqualTo(project.uuid());
668     assertThat(directoryReloaded.getRootUuid()).isEqualTo(moduleBReloaded.uuid());
669
670     ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_B:src/main/java/dir/Foo.java").get();
671     assertThat(fileReloaded).isNotNull();
672     assertThat(fileReloaded.uuid()).isEqualTo(file.uuid());
673     assertThat(fileReloaded.getUuidPath()).isEqualTo(fileReloaded.getUuidPath());
674     assertThat(fileReloaded.moduleUuid()).isEqualTo(moduleBReloaded.uuid());
675     assertThat(fileReloaded.moduleUuidPath()).isEqualTo(moduleBReloaded.moduleUuidPath());
676     assertThat(fileReloaded.projectUuid()).isEqualTo(project.uuid());
677     assertThat(fileReloaded.getRootUuid()).isEqualTo(moduleBReloaded.uuid());
678   }
679
680   @Test
681   public void do_not_update_created_at_on_existing_component() {
682     Date oldDate = DateUtils.parseDate("2015-01-01");
683     ComponentDto project = prepareProject(p -> p.setCreatedAt(oldDate));
684     ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module").setPath("path").setCreatedAt(oldDate);
685     dbClient.componentDao().insert(db.getSession(), module);
686     db.getSession().commit();
687
688     treeRootHolder.setRoot(
689       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
690         .build());
691
692     underTest.execute();
693
694     Optional<ComponentDto> projectReloaded = dbClient.componentDao().selectByUuid(db.getSession(), project.uuid());
695     assertThat(projectReloaded.get().getCreatedAt()).isNotEqualTo(now);
696   }
697
698   @Test
699   public void persist_components_that_were_previously_removed() {
700     ComponentDto project = prepareProject();
701     ComponentDto removedModule = ComponentTesting.newModuleDto("BCDE", project)
702       .setDbKey(MODULE_KEY)
703       .setName("Module")
704       .setEnabled(false);
705     dbClient.componentDao().insert(db.getSession(), removedModule);
706     ComponentDto removedDirectory = ComponentTesting.newDirectory(removedModule, "src/main/java/dir")
707       .setUuid("CDEF")
708       .setDbKey("MODULE_KEY:src/main/java/dir")
709       .setEnabled(false);
710     ComponentDto removedFile = ComponentTesting.newFileDto(removedModule, removedDirectory, "DEFG")
711       .setPath("src/main/java/dir/Foo.java")
712       .setName("Foo.java")
713       .setDbKey("MODULE_KEY:src/main/java/dir/Foo.java")
714       .setEnabled(false);
715     dbClient.componentDao().insert(db.getSession(), removedDirectory, removedFile);
716     db.getSession().commit();
717
718     treeRootHolder.setRoot(
719       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
720         .setName("Project")
721         .addChildren(
722           builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
723             .setName("Module")
724             .addChildren(
725               builder(DIRECTORY, 3).setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir")
726                 .setPath("src/main/java/dir")
727                 .addChildren(
728                   builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java")
729                     .setPath("src/main/java/dir/Foo.java")
730                     .build())
731                 .build())
732             .build())
733         .build());
734
735     underTest.execute();
736
737     assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
738     assertThat(dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get().getId()).isEqualTo(project.getId());
739     assertThat(dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get().getId()).isEqualTo(removedModule.getId());
740     assertThat(dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get().getId()).isEqualTo(removedDirectory.getId());
741     assertThat(dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get().getId()).isEqualTo(removedFile.getId());
742     assertExistButDisabled(removedModule.getDbKey(), removedDirectory.getDbKey(), removedFile.getDbKey());
743
744     // commit the functional transaction
745     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
746
747     ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
748     assertThat(projectReloaded.getId()).isEqualTo(project.getId());
749     assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
750     assertThat(projectReloaded.getUuidPath()).isEqualTo(project.getUuidPath());
751     assertThat(projectReloaded.moduleUuid()).isEqualTo(project.moduleUuid());
752     assertThat(projectReloaded.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
753     assertThat(projectReloaded.projectUuid()).isEqualTo(project.projectUuid());
754     assertThat(projectReloaded.getRootUuid()).isEqualTo(project.getRootUuid());
755     assertThat(projectReloaded.isEnabled()).isTrue();
756
757     ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
758     assertThat(moduleReloaded.getId()).isEqualTo(removedModule.getId());
759     assertThat(moduleReloaded.uuid()).isEqualTo(removedModule.uuid());
760     assertThat(moduleReloaded.getUuidPath()).isEqualTo(removedModule.getUuidPath());
761     assertThat(moduleReloaded.moduleUuid()).isEqualTo(removedModule.moduleUuid());
762     assertThat(moduleReloaded.moduleUuidPath()).isEqualTo(removedModule.moduleUuidPath());
763     assertThat(moduleReloaded.projectUuid()).isEqualTo(removedModule.projectUuid());
764     assertThat(moduleReloaded.getRootUuid()).isEqualTo(removedModule.getRootUuid());
765     assertThat(moduleReloaded.isEnabled()).isTrue();
766
767     ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
768     assertThat(directoryReloaded.getId()).isEqualTo(removedDirectory.getId());
769     assertThat(directoryReloaded.uuid()).isEqualTo(removedDirectory.uuid());
770     assertThat(directoryReloaded.getUuidPath()).isEqualTo(removedDirectory.getUuidPath());
771     assertThat(directoryReloaded.moduleUuid()).isEqualTo(removedDirectory.moduleUuid());
772     assertThat(directoryReloaded.moduleUuidPath()).isEqualTo(removedDirectory.moduleUuidPath());
773     assertThat(directoryReloaded.projectUuid()).isEqualTo(removedDirectory.projectUuid());
774     assertThat(directoryReloaded.getRootUuid()).isEqualTo(removedDirectory.getRootUuid());
775     assertThat(directoryReloaded.name()).isEqualTo(removedDirectory.name());
776     assertThat(directoryReloaded.path()).isEqualTo(removedDirectory.path());
777     assertThat(directoryReloaded.isEnabled()).isTrue();
778
779     ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
780     assertThat(fileReloaded.getId()).isEqualTo(fileReloaded.getId());
781     assertThat(fileReloaded.uuid()).isEqualTo(removedFile.uuid());
782     assertThat(fileReloaded.getUuidPath()).isEqualTo(removedFile.getUuidPath());
783     assertThat(fileReloaded.moduleUuid()).isEqualTo(removedFile.moduleUuid());
784     assertThat(fileReloaded.moduleUuidPath()).isEqualTo(removedFile.moduleUuidPath());
785     assertThat(fileReloaded.projectUuid()).isEqualTo(removedFile.projectUuid());
786     assertThat(fileReloaded.getRootUuid()).isEqualTo(removedFile.getRootUuid());
787     assertThat(fileReloaded.name()).isEqualTo(removedFile.name());
788     assertThat(fileReloaded.path()).isEqualTo(removedFile.path());
789     assertThat(fileReloaded.isEnabled()).isTrue();
790   }
791
792   private void assertExistButDisabled(String... keys) {
793     for (String key : keys) {
794       ComponentDto dto = dbClient.componentDao().selectByKey(db.getSession(), key).get();
795       assertThat(dto.isEnabled()).isFalse();
796     }
797   }
798
799   @Test
800   public void update_module_uuid_when_reactivating_removed_component() {
801     ComponentDto project = prepareProject();
802     ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module");
803     ComponentDto removedModule = ComponentTesting.newModuleDto("EDCD", project).setDbKey("REMOVED_MODULE_KEY").setName("Removed Module").setEnabled(false);
804     dbClient.componentDao().insert(db.getSession(), module, removedModule);
805     ComponentDto directory = ComponentTesting.newDirectory(module, "src/main/java/dir").setUuid("CDEF").setDbKey("MODULE_KEY:src/main/java/dir");
806     // The file was attached to another module
807     ComponentDto removedFile = ComponentTesting.newFileDto(removedModule, directory, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java")
808       .setDbKey("MODULE_KEY:src/main/java/dir/Foo.java").setEnabled(false);
809     dbClient.componentDao().insert(db.getSession(), directory, removedFile);
810     db.getSession().commit();
811
812     treeRootHolder.setRoot(
813       builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
814         .setName("Project")
815         .addChildren(
816           builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
817             .setName("Module")
818             .addChildren(
819               builder(DIRECTORY, 3).setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir")
820                 .setPath("src/main/java/dir")
821                 .addChildren(
822                   builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java")
823                     .setPath("src/main/java/dir/Foo.java")
824                     .build())
825                 .build())
826             .build())
827         .build());
828
829     underTest.execute();
830
831     // commit the functional transaction
832     dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
833     db.commit();
834
835     // Projects contains 4 components from the report + one removed module
836     assertThat(db.countRowsOfTable("projects")).isEqualTo(5);
837
838     ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
839
840     ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
841     assertThat(fileReloaded.getId()).isEqualTo(removedFile.getId());
842     assertThat(fileReloaded.uuid()).isEqualTo(removedFile.uuid());
843     assertThat(fileReloaded.getUuidPath()).isEqualTo(fileReloaded.getUuidPath());
844     assertThat(fileReloaded.moduleUuid()).isEqualTo(moduleReloaded.uuid());
845     assertThat(fileReloaded.moduleUuidPath()).isEqualTo(moduleReloaded.moduleUuidPath());
846     assertThat(fileReloaded.projectUuid()).isEqualTo(moduleReloaded.projectUuid());
847     assertThat(fileReloaded.name()).isEqualTo(removedFile.name());
848     assertThat(fileReloaded.path()).isEqualTo(removedFile.path());
849     assertThat(fileReloaded.isEnabled()).isTrue();
850   }
851
852   @Test
853   public void persists_existing_components_with_visibility_of_root_in_db_out_of_functional_transaction() {
854     ComponentDto project = prepareProject(p -> p.setPrivate(true));
855     ComponentDto module = newModuleDto(project).setPrivate(false);
856     db.components().insertComponent(module);
857     ComponentDto dir = db.components().insertComponent(newDirectory(module, "DEFG", "Directory").setDbKey("DIR").setPrivate(true));
858     treeRootHolder.setRoot(createSampleProjectComponentTree(project));
859
860     underTest.execute();
861
862     Stream.of(project.uuid(), module.uuid(), dir.uuid())
863       .forEach(uuid -> assertThat(dbClient.componentDao().selectByUuid(db.getSession(), uuid).get().isPrivate())
864         .describedAs("for uuid " + uuid)
865         .isEqualTo(true));
866   }
867
868   private ReportComponent createSampleProjectComponentTree(ComponentDto project) {
869     return createSampleProjectComponentTree(project.uuid(), project.getDbKey());
870   }
871
872   private ReportComponent createSampleProjectComponentTree(String projectUuid, String projectKey) {
873     return builder(PROJECT, 1).setUuid(projectUuid).setKey(projectKey)
874       .setName("Project")
875       .addChildren(
876         builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey("MODULE")
877           .setName("Module")
878           .addChildren(
879             builder(Component.Type.DIRECTORY, 3).setUuid("DEFG").setKey("DIR")
880               .setPath("Directory")
881               .addChildren(
882                 builder(FILE, 4).setUuid("CDEF").setKey("FILE")
883                   .setPath("file")
884                   .build())
885               .build())
886           .build())
887       .build();
888   }
889
890   private ReportComponent.Builder asTreeRoot(ComponentDto project) {
891     return builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey()).setName(project.name());
892   }
893
894   private ComponentDto prepareProject(Consumer<ComponentDto>... populators) {
895     ComponentDto dto = db.components().insertPrivateProject(db.organizations().insert(), populators);
896     analysisMetadataHolder.setProject(Project.copyOf(dto));
897     analysisMetadataHolder.setBranch(new DefaultBranchImpl());
898     return dto;
899   }
900
901   private ComponentDto prepareBranch(String branchName, Consumer<ComponentDto>... populators) {
902     ComponentDto dto = db.components().insertPrivateProject(db.organizations().insert(), populators);
903     analysisMetadataHolder.setProject(Project.copyOf(dto));
904     analysisMetadataHolder.setBranch(new BranchImpl(branchName));
905     return dto;
906   }
907
908   private static class BranchImpl implements Branch {
909     private final String name;
910
911     public BranchImpl(String name) {
912       this.name = name;
913     }
914
915     @Override
916     public BranchType getType() {
917       return BranchType.LONG;
918     }
919
920     @Override
921     public boolean isMain() {
922       return false;
923     }
924
925     @Override
926     public java.util.Optional<String> getMergeBranchUuid() {
927       return java.util.Optional.empty();
928     }
929
930     @Override
931     public boolean isLegacyFeature() {
932       return false;
933     }
934
935     @Override
936     public java.util.Optional<String> getName() {
937       return java.util.Optional.ofNullable(name);
938     }
939
940     @Override
941     public boolean supportsCrossProjectCpd() {
942       return false;
943     }
944
945     @Override
946     public String generateKey(ScannerReport.Component module, @Nullable ScannerReport.Component fileOrDir) {
947       String moduleKey =  module.getKey();
948       if (fileOrDir == null || isEmpty(fileOrDir.getPath())) {
949         return moduleKey;
950       }
951       return ComponentKeys.createEffectiveKey(moduleKey, trimToNull(fileOrDir.getPath()));
952     }
953   }
954 }