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