]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6620 persist metrics based on MetricRepository
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Fri, 12 Jun 2015 09:44:17 +0000 (11:44 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 15 Jun 2015 11:07:53 +0000 (13:07 +0200)
server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureToMeasureDto.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureToMeasureDtoTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java

index 8d08c9bc57407d96d01382b2932f91368bb98684..673a8bf58a2a843e708a87728a8bdf49fab94056 100644 (file)
@@ -46,7 +46,7 @@ public final class MeasureImpl implements Measure {
   @Nullable
   private String description;
 
-  protected MeasureImpl(ValueType valueType, @Nullable Integer ruleId, @Nullable Integer characteristicId, @Nullable Double value, @Nullable String data, @Nullable Level dataLevel) {
+  private MeasureImpl(ValueType valueType, @Nullable Integer ruleId, @Nullable Integer characteristicId, @Nullable Double value, @Nullable String data, @Nullable Level dataLevel) {
     this.valueType = valueType;
     this.ruleId = ruleId;
     this.characteristicId = characteristicId;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureToMeasureDto.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureToMeasureDto.java
new file mode 100644 (file)
index 0000000..c758805
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.measure;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.server.computation.metric.Metric;
+
+public enum MeasureToMeasureDto {
+  INSTANCE;
+
+  @Nonnull
+  public MeasureDto toMeasureDto(Measure measure, Metric metric, long componentId, long snapshotId) {
+    MeasureDto out = new MeasureDto();
+    out.setMetricId(metric.getId());
+    out.setComponentId(componentId);
+    out.setSnapshotId(snapshotId);
+    out.setCharacteristicId(measure.getCharacteristicId());
+    out.setRuleId(measure.getRuleId());
+    if (measure.hasVariations()) {
+      setVariations(out, measure.getVariations());
+    }
+    if (measure.hasQualityGateStatus()) {
+      setAlert(out, measure.getQualityGateStatus());
+    }
+    // TODO persist personId if DevCockpit is reactivated
+//    out.setPersonId(measure.hasPersonId() ? measure.getPersonId() : null);
+    out.setDescription(measure.getDescription());
+    out.setValue(valueAsDouble(measure));
+    out.setData(data(measure));
+    return out;
+  }
+
+  private static void setVariations(MeasureDto measureDto, MeasureVariations variations) {
+    measureDto.setVariation(1, variations.hasVariation1() ? variations.getVariation1() : null);
+    measureDto.setVariation(2, variations.hasVariation2() ? variations.getVariation2() : null);
+    measureDto.setVariation(3, variations.hasVariation3() ? variations.getVariation3() : null);
+    measureDto.setVariation(4, variations.hasVariation4() ? variations.getVariation4() : null);
+    measureDto.setVariation(5, variations.hasVariation5() ? variations.getVariation5() : null);
+  }
+
+  private static void setAlert(MeasureDto measureDto, QualityGateStatus qualityGateStatus) {
+    measureDto.setAlertStatus(qualityGateStatus.getStatus().name());
+    measureDto.setAlertText(qualityGateStatus.getText());
+  }
+
+  private static String data(Measure in) {
+    switch (in.getValueType()) {
+      case NO_VALUE:
+      case BOOLEAN:
+      case INT:
+      case LONG:
+      case DOUBLE:
+        return in.getData();
+      case STRING:
+        return in.getStringValue();
+      case LEVEL:
+        return in.getLevelValue().name();
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * return the numerical value as a double. It's the type used in db.
+   * Returns null if no numerical value found
+   */
+  @CheckForNull
+  private static Double valueAsDouble(Measure measure) {
+    switch (measure.getValueType()) {
+      case BOOLEAN:
+        return measure.getBooleanValue() ? 1.0d : 0.0d;
+      case INT:
+        return (double) measure.getIntValue();
+      case LONG:
+        return (double) measure.getLongValue();
+      case DOUBLE:
+        return measure.getDoubleValue();
+      case NO_VALUE:
+      case STRING:
+      case LEVEL:
+      default:
+        return null;
+    }
+  }
+}
index 4f40bcb46f6c01eddf6d7fd4721d4cfcb0acfd81..aff9c9704625d11f8a4ee4bb1a4e263ac32a14a1 100644 (file)
 
 package org.sonar.server.computation.step;
 
-import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
 import java.util.List;
-import javax.annotation.CheckForNull;
+import java.util.Map;
 import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.measure.db.MeasureDto;
 import org.sonar.core.persistence.DbSession;
-import org.sonar.server.computation.batch.BatchReportReader;
 import org.sonar.server.computation.component.Component;
 import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
 import org.sonar.server.computation.component.TreeRootHolder;
-import org.sonar.server.computation.issue.RuleCache;
-import org.sonar.server.computation.measure.MetricCache;
+import org.sonar.server.computation.measure.Measure;
+import org.sonar.server.computation.measure.MeasureRepository;
+import org.sonar.server.computation.measure.MeasureToMeasureDto;
+import org.sonar.server.computation.metric.Metric;
+import org.sonar.server.computation.metric.MetricRepository;
 import org.sonar.server.db.DbClient;
 
-import static com.google.common.collect.Lists.newArrayList;
 import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;
 
 public class PersistMeasuresStep implements ComputationStep {
@@ -45,23 +44,21 @@ public class PersistMeasuresStep implements ComputationStep {
   /**
    * List of metrics that should not be received from the report, as they should only by fed by the compute engine
    */
-  private static final List<String> FORBIDDEN_METRIC_KEYS = newArrayList(CoreMetrics.DUPLICATIONS_DATA_KEY);
+  private static final List<String> FORBIDDEN_METRIC_KEYS = ImmutableList.of(CoreMetrics.DUPLICATIONS_DATA_KEY);
 
   private final DbClient dbClient;
-  private final RuleCache ruleCache;
-  private final MetricCache metricCache;
+  private final MetricRepository metricRepository;
   private final DbIdsRepository dbIdsRepository;
   private final TreeRootHolder treeRootHolder;
-  private final BatchReportReader reportReader;
+  private final MeasureRepository measureRepository;
 
-  public PersistMeasuresStep(DbClient dbClient, RuleCache ruleCache, MetricCache metricCache, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder,
-    BatchReportReader reportReader) {
+  public PersistMeasuresStep(DbClient dbClient, MetricRepository metricRepository, DbIdsRepository dbIdsRepository,
+    TreeRootHolder treeRootHolder, MeasureRepository measureRepository) {
     this.dbClient = dbClient;
-    this.ruleCache = ruleCache;
-    this.metricCache = metricCache;
+    this.metricRepository = metricRepository;
     this.dbIdsRepository = dbIdsRepository;
     this.treeRootHolder = treeRootHolder;
-    this.reportReader = reportReader;
+    this.measureRepository = measureRepository;
   }
 
   @Override
@@ -81,7 +78,6 @@ public class PersistMeasuresStep implements ComputationStep {
   }
 
   private class MeasureVisitor extends DepthTraversalTypeAwareVisitor {
-
     private final DbSession session;
 
     private MeasureVisitor(DbSession session) {
@@ -91,74 +87,25 @@ public class PersistMeasuresStep implements ComputationStep {
 
     @Override
     public void visitAny(Component component) {
-      int componentRef = component.getRef();
-      List<BatchReport.Measure> measures = reportReader.readComponentMeasures(componentRef);
-      persistMeasures(measures, dbIdsRepository.getComponentId(component), dbIdsRepository.getSnapshotId(component));
-    }
-
-    private void persistMeasures(List<BatchReport.Measure> batchReportMeasures, long componentId, long snapshotId) {
-      for (BatchReport.Measure measure : batchReportMeasures) {
-        if (FORBIDDEN_METRIC_KEYS.contains(measure.getMetricKey())) {
-          throw new IllegalStateException(String.format("Measures on metric '%s' cannot be send in the report", measure.getMetricKey()));
-        }
-        dbClient.measureDao().insert(session, toMeasureDto(measure, componentId, snapshotId));
-      }
-    }
-  }
+      Map<String, Measure> measures = measureRepository.getRawMeasures(component);
+      long componentId = dbIdsRepository.getComponentId(component);
+      long snapshotId = dbIdsRepository.getSnapshotId(component);
 
-  @VisibleForTesting
-  MeasureDto toMeasureDto(BatchReport.Measure in, long componentId, long snapshotId) {
-    if (!in.hasValueType()) {
-      throw new IllegalStateException(String.format("Measure %s does not have value type", in));
-    }
-    if (!in.hasMetricKey()) {
-      throw new IllegalStateException(String.format("Measure %s does not have metric key", in));
+      persistMeasures(measures, componentId, snapshotId);
     }
 
-    MeasureDto out = new MeasureDto();
-    out.setVariation(1, in.hasVariationValue1() ? in.getVariationValue1() : null);
-    out.setVariation(2, in.hasVariationValue2() ? in.getVariationValue2() : null);
-    out.setVariation(3, in.hasVariationValue3() ? in.getVariationValue3() : null);
-    out.setVariation(4, in.hasVariationValue4() ? in.getVariationValue4() : null);
-    out.setVariation(5, in.hasVariationValue5() ? in.getVariationValue5() : null);
-    out.setAlertStatus(in.hasAlertStatus() ? in.getAlertStatus() : null);
-    out.setAlertText(in.hasAlertText() ? in.getAlertText() : null);
-    out.setDescription(in.hasDescription() ? in.getDescription() : null);
-    out.setComponentId(componentId);
-    out.setSnapshotId(snapshotId);
-    out.setMetricId(metricCache.get(in.getMetricKey()).getId());
-    out.setRuleId(in.hasRuleKey() ? ruleCache.get(RuleKey.parse(in.getRuleKey())).getId() : null);
-    out.setCharacteristicId(in.hasCharactericId() ? in.getCharactericId() : null);
-    out.setPersonId(in.hasPersonId() ? in.getPersonId() : null);
-    out.setValue(valueAsDouble(in));
-    setData(in, out);
-    return out;
-  }
+    private void persistMeasures(Map<String, Measure> batchReportMeasures, long componentId, long snapshotId) {
+      for (Map.Entry<String, Measure> measure : batchReportMeasures.entrySet()) {
+        String metricKey = measure.getKey();
+        if (FORBIDDEN_METRIC_KEYS.contains(metricKey)) {
+          throw new IllegalStateException(String.format("Measures on metric '%s' cannot be send in the report", metricKey));
+        }
 
-  private static MeasureDto setData(BatchReport.Measure in, MeasureDto out) {
-    if (in.hasStringValue()) {
-      out.setData(in.getStringValue());
+        Metric metric = metricRepository.getByKey(metricKey);
+        MeasureDto measureDto = MeasureToMeasureDto.INSTANCE.toMeasureDto(measure.getValue(), metric, componentId, snapshotId);
+        dbClient.measureDao().insert(session, measureDto);
+      }
     }
-    return out;
   }
 
-  /**
-   * return the numerical value as a double. It's the type used in db.
-   * Returns null if no numerical value found
-   */
-  @CheckForNull
-  private static Double valueAsDouble(BatchReport.Measure measure) {
-    switch (measure.getValueType()) {
-      case BOOLEAN:
-        return measure.hasBooleanValue() ? (measure.getBooleanValue() ? 1.0d : 0.0d) : null;
-      case INT:
-        return measure.hasIntValue() ? (double) measure.getIntValue() : null;
-      case LONG:
-        return measure.hasLongValue() ? (double) measure.getLongValue() : null;
-      case DOUBLE:
-        return measure.hasDoubleValue() ? measure.getDoubleValue() : null;
-      default:
-        return null;
-    }
-  }
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureToMeasureDtoTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureToMeasureDtoTest.java
new file mode 100644 (file)
index 0000000..777cae0
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.measure;
+
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.sonar.core.measure.db.MeasureDto;
+import org.sonar.server.computation.metric.Metric;
+import org.sonar.server.computation.metric.MetricImpl;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(DataProviderRunner.class)
+public class MeasureToMeasureDtoTest {
+  private static final MetricImpl SOME_METRIC = new MetricImpl(42, "metric_key", "metric_name", Metric.MetricType.STRING);
+  private static final int SOME_COMPONENT_ID = 951;
+  private static final int SOME_SNAPSHOT_ID = 753;
+  private static final String SOME_DATA = "some_data";
+  private static final String SOME_STRING = "some_string";
+  private static final MeasureVariations SOME_VARIATIONS = new MeasureVariations(1d, 2d, 3d, 4d, 5d);
+  private static final MetricImpl SOME_BOOLEAN_METRIC = new MetricImpl(1, "1", "1", Metric.MetricType.BOOL);
+  private static final MetricImpl SOME_INT_METRIC = new MetricImpl(2, "2", "2", Metric.MetricType.INT);
+  private static final MetricImpl SOME_LONG_METRIC = new MetricImpl(3, "3", "3", Metric.MetricType.DISTRIB);
+  private static final MetricImpl SOME_DOUBLE_METRIC = new MetricImpl(4, "4", "4", Metric.MetricType.FLOAT);
+  private static final MetricImpl SOME_STRING_METRIC = new MetricImpl(5, "5", "5", Metric.MetricType.STRING);
+  private static final MetricImpl SOME_LEVEL_METRIC = new MetricImpl(6, "6", "6", Metric.MetricType.LEVEL);
+
+  private final MeasureToMeasureDto underTest = MeasureToMeasureDto.INSTANCE;
+
+  @Test(expected = NullPointerException.class)
+  public void toMeasureDto_throws_NPE_if_Measure_arg_is_null() {
+    underTest.toMeasureDto(null, SOME_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void toMeasureDto_throws_NPE_if_Metric_arg_is_null() {
+    underTest.toMeasureDto(MeasureImpl.builder().createNoValue(), null, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+  }
+
+  @DataProvider
+  public static Object[][] all_types_MeasureImpls() {
+    return new Object[][] {
+        { MeasureImpl.builder().create(true, SOME_DATA), SOME_BOOLEAN_METRIC},
+        { MeasureImpl.builder().create(1, SOME_DATA), SOME_INT_METRIC},
+        { MeasureImpl.builder().create((long) 1, SOME_DATA), SOME_LONG_METRIC},
+        { MeasureImpl.builder().create((double) 2, SOME_DATA), SOME_DOUBLE_METRIC},
+        { MeasureImpl.builder().create(SOME_STRING), SOME_STRING_METRIC},
+        { MeasureImpl.builder().create(Measure.Level.OK), SOME_LEVEL_METRIC}
+    };
+  }
+
+  @Test
+  @UseDataProvider("all_types_MeasureImpls")
+  public void toMeasureDto_returns_Dto_without_any_variation_if_Measure_has_no_MeasureVariations(MeasureImpl measure, Metric metric) {
+    MeasureDto measureDto = underTest.toMeasureDto(measure, metric, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(measureDto.getVariation(1)).isNull();
+    assertThat(measureDto.getVariation(2)).isNull();
+    assertThat(measureDto.getVariation(3)).isNull();
+    assertThat(measureDto.getVariation(4)).isNull();
+    assertThat(measureDto.getVariation(5)).isNull();
+  }
+
+  @Test
+  @UseDataProvider("all_types_MeasureImpls")
+  public void toMeasureDto_returns_Dto_with_variation_if_Measure_has_MeasureVariations(MeasureImpl measure, Metric metric) {
+    MeasureDto measureDto = underTest.toMeasureDto(measure.setVariations(SOME_VARIATIONS), metric, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(measureDto.getVariation(1)).isEqualTo(1d);
+    assertThat(measureDto.getVariation(2)).isEqualTo(2d);
+    assertThat(measureDto.getVariation(3)).isEqualTo(3d);
+    assertThat(measureDto.getVariation(4)).isEqualTo(4d);
+    assertThat(measureDto.getVariation(5)).isEqualTo(5d);
+  }
+
+  @Test
+  @UseDataProvider("all_types_MeasureImpls")
+  public void toMeasureDto_returns_Dto_without_alertStatus_nor_alertText_if_Measure_has_no_QualityGateStatus(MeasureImpl measure, Metric metric) {
+    MeasureDto measureDto = underTest.toMeasureDto(measure, metric, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(measureDto.getAlertStatus()).isNull();
+    assertThat(measureDto.getAlertText()).isNull();
+  }
+
+  @Test
+  @UseDataProvider("all_types_MeasureImpls")
+  public void toMeasureDto_returns_Dto_with_alertStatus_and_alertText_if_Measure_has_QualityGateStatus(MeasureImpl measure, Metric metric) {
+    String alertText = "some error";
+    MeasureDto measureDto = underTest.toMeasureDto(measure.setQualityGateStatus(new QualityGateStatus(Measure.Level.ERROR, alertText)), metric, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(measureDto.getAlertStatus()).isEqualTo(Measure.Level.ERROR.name());
+    assertThat(measureDto.getAlertText()).isEqualTo(alertText);
+  }
+
+  @Test
+  @UseDataProvider("all_types_MeasureImpls")
+  public void toMeasureDto_does_no_set_ruleId_if_not_set_in_Measure(MeasureImpl measure, Metric metric) {
+    assertThat(underTest.toMeasureDto(measure, metric, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID).getRuleId()).isNull();
+  }
+
+  @Test
+  public void toMeasureDto_sets_ruleId_if_set_in_Measure() {
+    MeasureImpl measure = MeasureImpl.builder().forRule(42).createNoValue();
+
+    assertThat(underTest.toMeasureDto(measure, SOME_BOOLEAN_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID).getRuleId()).isEqualTo(42);
+  }
+
+  @Test
+  @UseDataProvider("all_types_MeasureImpls")
+  public void toMeasureDto_does_no_set_characteristicId_if_not_set_in_Measure(MeasureImpl measure, Metric metric) {
+    assertThat(underTest.toMeasureDto(measure, metric, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID).getCharacteristicId()).isNull();
+  }
+
+  @Test
+  public void toMeasureDto_sets_characteristicId_if_set_in_Measure() {
+    MeasureImpl measure = MeasureImpl.builder().forCharacteristic(42).createNoValue();
+
+    assertThat(underTest.toMeasureDto(measure, SOME_BOOLEAN_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID).getCharacteristicId()).isEqualTo(42);
+  }
+
+  @Test
+  @UseDataProvider("all_types_MeasureImpls")
+  public void toMeasureDto_set_componentId_and_snapshotId_from_method_arguments(MeasureImpl measure, Metric metric) {
+    MeasureDto measureDto = underTest.toMeasureDto(measure, metric, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(measureDto.getComponentId()).isEqualTo(SOME_COMPONENT_ID);
+    assertThat(measureDto.getSnapshotId()).isEqualTo(SOME_SNAPSHOT_ID);
+  }
+
+  @Test
+  @UseDataProvider("all_types_MeasureImpls")
+  public void toMeasureDto_does_not_set_personId_until_DevCockpit_is_enabled_again(MeasureImpl measure, Metric metric) {
+    MeasureDto measureDto = underTest.toMeasureDto(measure, metric, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(measureDto.getPersonId()).isNull();
+  }
+
+  @Test
+  public void toMeasureDto_maps_value_to_1_or_0_and_data_from_data_field_for_BOOLEAN_metric() {
+    MeasureDto trueMeasureDto = underTest.toMeasureDto(MeasureImpl.builder().create(true, SOME_DATA), SOME_BOOLEAN_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(trueMeasureDto.getValue()).isEqualTo(1d);
+    assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA);
+
+    MeasureDto falseMeasureDto = underTest.toMeasureDto(MeasureImpl.builder().create(false, SOME_DATA), SOME_BOOLEAN_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(falseMeasureDto.getValue()).isEqualTo(0d);
+    assertThat(falseMeasureDto.getData()).isEqualTo(SOME_DATA);
+  }
+
+  @Test
+  public void toMeasureDto_maps_value_and_data_from_data_field_for_INT_metric() {
+    MeasureDto trueMeasureDto = underTest.toMeasureDto(MeasureImpl.builder().create(123, SOME_DATA), SOME_INT_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(trueMeasureDto.getValue()).isEqualTo(123);
+    assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA);
+  }
+
+  @Test
+  public void toMeasureDto_maps_value_and_data_from_data_field_for_LONG_metric() {
+    MeasureDto trueMeasureDto = underTest.toMeasureDto(MeasureImpl.builder().create((long) 456, SOME_DATA), SOME_LONG_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(trueMeasureDto.getValue()).isEqualTo(456);
+    assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA);
+  }
+
+  @Test
+  public void toMeasureDto_maps_value_and_data_from_data_field_for_DOUBLE_metric() {
+    MeasureDto trueMeasureDto = underTest.toMeasureDto(MeasureImpl.builder().create((double) 789, SOME_DATA), SOME_DOUBLE_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(trueMeasureDto.getValue()).isEqualTo(789);
+    assertThat(trueMeasureDto.getData()).isEqualTo(SOME_DATA);
+  }
+
+  @Test
+  public void toMeasureDto_maps_to_only_data_for_STRING_metric() {
+    MeasureDto trueMeasureDto = underTest.toMeasureDto(MeasureImpl.builder().create(SOME_STRING), SOME_STRING_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(trueMeasureDto.getValue()).isNull();
+    assertThat(trueMeasureDto.getData()).isEqualTo(SOME_STRING);
+  }
+
+  @Test
+  public void toMeasureDto_maps_name_of_Level_to_data_and_has_no_value_for_LEVEL_metric() {
+    MeasureDto trueMeasureDto = underTest.toMeasureDto(MeasureImpl.builder().create(Measure.Level.OK), SOME_LEVEL_METRIC, SOME_COMPONENT_ID, SOME_SNAPSHOT_ID);
+
+    assertThat(trueMeasureDto.getValue()).isNull();
+    assertThat(trueMeasureDto.getData()).isEqualTo(Measure.Level.OK.name());
+  }
+}
index 9252828d997be67b85adcb434df202ea3dc7659e..5f2921ae468006969eaccc7bd9603ae7c5db79dd 100644 (file)
@@ -30,13 +30,11 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.Severity;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.internal.Uuids;
 import org.sonar.batch.protocol.Constants.MeasureValueType;
 import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.component.ComponentDto;
-import org.sonar.core.measure.db.MeasureDto;
 import org.sonar.core.metric.db.MetricDto;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.DbTester;
@@ -49,7 +47,9 @@ import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.computation.issue.RuleCache;
 import org.sonar.server.computation.issue.RuleCacheLoader;
-import org.sonar.server.computation.measure.MetricCache;
+import org.sonar.server.computation.measure.MeasureRepository;
+import org.sonar.server.computation.measure.MeasureRepositoryImpl;
+import org.sonar.server.computation.metric.MetricRepositoryImpl;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.measure.persistence.MeasureDao;
 import org.sonar.server.metric.persistence.MetricDao;
@@ -63,25 +63,22 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class PersistMeasuresStepTest extends BaseStepTest {
 
   private static final String PROJECT_KEY = "PROJECT_KEY";
-  private static final String METRIC_KEY = "metric-key";
+  private static final String STRING_METRIC_KEY = "string-metric-key";
+  private static final String DOUBLE_METRIC_KEY = "double-metric-key";
   private static final RuleKey RULE_KEY = RuleKey.of("repo", "rule-key");
 
-  private static final long FILE_COMPONENT_ID = 3L;
-  private static final long FILE_SNAPSHOT_ID = 3L;
-
   @ClassRule
   public static DbTester dbTester = new DbTester();
-
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
-
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
   DbClient dbClient;
   DbSession session;
   DbIdsRepository dbIdsRepository = new DbIdsRepository();
-  MetricDto metric;
+  MetricDto stringMetric;
+  MetricDto doubleMetric;
   RuleDto rule;
 
   PersistMeasuresStep sut;
@@ -93,17 +90,21 @@ public class PersistMeasuresStepTest extends BaseStepTest {
     dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new MeasureDao(), new ComponentDao(), new MetricDao(), new RuleDao(System2.INSTANCE));
     session = dbClient.openSession(false);
 
-    metric = new MetricDto().setKey(METRIC_KEY).setEnabled(true).setOptimizedBestValue(false).setHidden(false).setDeleteHistoricalData(false);
-    dbClient.metricDao().insert(session, metric);
+    stringMetric = new MetricDto().setValueType("STRING").setShortName("String metric").setKey(STRING_METRIC_KEY).setEnabled(true);
+    dbClient.metricDao().insert(session, stringMetric);
+    doubleMetric = new MetricDto().setValueType("FLOAT").setShortName("Double metric").setKey(DOUBLE_METRIC_KEY).setEnabled(true);
+    dbClient.metricDao().insert(session, doubleMetric);
     rule = RuleTesting.newDto(RULE_KEY);
     dbClient.ruleDao().insert(session, rule);
     session.commit();
 
     RuleCache ruleCache = new RuleCache(new RuleCacheLoader(dbClient));
-    MetricCache metricCache = new MetricCache(dbClient);
+    MetricRepositoryImpl metricRepository = new MetricRepositoryImpl(dbClient);
+    metricRepository.start();
+    MeasureRepository measureRepository = new MeasureRepositoryImpl(dbClient, reportReader, metricRepository, ruleCache);
     session.commit();
 
-    sut = new PersistMeasuresStep(dbClient, ruleCache, metricCache, dbIdsRepository, treeRootHolder, reportReader);
+    sut = new PersistMeasuresStep(dbClient, metricRepository, dbIdsRepository, treeRootHolder, measureRepository);
   }
 
   @After
@@ -113,8 +114,8 @@ public class PersistMeasuresStepTest extends BaseStepTest {
 
   @Test
   public void insert_measures_from_report() throws Exception {
-    ComponentDto projectDto = addComponent(1, "project-key");
-    ComponentDto fileDto = addComponent(2, "file-key");
+    ComponentDto projectDto = addComponent("project-key");
+    ComponentDto fileDto = addComponent("file-key");
 
     Component file = DumbComponent.builder(Component.Type.FILE, 2).setUuid("CDEF").setKey("MODULE_KEY:file").build();
     Component project = DumbComponent.builder(Component.Type.PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY).addChildren(file).build();
@@ -137,8 +138,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
         .setAlertStatus("WARN")
         .setAlertText("Open issues > 0")
         .setDescription("measure-description")
-        .setMetricKey(METRIC_KEY)
-        .setRuleKey(RULE_KEY.toString())
+        .setMetricKey(STRING_METRIC_KEY)
         .setCharactericId(123456)
         .build()));
 
@@ -154,9 +154,8 @@ public class PersistMeasuresStepTest extends BaseStepTest {
         .setAlertStatus("ERROR")
         .setAlertText("Blocker issues variation > 0")
         .setDescription("measure-description")
-        .setMetricKey(METRIC_KEY)
+        .setMetricKey(DOUBLE_METRIC_KEY)
         .setRuleKey(RULE_KEY.toString())
-        .setCharactericId(123456)
         .build()));
 
     sut.execute();
@@ -165,234 +164,28 @@ public class PersistMeasuresStepTest extends BaseStepTest {
     assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(2);
 
     List<Map<String, Object>> dtos = dbTester.select(
-      "select snapshot_id as \"snapshotId\", project_id as \"componentId\", metric_id as \"metricId\", rule_id as \"ruleId\", value as \"value\", text_value as \"textValue\" " +
-        " from project_measures");
+      "select snapshot_id as \"snapshotId\", project_id as \"componentId\", metric_id as \"metricId\", rule_id as \"ruleId\", value as \"value\", text_value as \"textValue\", " +
+        "rule_priority as \"severity\" from project_measures");
 
     Map<String, Object> dto = dtos.get(0);
     assertThat(dto.get("snapshotId")).isEqualTo(3L);
     assertThat(dto.get("componentId")).isEqualTo(projectDto.getId());
-    assertThat(dto.get("metricId")).isEqualTo(metric.getId().longValue());
-    assertThat(dto.get("ruleId")).isEqualTo(rule.getId().longValue());
+    assertThat(dto.get("metricId")).isEqualTo(stringMetric.getId().longValue());
+    assertThat(dto.get("ruleId")).isNull();
     assertThat(dto.get("textValue")).isEqualTo("measure-data");
+    assertThat(dto.get("severity")).isNull();
 
     dto = dtos.get(1);
     assertThat(dto.get("snapshotId")).isEqualTo(4L);
     assertThat(dto.get("componentId")).isEqualTo(fileDto.getId());
-    assertThat(dto.get("metricId")).isEqualTo(metric.getId().longValue());
+    assertThat(dto.get("metricId")).isEqualTo(doubleMetric.getId().longValue());
     assertThat(dto.get("ruleId")).isEqualTo(rule.getId().longValue());
+    assertThat(dto.get("characteristicId")).isNull();
     assertThat(dto.get("value")).isEqualTo(123.123d);
+    assertThat(dto.get("severity")).isNull();
   }
 
-  @Test
-  public void map_full_batch_measure() {
-    BatchReport.Component component = defaultComponent().build();
-    ComponentDto componentDto = addComponent(component.getRef(), "component-key");
-
-    BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.DOUBLE)
-      .setDoubleValue(123.123d)
-      .setVariationValue1(1.1d)
-      .setVariationValue2(2.2d)
-      .setVariationValue3(3.3d)
-      .setVariationValue4(4.4d)
-      .setVariationValue5(5.5d)
-      .setAlertStatus("WARN")
-      .setAlertText("Open issues > 0")
-      .setDescription("measure-description")
-      .setMetricKey(METRIC_KEY)
-      .setRuleKey(RULE_KEY.toString())
-      .setCharactericId(123456)
-      .setPersonId(5432)
-      .build();
-
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, componentDto.getId(), FILE_SNAPSHOT_ID);
-
-    assertThat(measure).isEqualToComparingFieldByField(new MeasureDto()
-      .setComponentId(componentDto.getId())
-      .setSnapshotId(3L)
-      .setCharacteristicId(123456)
-      .setPersonId(5432)
-      .setValue(123.123d)
-      .setVariation(1, 1.1d)
-      .setVariation(2, 2.2d)
-      .setVariation(3, 3.3d)
-      .setVariation(4, 4.4d)
-      .setVariation(5, 5.5d)
-      .setAlertStatus("WARN")
-      .setAlertText("Open issues > 0")
-      .setDescription("measure-description")
-      .setMetricId(metric.getId())
-      .setRuleId(rule.getId()));
-  }
-
-  @Test
-  public void map_minimal_batch_measure() {
-    BatchReport.Component component = defaultComponent().build();
-    ComponentDto componentDto = addComponent(component.getRef(), "component-key");
-
-    BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.INT)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, componentDto.getId(), FILE_SNAPSHOT_ID);
-
-    assertThat(measure).isEqualToComparingFieldByField(new MeasureDto()
-      .setComponentId(componentDto.getId())
-      .setSnapshotId(FILE_SNAPSHOT_ID)
-      .setMetricId(metric.getId()));
-  }
-
-  @Test
-  public void map_boolean_batch_measure() {
-    BatchReport.Component component = defaultComponent().build();
-    addComponent(component.getRef(), "component-key");
-
-    BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.BOOLEAN)
-      .setBooleanValue(true)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isEqualTo(1.0);
-
-    batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.BOOLEAN)
-      .setBooleanValue(false)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isEqualTo(0.0);
-
-    batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.BOOLEAN)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isNull();
-  }
-
-  @Test
-  public void map_double_batch_measure() {
-    BatchReport.Component component = defaultComponent().build();
-    addComponent(component.getRef(), "component-key");
-
-    BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.DOUBLE)
-      .setDoubleValue(3.2)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isEqualTo(3.2);
-
-    batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.DOUBLE)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isNull();
-  }
-
-  @Test
-  public void map_int_batch_measure() {
-    BatchReport.Component component = defaultComponent().build();
-    addComponent(component.getRef(), "component-key");
-
-    BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.INT)
-      .setIntValue(3)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isEqualTo(3.0);
-
-    batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.INT)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isNull();
-  }
-
-  @Test
-  public void map_long_batch_measure() {
-    BatchReport.Component component = defaultComponent().build();
-    addComponent(component.getRef(), "component-key");
-
-    BatchReport.Measure batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.LONG)
-      .setLongValue(3L)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isEqualTo(3.0);
-
-    batchMeasure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.LONG)
-      .setMetricKey(METRIC_KEY)
-      .build();
-
-    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-
-    assertThat(measure.getValue()).isNull();
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void fail_when_no_metric_key() {
-    BatchReport.Measure measure = BatchReport.Measure.newBuilder()
-      .setValueType(MeasureValueType.STRING)
-      .setStringValue("string-value")
-      .build();
-    BatchReport.Component component = defaultComponent()
-      .build();
-    addComponent(component.getRef(), "component-key");
-    sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void fail_when_no_value() {
-    BatchReport.Measure measure = BatchReport.Measure.newBuilder()
-      .setMetricKey("repo:metric-key")
-      .build();
-    BatchReport.Component component = defaultComponent()
-      .build();
-    addComponent(component.getRef(), "component-key");
-    sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void fail_when_forbid_metric() {
-    BatchReport.Measure measure = BatchReport.Measure.newBuilder()
-      .setMetricKey("duplications_data")
-      .build();
-    BatchReport.Component component = defaultComponent()
-      .build();
-    addComponent(component.getRef(), "component-key");
-    sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
-  }
-
-  private BatchReport.Component.Builder defaultComponent() {
-    return BatchReport.Component.newBuilder()
-      .setRef(1);
-  }
-
-  private ComponentDto addComponent(int ref, String key) {
+  private ComponentDto addComponent(String key) {
     ComponentDto componentDto = new ComponentDto().setKey(key).setUuid(Uuids.create());
     dbClient.componentDao().insert(session, componentDto);
     session.commit();