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.

ExportMeasuresStep.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 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.ce.task.projectexport.steps;
  21. import com.sonarsource.governance.projectdump.protobuf.ProjectDump;
  22. import java.sql.PreparedStatement;
  23. import java.sql.ResultSet;
  24. import java.sql.SQLException;
  25. import org.slf4j.LoggerFactory;
  26. import org.sonar.ce.task.projectexport.component.ComponentRepository;
  27. import org.sonar.ce.task.step.ComputationStep;
  28. import org.sonar.db.DatabaseUtils;
  29. import org.sonar.db.DbClient;
  30. import org.sonar.db.DbSession;
  31. import org.sonar.db.component.SnapshotDto;
  32. import static java.lang.String.format;
  33. import static org.apache.commons.lang3.StringUtils.defaultString;
  34. import static org.sonar.db.DatabaseUtils.getDouble;
  35. import static org.sonar.db.DatabaseUtils.getString;
  36. public class ExportMeasuresStep implements ComputationStep {
  37. private static final String QUERY = "select pm.metric_uuid, pm.analysis_uuid, pm.component_uuid, pm.text_value, pm.value," +
  38. " pm.alert_status, pm.alert_text, m.name" +
  39. " from project_measures pm" +
  40. " join metrics m on m.uuid=pm.metric_uuid" +
  41. " join snapshots s on s.uuid=pm.analysis_uuid" +
  42. " join components p on p.uuid=pm.component_uuid" +
  43. " join project_branches pb on pb.uuid=p.uuid" +
  44. " where pb.project_uuid=? and pb.branch_type = 'BRANCH' and pb.exclude_from_purge=?" +
  45. " and s.status=? and p.enabled=? and m.enabled=? and pm.person_id is null";
  46. private final DbClient dbClient;
  47. private final ProjectHolder projectHolder;
  48. private final ComponentRepository componentRepository;
  49. private final MutableMetricRepository metricHolder;
  50. private final DumpWriter dumpWriter;
  51. public ExportMeasuresStep(DbClient dbClient, ProjectHolder projectHolder, ComponentRepository componentRepository, MutableMetricRepository metricHolder,
  52. DumpWriter dumpWriter) {
  53. this.dbClient = dbClient;
  54. this.projectHolder = projectHolder;
  55. this.componentRepository = componentRepository;
  56. this.metricHolder = metricHolder;
  57. this.dumpWriter = dumpWriter;
  58. }
  59. @Override
  60. public void execute(Context context) {
  61. long count = 0L;
  62. try (
  63. StreamWriter<ProjectDump.Measure> output = dumpWriter.newStreamWriter(DumpElement.MEASURES);
  64. DbSession dbSession = dbClient.openSession(false);
  65. PreparedStatement stmt = createSelectStatement(dbSession);
  66. ResultSet rs = stmt.executeQuery()) {
  67. ProjectDump.Measure.Builder measureBuilder = ProjectDump.Measure.newBuilder();
  68. ProjectDump.DoubleValue.Builder doubleBuilder = ProjectDump.DoubleValue.newBuilder();
  69. while (rs.next()) {
  70. ProjectDump.Measure measure = convertToMeasure(rs, measureBuilder, doubleBuilder);
  71. output.write(measure);
  72. count++;
  73. }
  74. LoggerFactory.getLogger(getClass()).debug("{} measures exported", count);
  75. } catch (Exception e) {
  76. throw new IllegalStateException(format("Measure Export failed after processing %d measures successfully", count), e);
  77. }
  78. }
  79. private PreparedStatement createSelectStatement(DbSession dbSession) throws SQLException {
  80. PreparedStatement stmt = dbClient.getMyBatis().newScrollingSelectStatement(dbSession, QUERY);
  81. try {
  82. stmt.setString(1, projectHolder.projectDto().getUuid());
  83. stmt.setBoolean(2, true);
  84. stmt.setString(3, SnapshotDto.STATUS_PROCESSED);
  85. stmt.setBoolean(4, true);
  86. stmt.setBoolean(5, true);
  87. return stmt;
  88. } catch (Exception t) {
  89. DatabaseUtils.closeQuietly(stmt);
  90. throw t;
  91. }
  92. }
  93. private ProjectDump.Measure convertToMeasure(ResultSet rs, ProjectDump.Measure.Builder builder,
  94. ProjectDump.DoubleValue.Builder doubleBuilder) throws SQLException {
  95. long componentRef = componentRepository.getRef(rs.getString(3));
  96. int metricRef = metricHolder.add(rs.getString(1));
  97. String metricKey = rs.getString(8);
  98. builder
  99. .clear()
  100. .setMetricRef(metricRef)
  101. .setAnalysisUuid(rs.getString(2))
  102. .setComponentRef(componentRef)
  103. .setTextValue(defaultString(getString(rs, 4)));
  104. Double value = getDouble(rs, 5);
  105. if (value != null) {
  106. if (metricKey.startsWith("new_")) {
  107. builder.setVariation1(doubleBuilder.setValue(value).build());
  108. } else {
  109. builder.setDoubleValue(doubleBuilder.setValue(value).build());
  110. }
  111. }
  112. builder.setAlertStatus(defaultString(getString(rs, 6)));
  113. builder.setAlertText(defaultString(getString(rs, 7)));
  114. return builder.build();
  115. }
  116. @Override
  117. public String getDescription() {
  118. return "Export measures";
  119. }
  120. }