You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ReportQueue.java 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * SonarQube, open source software quality management tool.
  3. * Copyright (C) 2008-2014 SonarSource
  4. * mailto:contact AT sonarsource DOT com
  5. *
  6. * SonarQube 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. * SonarQube 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;
  21. import java.io.File;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.util.List;
  25. import javax.annotation.CheckForNull;
  26. import org.apache.commons.io.FileUtils;
  27. import org.sonar.api.config.Settings;
  28. import org.sonar.api.server.ServerSide;
  29. import org.sonar.api.utils.internal.Uuids;
  30. import org.sonar.api.utils.log.Loggers;
  31. import org.sonar.db.compute.AnalysisReportDto;
  32. import org.sonar.db.DbSession;
  33. import org.sonar.db.MyBatis;
  34. import org.sonar.process.ProcessProperties;
  35. import org.sonar.server.computation.db.AnalysisReportDao;
  36. import org.sonar.server.db.DbClient;
  37. import static org.sonar.db.compute.AnalysisReportDto.Status.PENDING;
  38. @ServerSide
  39. public class ReportQueue {
  40. private final DbClient dbClient;
  41. private final Settings settings;
  42. public ReportQueue(DbClient dbClient, Settings settings) {
  43. this.dbClient = dbClient;
  44. this.settings = settings;
  45. }
  46. public Item add(String projectKey, String projectName, InputStream reportData) {
  47. String uuid = Uuids.create();
  48. File file = reportFileForUuid(uuid);
  49. DbSession session = dbClient.openSession(false);
  50. try {
  51. saveReportOnDisk(reportData, file);
  52. AnalysisReportDto dto = saveReportMetadataInDatabase(projectKey, projectName, uuid, session);
  53. return new Item(dto, file);
  54. } catch (Exception e) {
  55. FileUtils.deleteQuietly(file);
  56. throw new IllegalStateException("Fail to store analysis report of project " + projectKey, e);
  57. } finally {
  58. MyBatis.closeQuietly(session);
  59. }
  60. }
  61. private AnalysisReportDto saveReportMetadataInDatabase(String projectKey, String projectName, String uuid, DbSession session) {
  62. AnalysisReportDto dto = new AnalysisReportDto()
  63. .setProjectKey(projectKey)
  64. .setProjectName(projectName)
  65. .setStatus(PENDING)
  66. .setUuid(uuid);
  67. dao().insert(session, dto);
  68. session.commit();
  69. return dto;
  70. }
  71. private AnalysisReportDao dao() {
  72. return dbClient.analysisReportDao();
  73. }
  74. private static void saveReportOnDisk(InputStream reportData, File file) throws IOException {
  75. FileUtils.copyInputStreamToFile(reportData, file);
  76. }
  77. public void remove(Item item) {
  78. DbSession session = dbClient.openSession(false);
  79. try {
  80. FileUtils.deleteQuietly(item.zipFile);
  81. dao().delete(session, item.dto.getId());
  82. session.commit();
  83. } finally {
  84. MyBatis.closeQuietly(session);
  85. }
  86. }
  87. @CheckForNull
  88. public Item pop() {
  89. DbSession session = dbClient.openSession(false);
  90. try {
  91. AnalysisReportDto dto = dao().pop(session);
  92. if (dto != null) {
  93. File file = reportFileForUuid(dto.getUuid());
  94. if (file.exists()) {
  95. return new Item(dto, file);
  96. }
  97. Loggers.get(getClass()).error("Analysis report not found: " + file.getAbsolutePath());
  98. dao().delete(session, dto.getId());
  99. session.commit();
  100. }
  101. return null;
  102. } finally {
  103. MyBatis.closeQuietly(session);
  104. }
  105. }
  106. /**
  107. * Truncates table ANALYSIS_REPORTS and delete all files from directory {data}/analysis
  108. */
  109. public void clear() {
  110. File dir = reportsDir();
  111. try {
  112. FileUtils.deleteDirectory(dir);
  113. } catch (IOException e) {
  114. throw new IllegalStateException("Fail to delete directory: " + dir.getAbsolutePath(), e);
  115. }
  116. DbSession session = dbClient.openSession(false);
  117. try {
  118. dao().truncate(session);
  119. session.commit();
  120. } finally {
  121. MyBatis.closeQuietly(session);
  122. }
  123. }
  124. public void resetToPendingStatus() {
  125. DbSession session = dbClient.openSession(false);
  126. try {
  127. dao().resetAllToPendingStatus(session);
  128. session.commit();
  129. } finally {
  130. MyBatis.closeQuietly(session);
  131. }
  132. }
  133. /**
  134. * All the reports of the queue, whatever the status
  135. */
  136. public List<AnalysisReportDto> all() {
  137. DbSession session = dbClient.openSession(false);
  138. try {
  139. return dao().selectAll(session);
  140. } finally {
  141. MyBatis.closeQuietly(session);
  142. }
  143. }
  144. /**
  145. * This directory is a flat list of the reports referenced in table ANALYSIS_REPORTS.
  146. * Never return null but the directory may not exist.
  147. */
  148. private File reportsDir() {
  149. return new File(settings.getString(ProcessProperties.PATH_DATA), "analysis");
  150. }
  151. private File reportFileForUuid(String uuid) {
  152. return new File(reportsDir(), String.format("%s.zip", uuid));
  153. }
  154. public static class Item {
  155. public final AnalysisReportDto dto;
  156. public final File zipFile;
  157. public Item(AnalysisReportDto dto, File zipFile) {
  158. this.dto = dto;
  159. this.zipFile = zipFile;
  160. }
  161. }
  162. }