]> source.dussan.org Git - sonarqube.git/commitdiff
Refactor registration of metrics at server startup
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Wed, 17 Jun 2015 22:03:18 +0000 (00:03 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 18 Jun 2015 09:52:18 +0000 (11:52 +0200)
Replace Hibernate by MyBatis

33 files changed:
server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java
server/sonar-server/src/main/java/org/sonar/server/metric/DefaultMetricFinder.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/metric/persistence/MetricDao.java
server/sonar-server/src/main/java/org/sonar/server/metric/ws/DeleteAction.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java
server/sonar-server/src/test/java/org/sonar/server/metric/DefaultMetricFinderTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/startup/RegisterMetricsTest.java
server/sonar-server/src/test/resources/org/sonar/server/metric/DefaultMetricFinderTest/shared.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics-result.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics-result.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldAddUserManagesMetric-result.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldAddUserManagesMetric.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldEnableOnlyLoadedMetrics.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldNotUpdateUserManagesMetricIfAlreadyExists-result.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldNotUpdateUserManagesMetricIfAlreadyExists.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldSaveIfNew-result.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldSaveIfNew.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldUpdateIfAlreadyExists-result.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldUpdateIfAlreadyExists.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics-result.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics.xml [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/metric/DefaultMetricFinder.java [deleted file]
sonar-core/src/main/java/org/sonar/core/metric/db/MetricMapper.java
sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateConditionDao.java
sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java [deleted file]
sonar-core/src/main/resources/org/sonar/core/metric/db/MetricMapper.xml
sonar-core/src/test/java/org/sonar/core/metric/DefaultMetricFinderTest.java [deleted file]
sonar-core/src/test/java/org/sonar/jpa/dao/MeasuresDaoTest.java [deleted file]
sonar-core/src/test/resources/org/sonar/core/metric/DefaultMetricFinderTest/shared.xml [deleted file]

index b4194d6617850e11f8ea3bbad0fa734053ca17ca..481ca005b96d374acf0c00102c1894c170cf402e 100644 (file)
@@ -36,6 +36,7 @@ import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.properties.PropertiesDao;
 import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
 import org.sonar.core.qualityprofile.db.QualityProfileDao;
 import org.sonar.core.resource.ResourceDao;
 import org.sonar.core.technicaldebt.db.CharacteristicDao;
@@ -107,6 +108,7 @@ public class DbClient {
   private final EventDao eventDao;
   private final PurgeDao purgeDao;
   private final CustomMeasureDao customMeasureDao;
+  private final QualityGateConditionDao gateConditionDao;
 
   public DbClient(Database db, MyBatis myBatis, DaoComponent... daoComponents) {
     this.db = db;
@@ -150,6 +152,7 @@ public class DbClient {
     componentLinkDao = getDao(map, ComponentLinkDao.class);
     eventDao = getDao(map, EventDao.class);
     purgeDao = getDao(map, PurgeDao.class);
+    gateConditionDao = getDao(map, QualityGateConditionDao.class);
   }
 
   public Database database() {
@@ -296,6 +299,10 @@ public class DbClient {
     return purgeDao;
   }
 
+  public QualityGateConditionDao gateConditionDao() {
+    return gateConditionDao;
+  }
+
   private <K> K getDao(Map<Class, DaoComponent> map, Class<K> clazz) {
     return (K) map.get(clazz);
   }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/metric/DefaultMetricFinder.java b/server/sonar-server/src/main/java/org/sonar/server/metric/DefaultMetricFinder.java
new file mode 100644 (file)
index 0000000..91433ef
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * 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.metric;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.core.metric.db.MetricDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.db.DbClient;
+
+import static com.google.common.collect.FluentIterable.from;
+
+public class DefaultMetricFinder implements MetricFinder {
+
+  private final DbClient dbClient;
+
+  public DefaultMetricFinder(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  @Override
+  public Metric findById(int id) {
+    DbSession session = dbClient.openSession(false);
+    try {
+      MetricDto dto = dbClient.metricDao().selectNullableById(session, id);
+      if (dto != null && dto.isEnabled()) {
+        return ToMetric.INSTANCE.apply(dto);
+      }
+      return null;
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  @Override
+  public Metric findByKey(String key) {
+    DbSession session = dbClient.openSession(false);
+    try {
+      MetricDto dto = dbClient.metricDao().selectNullableByKey(session, key);
+      if (dto != null && dto.isEnabled()) {
+        return ToMetric.INSTANCE.apply(dto);
+      }
+      return null;
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  @Override
+  public Collection<Metric> findAll(List<String> metricKeys) {
+    DbSession session = dbClient.openSession(false);
+    try {
+      List<MetricDto> dtos = dbClient.metricDao().selectNullableByKeys(session, metricKeys);
+      return from(dtos).filter(IsEnabled.INSTANCE).transform(ToMetric.INSTANCE).toList();
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  @Override
+  public Collection<Metric> findAll() {
+    DbSession session = dbClient.openSession(false);
+    try {
+      List<MetricDto> dtos = dbClient.metricDao().selectEnabled(session);
+      return from(dtos).transform(ToMetric.INSTANCE).toList();
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  private enum IsEnabled implements Predicate<MetricDto> {
+    INSTANCE;
+    @Override
+    public boolean apply(@Nonnull MetricDto dto) {
+      return dto.isEnabled();
+    }
+  }
+
+  private enum ToMetric implements Function<MetricDto, Metric> {
+    INSTANCE;
+
+    @Override
+    public Metric apply(@Nonnull MetricDto dto) {
+      Metric<Serializable> metric = new Metric<>();
+      metric.setId(dto.getId());
+      metric.setKey(dto.getKey());
+      metric.setDescription(dto.getDescription());
+      metric.setName(dto.getShortName());
+      metric.setBestValue(dto.getBestValue());
+      metric.setDomain(dto.getDomain());
+      metric.setEnabled(dto.isEnabled());
+      metric.setDirection(dto.getDirection());
+      metric.setHidden(dto.isHidden());
+      metric.setQualitative(dto.isQualitative());
+      metric.setType(Metric.ValueType.valueOf(dto.getValueType()));
+      metric.setOptimizedBestValue(dto.isOptimizedBestValue());
+      metric.setUserManaged(dto.isUserManaged());
+      metric.setWorstValue(dto.getWorstValue());
+      return metric;
+    }
+  }
+}
index 8765806f7351633058223c58483251c2fa314186..0be5857222966162a820168124dd424a0330cada 100644 (file)
@@ -112,16 +112,20 @@ public class MetricDao implements DaoComponent {
     return session.getMapper(MetricMapper.class);
   }
 
-  public void disable(final DbSession session, List<Integer> ids) {
+  public void disableByIds(final DbSession session, List<Integer> ids) {
     DaoUtils.executeLargeInputsWithoutOutput(ids, new Function<List<Integer>, Void>() {
       @Override
       public Void apply(@Nonnull List<Integer> input) {
-        mapper(session).disable(input);
+        mapper(session).disableByIds(input);
         return null;
       }
     });
   }
 
+  public void disableByKey(final DbSession session, String key) {
+    mapper(session).disableByKey(key);
+  }
+
   public void update(DbSession session, MetricDto metric) {
     mapper(session).update(metric);
   }
index d388560ba896aa700ca33b1a98524c79da15efc0..5ef5649bf4e6023716e028827369683b0df40e5a 100644 (file)
@@ -74,7 +74,7 @@ public class DeleteAction implements MetricsWsAction {
     DbSession dbSession = dbClient.openSession(false);
     try {
       List<Integer> ids = loadIds(dbSession, request);
-      dbClient.metricDao().disable(dbSession, ids);
+      dbClient.metricDao().disableByIds(dbSession, ids);
       dbClient.customMeasureDao().deleteByMetricIds(dbSession, ids);
       dbSession.commit();
     } finally {
index 42ef539aa6c380e8a29200b61d24bec601cbe5f7..85f0d0495e9fb04552bae48ccc9d3220a103f8d4 100644 (file)
@@ -37,7 +37,6 @@ import org.sonar.core.issue.IssueFilterSerializer;
 import org.sonar.core.issue.IssueUpdater;
 import org.sonar.core.issue.workflow.FunctionExecutor;
 import org.sonar.core.issue.workflow.IssueWorkflow;
-import org.sonar.core.metric.DefaultMetricFinder;
 import org.sonar.core.permission.PermissionFacade;
 import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao;
 import org.sonar.core.qualitygate.db.QualityGateConditionDao;
@@ -46,7 +45,6 @@ import org.sonar.core.resource.DefaultResourceTypes;
 import org.sonar.core.timemachine.Periods;
 import org.sonar.core.user.DefaultUserFinder;
 import org.sonar.core.user.DeprecatedUserFinder;
-import org.sonar.jpa.dao.MeasuresDao;
 import org.sonar.server.activity.ActivityService;
 import org.sonar.server.activity.RubyQProfileActivityService;
 import org.sonar.server.activity.index.ActivityIndex;
@@ -170,6 +168,7 @@ import org.sonar.server.measure.template.ProjectFilter;
 import org.sonar.server.measure.ws.ManualMeasuresWs;
 import org.sonar.server.measure.ws.TimeMachineWs;
 import org.sonar.server.metric.CoreCustomMetrics;
+import org.sonar.server.metric.DefaultMetricFinder;
 import org.sonar.server.metric.ws.MetricsWsModule;
 import org.sonar.server.notification.DefaultNotificationManager;
 import org.sonar.server.notification.NotificationCenter;
@@ -486,8 +485,6 @@ public class PlatformLevel4 extends PlatformLevel {
       ActivityMapping.class,
 
       // measure
-      MeasuresDao.class,
-
       MeasureFilterFactory.class,
       MeasureFilterExecutor.class,
       MeasureFilterEngine.class,
index 23636e511333b93f2fbf7f4583397f250f9f704e..1000c1078e6ea45785c58ff6d34049bab911b024 100644 (file)
 package org.sonar.server.startup;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
+import com.google.common.base.Function;
 import com.google.common.collect.Maps;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nonnull;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.measures.Metrics;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.api.utils.log.Profiler;
-import org.sonar.core.qualitygate.db.QualityGateConditionDao;
-import org.sonar.jpa.dao.MeasuresDao;
-
-import java.util.List;
-import java.util.Map;
+import org.sonar.core.metric.db.MetricDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.db.DbClient;
 
+import static com.google.common.collect.FluentIterable.from;
+import static com.google.common.collect.Iterables.concat;
 import static com.google.common.collect.Lists.newArrayList;
 
 public class RegisterMetrics {
 
   private static final Logger LOG = Loggers.get(RegisterMetrics.class);
 
-  private final MeasuresDao measuresDao;
+  private final DbClient dbClient;
   private final Metrics[] metricsRepositories;
-  private final QualityGateConditionDao conditionDao;
 
-  public RegisterMetrics(MeasuresDao measuresDao, QualityGateConditionDao conditionDao, Metrics[] metricsRepositories) {
-    this.measuresDao = measuresDao;
+  public RegisterMetrics(DbClient dbClient, Metrics[] metricsRepositories) {
+    this.dbClient = dbClient;
     this.metricsRepositories = metricsRepositories;
-    this.conditionDao = conditionDao;
   }
 
   /**
    * Used when no plugin is defining Metrics
    */
-  public RegisterMetrics(MeasuresDao measuresDao, QualityGateConditionDao conditionDao) {
-    this(measuresDao, conditionDao, new Metrics[]{});
+  public RegisterMetrics(DbClient dbClient) {
+    this(dbClient, new Metrics[] {});
   }
 
   public void start() {
-    Profiler profiler = Profiler.create(LOG).startInfo("Register metrics");
-    measuresDao.disableAutomaticMetrics();
+    register(concat(CoreMetrics.getMetrics(), getPluginMetrics()));
+  }
 
-    List<Metric> metricsToRegister = newArrayList();
-    metricsToRegister.addAll(CoreMetrics.getMetrics());
-    metricsToRegister.addAll(getMetricsRepositories());
-    register(metricsToRegister);
-    cleanAlerts();
+  void register(Iterable<Metric> metrics) {
+    Profiler profiler = Profiler.create(LOG).startInfo("Register metrics");
+    DbSession session = dbClient.openSession(false);
+    try {
+      save(session, metrics);
+      sanitizeQualityGates(session);
+      session.commit();
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
     profiler.stopDebug();
   }
 
+  private void sanitizeQualityGates(DbSession session) {
+    dbClient.gateConditionDao().deleteConditionsWithInvalidMetrics(session);
+  }
+
+  private void save(DbSession session, Iterable<Metric> metrics) {
+    Map<String, MetricDto> basesByKey = new HashMap<>();
+    for (MetricDto base : from(dbClient.metricDao().selectEnabled(session)).toList()) {
+      basesByKey.put(base.getKey(), base);
+    }
+
+    for (Metric metric : metrics) {
+      MetricDto dto = MetricToDto.INSTANCE.apply(metric);
+      MetricDto base = basesByKey.get(metric.getKey());
+      if (base == null) {
+        // new metric, never installed
+        dbClient.metricDao().insert(session, dto);
+      } else if (!base.isUserManaged()) {
+        // existing metric, update changes. Existing custom metrics are kept without applying changes.
+        dto.setId(base.getId());
+        dbClient.metricDao().update(session, dto);
+      }
+      basesByKey.remove(metric.getKey());
+    }
+
+    for (MetricDto nonUpdatedBase : basesByKey.values()) {
+      if (!nonUpdatedBase.isUserManaged()) {
+        LOG.info("Disable metric {} [{}]", nonUpdatedBase.getShortName(), nonUpdatedBase.getKey());
+        dbClient.metricDao().disableByKey(session, nonUpdatedBase.getKey());
+      }
+    }
+  }
+
   @VisibleForTesting
-  List<Metric> getMetricsRepositories() {
+  List<Metric> getPluginMetrics() {
     List<Metric> metricsToRegister = newArrayList();
     Map<String, Metrics> metricsByRepository = Maps.newHashMap();
-
     for (Metrics metrics : metricsRepositories) {
       checkMetrics(metricsByRepository, metrics);
-      metricsToRegister.addAll(removeExistingUserManagedMetrics(metrics.getMetrics()));
+      metricsToRegister.addAll(metrics.getMetrics());
     }
 
     return metricsToRegister;
   }
 
-  private List<Metric> removeExistingUserManagedMetrics(List<Metric> metrics) {
-    return newArrayList(Iterables.filter(metrics, new Predicate<Metric>() {
-      @Override
-      public boolean apply(Metric metric) {
-        // It should be better to use the template mechanism (as it's done in #RegisterDashboards to register provided user manager metrics
-        return !metric.getUserManaged() || measuresDao.getMetric(metric.getKey()) == null;
-      }
-    }));
-  }
-
   private void checkMetrics(Map<String, Metrics> metricsByRepository, Metrics metrics) {
     for (Metric metric : metrics.getMetrics()) {
       String metricKey = metric.getKey();
       if (CoreMetrics.getMetrics().contains(metric)) {
-        throw new IllegalStateException("The following metric is already defined in sonar: " + metricKey);
+        throw new IllegalStateException(String.format("Metric [%s] is already defined by SonarQube", metricKey));
       }
       Metrics anotherRepository = metricsByRepository.get(metricKey);
       if (anotherRepository != null) {
-        throw new IllegalStateException("The metric '" + metricKey + "' is already defined in the extension: " + anotherRepository);
+        throw new IllegalStateException(String.format("Metric [%s] is already defined by the repository [%s]", metricKey, anotherRepository));
       }
       metricsByRepository.put(metricKey, metrics);
     }
   }
 
-  protected void cleanAlerts() {
-    LOG.info("Cleaning quality gate conditions");
-    conditionDao.deleteConditionsWithInvalidMetrics();
-  }
-
-  protected void register(List<Metric> metrics) {
-    measuresDao.registerMetrics(metrics);
+  private enum MetricToDto implements Function<Metric, MetricDto> {
+    INSTANCE;
+    @Override
+    @Nonnull
+    public MetricDto apply(@Nonnull Metric metric) {
+      MetricDto dto = new MetricDto();
+      dto.setId(metric.getId());
+      dto.setKey(metric.getKey());
+      dto.setDescription(metric.getDescription());
+      dto.setShortName(metric.getName());
+      dto.setBestValue(metric.getBestValue());
+      dto.setDomain(metric.getDomain());
+      dto.setEnabled(metric.getEnabled());
+      dto.setDirection(metric.getDirection());
+      dto.setHidden(metric.isHidden());
+      dto.setQualitative(metric.getQualitative());
+      dto.setValueType(metric.getType().name());
+      dto.setOptimizedBestValue(metric.isOptimizedBestValue());
+      dto.setUserManaged(metric.getUserManaged());
+      dto.setWorstValue(metric.getWorstValue());
+      return dto;
+    }
   }
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/metric/DefaultMetricFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/metric/DefaultMetricFinderTest.java
new file mode 100644 (file)
index 0000000..3d257d4
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.metric;
+
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.metric.persistence.MetricDao;
+import org.sonar.test.DbTests;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertThat;
+
+@Category(DbTests.class)
+public class DefaultMetricFinderTest {
+
+  @ClassRule
+  public static DbTester dbTester = new DbTester();
+
+  DefaultMetricFinder finder;
+
+  @Before
+  public void setUp() {
+    dbTester.prepareDbUnit(DefaultMetricFinderTest.class, "shared.xml");
+    finder = new DefaultMetricFinder(new DbClient(dbTester.database(), dbTester.myBatis(), new MetricDao()));
+  }
+
+  @Test
+  public void shouldFindAll() {
+    assertThat(finder.findAll().size(), is(2));
+  }
+
+  @Test
+  public void shouldFindByKeys() {
+    assertThat(finder.findAll(Arrays.asList("ncloc", "foo", "coverage")).size(), is(2));
+  }
+
+  @Test
+  public void shouldFindById() {
+    assertThat(finder.findById(1).getKey(), is("ncloc"));
+    assertThat(finder.findById(3), nullValue());
+  }
+
+  @Test
+  public void shouldFindByKey() {
+    assertThat(finder.findByKey("ncloc").getKey(), is("ncloc"));
+    assertThat(finder.findByKey("disabled"), nullValue());
+  }
+}
index af536fab964d80f595de612b6419c9a305f8eb77..c37600379b96fe405607c298682a72b3cfd1ebe6 100644 (file)
  */
 package org.sonar.server.startup;
 
-import com.google.common.collect.Lists;
+import java.util.Collections;
+import java.util.List;
+import org.junit.ClassRule;
 import org.junit.Test;
+import org.junit.experimental.categories.Category;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.measures.Metrics;
+import org.sonar.core.persistence.DbTester;
 import org.sonar.core.qualitygate.db.QualityGateConditionDao;
-import org.sonar.jpa.dao.MeasuresDao;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.util.Arrays;
-import java.util.List;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.metric.persistence.MetricDao;
+import org.sonar.test.DbTests;
 
+import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
-public class RegisterMetricsTest extends AbstractDbUnitTestCase {
+@Category(DbTests.class)
+public class RegisterMetricsTest {
+
+  @ClassRule
+  public static DbTester dbTester = new DbTester();
 
+  /**
+   * Insert new metrics, including custom metrics
+   */
   @Test
-  public void shouldSaveIfNew() {
-    setupData("shouldSaveIfNew");
+  public void insert_new_metrics() {
+    dbTester.prepareDbUnit(getClass(), "insert_new_metrics.xml");
 
-    Metric metric1 = new Metric.Builder("new1", "short1", Metric.ValueType.FLOAT)
+    Metric m1 = new Metric.Builder("m1", "One", Metric.ValueType.FLOAT)
       .setDescription("desc1")
       .setDirection(1)
       .setQualitative(true)
       .setDomain("domain1")
       .setUserManaged(false)
       .create();
-    Metric metric2 = new Metric.Builder("new2", "short2", Metric.ValueType.FLOAT)
-      .setDescription("desc2")
-      .setDirection(1)
-      .setQualitative(true)
-      .setDomain("domain2")
-      .setUserManaged(false)
+    Metric custom = new Metric.Builder("custom", "Custom", Metric.ValueType.FLOAT)
+      .setDescription("This is a custom metric")
+      .setUserManaged(true)
       .create();
 
-    RegisterMetrics synchronizer = new RegisterMetrics(new MeasuresDao(getSession()), mock(QualityGateConditionDao.class), new Metrics[0]);
-    synchronizer.register(Arrays.asList(metric1, metric2));
-    checkTables("shouldSaveIfNew", "metrics");
+    RegisterMetrics register = new RegisterMetrics(dbClient());
+    register.register(asList(m1, custom));
+    dbTester.assertDbUnit(getClass(), "insert_new_metrics-result.xml", "metrics");
   }
 
+  /**
+   * Update existing metrics, except if custom metric
+   */
   @Test
-  public void shouldUpdateIfAlreadyExists() {
-    setupData("shouldUpdateIfAlreadyExists");
+  public void update_non_custom_metrics() {
+    dbTester.prepareDbUnit(getClass(), "update_non_custom_metrics.xml");
 
-    RegisterMetrics synchronizer = new RegisterMetrics(new MeasuresDao(getSession()), mock(QualityGateConditionDao.class), new Metrics[0]);
-    synchronizer.register(Lists.<Metric>newArrayList(new Metric.Builder("key", "new short name", Metric.ValueType.FLOAT)
+    RegisterMetrics register = new RegisterMetrics(dbClient());
+    Metric m1 = new Metric.Builder("m1", "New name", Metric.ValueType.FLOAT)
       .setDescription("new description")
       .setDirection(-1)
       .setQualitative(true)
       .setDomain("new domain")
       .setUserManaged(false)
-      .create()));
+      .setHidden(true)
+      .create();
+    Metric custom = new Metric.Builder("custom", "New custom", Metric.ValueType.FLOAT)
+      .setDescription("New description of custom metric")
+      .setUserManaged(true)
+      .create();
+    register.register(asList(m1, custom));
 
-    checkTables("shouldUpdateIfAlreadyExists", "metrics");
+    dbTester.assertDbUnit(getClass(), "update_non_custom_metrics-result.xml", "metrics");
   }
 
   @Test
-  public void shouldAddUserManagesMetric() {
-    Metrics metrics = mock(Metrics.class);
-    when(metrics.getMetrics()).thenReturn(Lists.<Metric>newArrayList(new Metric.Builder("key", "new short name", Metric.ValueType.FLOAT)
-      .setDescription("new description")
-      .setDirection(-1)
-      .setQualitative(true)
-      .setDomain("new domain")
-      .setUserManaged(true)
-      .create()));
+  public void disable_undefined_metrics() {
+    dbTester.prepareDbUnit(getClass(), "disable_undefined_metrics.xml");
 
-    MeasuresDao measuresDao = new MeasuresDao(getSession());
-    RegisterMetrics loader = new RegisterMetrics(measuresDao, mock(QualityGateConditionDao.class), new Metrics[] {metrics});
-    List<Metric> result = loader.getMetricsRepositories();
+    RegisterMetrics register = new RegisterMetrics(dbClient());
+    register.register(Collections.<Metric>emptyList());
 
-    assertThat(result).hasSize(1);
+    dbTester.assertDbUnit(getClass(), "disable_undefined_metrics-result.xml", "metrics");
   }
 
   @Test
-  public void shouldNotUpdateUserManagesMetricIfAlreadyExists() {
-    setupData("shouldNotUpdateUserManagesMetricIfAlreadyExists");
+  public void insert_core_metrics() {
+    dbTester.truncateTables();
 
-    Metrics metrics = mock(Metrics.class);
-    when(metrics.getMetrics()).thenReturn(Lists.<Metric>newArrayList(new Metric.Builder("key", "new short name", Metric.ValueType.FLOAT)
-      .setDescription("new description")
-      .setDirection(-1)
-      .setQualitative(true)
-      .setDomain("new domain")
-      .setUserManaged(true)
-      .create()));
+    RegisterMetrics register = new RegisterMetrics(dbClient());
+    register.start();
 
-    MeasuresDao measuresDao = new MeasuresDao(getSession());
-    RegisterMetrics loader = new RegisterMetrics(measuresDao, mock(QualityGateConditionDao.class), new Metrics[] {metrics});
-    List<Metric> result = loader.getMetricsRepositories();
+    assertThat(dbTester.countRowsOfTable("metrics")).isEqualTo(CoreMetrics.getMetrics().size());
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void fail_if_duplicated_plugin_metrics() throws Exception {
+    Metrics plugin1 = new TestMetrics(new Metric.Builder("m1", "In first plugin", Metric.ValueType.FLOAT).create());
+    Metrics plugin2 = new TestMetrics(new Metric.Builder("m1", "In second plugin", Metric.ValueType.FLOAT).create());
 
-    assertThat(result).isEmpty();
+    new RegisterMetrics(dbClient(), new Metrics[]{plugin1, plugin2}).start();
   }
 
-  @Test
-  public void shouldEnableOnlyLoadedMetrics() {
-    setupData("shouldEnableOnlyLoadedMetrics");
+  @Test(expected = IllegalStateException.class)
+  public void fail_if_plugin_duplicates_core_metric() throws Exception {
+    Metrics plugin = new TestMetrics(new Metric.Builder("ncloc", "In plugin", Metric.ValueType.FLOAT).create());
 
-    MeasuresDao measuresDao = new MeasuresDao(getSession());
-    RegisterMetrics loader = new RegisterMetrics(measuresDao, mock(QualityGateConditionDao.class), new Metrics[0]);
-    loader.start();
+    new RegisterMetrics(dbClient(), new Metrics[]{plugin}).start();
+  }
 
-    assertThat(measuresDao.getMetric("deprecated").getEnabled()).isFalse();
-    assertThat(measuresDao.getMetric(CoreMetrics.COMPLEXITY_KEY).getEnabled()).isTrue();
+  private DbClient dbClient() {
+    return new DbClient(dbTester.database(), dbTester.myBatis(), new MetricDao(), new QualityGateConditionDao(dbTester.myBatis()));
   }
 
-  @Test
-  public void clean_quality_gate_conditions() {
-    QualityGateConditionDao conditionDao = mock(QualityGateConditionDao.class);
-    RegisterMetrics loader = new RegisterMetrics(new MeasuresDao(getSession()), conditionDao, new Metrics[0]);
-    loader.cleanAlerts();
-    verify(conditionDao).deleteConditionsWithInvalidMetrics();
+  private class TestMetrics implements Metrics {
+    private final List<Metric> metrics;
+
+    public TestMetrics(Metric... metrics) {
+      this.metrics = asList(metrics);
+    }
+
+    @Override
+    public List<Metric> getMetrics() {
+      return metrics;
+    }
   }
 }
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/metric/DefaultMetricFinderTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/metric/DefaultMetricFinderTest/shared.xml
new file mode 100644 (file)
index 0000000..dd645d6
--- /dev/null
@@ -0,0 +1,12 @@
+<dataset>
+
+  <metrics delete_historical_data="[null]" id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0"
+           hidden="false"/>
+
+  <metrics delete_historical_data="[null]" id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="true" worst_value="0" optimized_best_value="true" best_value="100" direction="1" hidden="false"/>
+
+  <metrics delete_historical_data="[null]" id="3" name="disabled" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+           enabled="false" worst_value="0" optimized_best_value="true" best_value="100" direction="1" hidden="false"/>
+</dataset>
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics-result.xml
new file mode 100644 (file)
index 0000000..dbedde9
--- /dev/null
@@ -0,0 +1,8 @@
+<dataset>
+
+  <!-- disabled -->
+  <metrics delete_historical_data="[false]" id="1" name="m1" val_type="FLOAT" description="desc1" domain="domain1"
+           short_name="One" qualitative="[true]" user_managed="[false]" enabled="[false]" worst_value="[null]"
+           optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/disable_undefined_metrics.xml
new file mode 100644 (file)
index 0000000..b48ad61
--- /dev/null
@@ -0,0 +1,9 @@
+<dataset>
+
+  <metrics delete_historical_data="[false]" id="1" name="m1" val_type="FLOAT" description="desc1" domain="domain1"
+           short_name="One" qualitative="[true]" user_managed="[false]"
+           enabled="[true]"
+           worst_value="[null]"
+           optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics-result.xml
new file mode 100644 (file)
index 0000000..1bb5088
--- /dev/null
@@ -0,0 +1,11 @@
+<dataset>
+
+  <metrics delete_historical_data="[false]" id="1" name="m1" val_type="FLOAT" description="desc1" domain="domain1"
+           short_name="One" qualitative="[true]" user_managed="[false]" enabled="[true]" worst_value="[null]"
+           optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+  <metrics delete_historical_data="[false]" id="2" name="custom" val_type="FLOAT" description="This is a custom metric"
+           domain="[null]"
+           short_name="Custom" qualitative="[false]" user_managed="[true]" enabled="[true]" worst_value="[null]"
+           optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/insert_new_metrics.xml
new file mode 100644 (file)
index 0000000..a1c54e4
--- /dev/null
@@ -0,0 +1,4 @@
+<dataset>
+
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldAddUserManagesMetric-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldAddUserManagesMetric-result.xml
deleted file mode 100644 (file)
index e007031..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="false" id="1" name="key" val_type="FLOAT" description="new description" domain="new domain"
-           short_name="new short name"  qualitative="true" user_managed="true" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="-1" hidden="false"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldAddUserManagesMetric.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldAddUserManagesMetric.xml
deleted file mode 100644 (file)
index f1e73ac..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<dataset>
-
-  <metrics/>
-
-</dataset>
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldEnableOnlyLoadedMetrics.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldEnableOnlyLoadedMetrics.xml
deleted file mode 100644 (file)
index 93aa067..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="false" id="1" name="deprecated" val_type="INT" description="description"  domain="domain"
-           short_name="short name"  qualitative="false" user_managed="false" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="1" hidden="false"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldNotUpdateUserManagesMetricIfAlreadyExists-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldNotUpdateUserManagesMetricIfAlreadyExists-result.xml
deleted file mode 100644 (file)
index 968b9e9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="false" id="1" name="key" val_type="INT" description="old description"  domain="old domain"
-           short_name="old short name"  qualitative="false" user_managed="true" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="1" hidden="false"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldNotUpdateUserManagesMetricIfAlreadyExists.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldNotUpdateUserManagesMetricIfAlreadyExists.xml
deleted file mode 100644 (file)
index ed24c0d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="false" id="1" name="key" val_type="INT" description="old description"  domain="old domain"
-           short_name="old short name"  qualitative="false" user_managed="true" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="1" hidden="false"/>
-
-  
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldSaveIfNew-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldSaveIfNew-result.xml
deleted file mode 100644 (file)
index 182a4a8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="false" id="1" name="key1" val_type="INT" description="description"  domain="domain"
-           short_name="short name"  qualitative="false" user_managed="false" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="1" hidden="false"/>
-
-  <!--New metrics -->
-  <metrics delete_historical_data="false" id="2" name="new1" val_type="FLOAT" description="desc1"  domain="domain1"
-           short_name="short1"  qualitative="true"  user_managed="false" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="1" hidden="false"/>
-  <metrics delete_historical_data="false" id="3" name="new2" val_type="FLOAT" description="desc2"  domain="domain2"
-           short_name="short2"   qualitative="true"  user_managed="false" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="1" hidden="false"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldSaveIfNew.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldSaveIfNew.xml
deleted file mode 100644 (file)
index 3f7c902..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="false" id="1" name="key1" val_type="INT" description="description"  domain="domain"
-           short_name="short name"  qualitative="false" user_managed="false" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="1" hidden="false"/>
-  
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldUpdateIfAlreadyExists-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldUpdateIfAlreadyExists-result.xml
deleted file mode 100644 (file)
index ed9a86d..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="false" id="1" name="key" val_type="FLOAT" description="new description" domain="new domain"
-           short_name="new short name"  qualitative="true" user_managed="false" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="-1" hidden="false"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldUpdateIfAlreadyExists.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/shouldUpdateIfAlreadyExists.xml
deleted file mode 100644 (file)
index fb9242e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="false" id="1" name="key" val_type="INT" description="old description"  domain="old domain"
-           short_name="old short name"  qualitative="false" user_managed="false" enabled="true"  worst_value="[null]" optimized_best_value="false" best_value="[null]" direction="1" hidden="false"/>
-
-  
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics-result.xml
new file mode 100644 (file)
index 0000000..886e1d2
--- /dev/null
@@ -0,0 +1,15 @@
+<dataset>
+
+  <!-- changed -->
+  <metrics delete_historical_data="[false]" id="1" name="m1" val_type="FLOAT" description="new description"
+           domain="new domain"
+           short_name="New name" qualitative="[true]" user_managed="[false]" enabled="[true]" worst_value="[null]"
+           optimized_best_value="[false]" best_value="[null]" direction="-1" hidden="[true]"/>
+
+  <!-- custom metric is unchanged -->
+  <metrics delete_historical_data="[false]" id="2" name="custom" val_type="FLOAT" description="This is a custom metric"
+           domain="[null]"
+           short_name="Custom" qualitative="[false]" user_managed="[true]" enabled="[true]" worst_value="[null]"
+           optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics.xml b/server/sonar-server/src/test/resources/org/sonar/server/startup/RegisterMetricsTest/update_non_custom_metrics.xml
new file mode 100644 (file)
index 0000000..483a9cb
--- /dev/null
@@ -0,0 +1,12 @@
+<dataset>
+
+  <metrics delete_historical_data="[false]" id="1" name="m1" val_type="INT" description="old description"
+           domain="old domain"
+           short_name="old short name" qualitative="[false]" user_managed="[false]" enabled="[true]" worst_value="[null]"
+           optimized_best_value="[false]" best_value="[null]" direction="1" hidden="[false]"/>
+
+  <metrics delete_historical_data="[false]" id="2" name="custom" val_type="FLOAT" description="This is a custom metric"
+           domain="[null]"
+           short_name="Custom" qualitative="[false]" user_managed="[true]" enabled="[true]" worst_value="[null]"
+           optimized_best_value="[false]" best_value="[null]" direction="0" hidden="[false]"/>
+</dataset>
diff --git a/sonar-core/src/main/java/org/sonar/core/metric/DefaultMetricFinder.java b/sonar-core/src/main/java/org/sonar/core/metric/DefaultMetricFinder.java
deleted file mode 100644 (file)
index 087a6be..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.core.metric;
-
-import com.google.common.collect.Lists;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.MetricFinder;
-import org.sonar.jpa.session.DatabaseSessionFactory;
-
-import java.util.Collection;
-import java.util.List;
-
-public class DefaultMetricFinder implements MetricFinder {
-
-  private static final String ENABLED = "enabled";
-  private DatabaseSessionFactory sessionFactory;
-
-  public DefaultMetricFinder(DatabaseSessionFactory sessionFactory) {
-    this.sessionFactory = sessionFactory;
-  }
-
-  @Override
-  public Metric findById(int id) {
-    return sessionFactory.getSession().getSingleResult(Metric.class, "id", id, ENABLED, true);
-  }
-
-  @Override
-  public Metric findByKey(String key) {
-    return sessionFactory.getSession().getSingleResult(Metric.class, "key", key, ENABLED, true);
-  }
-
-  @Override
-  public Collection<Metric> findAll(List<String> metricKeys) {
-    List<Metric> result = Lists.newLinkedList();
-    for (String metricKey : metricKeys) {
-      Metric metric = findByKey(metricKey);
-      if (metric != null) {
-        result.add(metric);
-      }
-    }
-    return result;
-  }
-
-  @Override
-  public Collection<Metric> findAll() {
-    return doFindAll();
-  }
-
-  protected Collection<Metric> doFindAll() {
-    return sessionFactory.getSession().getResults(Metric.class, ENABLED, true);
-  }
-
-}
index dd216603d05ad8bb38c1933a1a3afb79a4af818a..280fb82f4e01c14126668bba2e7dd8b5a09d8c7e 100644 (file)
@@ -40,7 +40,9 @@ public interface MetricMapper {
 
   List<MetricDto> selectByKeys(@Param("keys") List<String> keys);
 
-  void disable(@Param("ids") List<Integer> ids);
+  void disableByIds(@Param("ids") List<Integer> ids);
+
+  void disableByKey(@Param("key") String key);
 
   int countEnabled(@Param("isCustom") @Nullable Boolean isCustom);
 
index 03372a7071726e07de26866b647de014efe675ac..17764552b20c4565181bcf9be04d84b701ed0076 100644 (file)
@@ -39,6 +39,7 @@ import org.sonar.core.permission.PermissionDao;
 import org.sonar.core.permission.PermissionTemplateDao;
 import org.sonar.core.properties.PropertiesDao;
 import org.sonar.core.purge.PurgeDao;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
 import org.sonar.core.qualityprofile.db.ActiveRuleDao;
 import org.sonar.core.qualityprofile.db.QualityProfileDao;
 import org.sonar.core.resource.ResourceDao;
@@ -84,6 +85,7 @@ public final class DaoUtils {
       PermissionDao.class,
       PermissionTemplateDao.class,
       PropertiesDao.class,
+      QualityGateConditionDao.class,
       QualityProfileDao.class,
       PurgeDao.class,
       CharacteristicDao.class,
index a634f15bf619127f9d47c76a7c57e8ce8dd81ec8..5c1eec7664fb9d1bdbbece297c4603c13866a1ba 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.core.qualitygate.db;
 
 import org.apache.ibatis.session.SqlSession;
+import org.sonar.core.persistence.DaoComponent;
 import org.sonar.core.persistence.MyBatis;
 
 import java.util.Collection;
@@ -28,7 +29,7 @@ import java.util.Date;
 /**
  * @since 4.3
  */
-public class QualityGateConditionDao {
+public class QualityGateConditionDao implements DaoComponent {
 
   private final MyBatis myBatis;
 
diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java b/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java
deleted file mode 100644 (file)
index 372674b..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.jpa.dao;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.Predicate;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.measures.Metric;
-
-public class MeasuresDao {
-
-  private final DatabaseSession session;
-  private final Map<String, Metric> metricsByName = new HashMap<>();
-
-  public MeasuresDao(DatabaseSession session) {
-    this.session = session;
-  }
-
-  public Metric getMetric(String metricName) {
-    return getMetricsByName().get(metricName);
-  }
-
-  public Collection<Metric> getMetrics() {
-    return getMetricsByName().values();
-  }
-
-  public Collection<Metric> getEnabledMetrics() {
-    return CollectionUtils.select(getMetricsByName().values(), new Predicate() {
-      @Override
-      public boolean evaluate(Object o) {
-        return ((Metric) o).getEnabled();
-      }
-    });
-  }
-
-  public void disableAutomaticMetrics() {
-    session.createQuery("update " + Metric.class.getSimpleName() + " m set m.enabled=false where m.userManaged=false").executeUpdate();
-    session.commit();
-    metricsByName.clear();
-  }
-
-  public void registerMetrics(Collection<Metric> metrics) {
-    if (metrics != null) {
-      for (Metric metric : metrics) {
-        metric.setEnabled(Boolean.TRUE);
-        persistMetricWithoutClear(metric);
-      }
-      session.commit();
-    }
-    metricsByName.clear();
-  }
-
-  private void persistMetricWithoutClear(Metric metric) {
-    Metric dbMetric = getMetric(metric.getKey());
-    if (dbMetric != null) {
-      dbMetric.merge(metric);
-      session.getEntityManager().merge(dbMetric);
-
-    } else {
-      session.getEntityManager().persist(new Metric().merge(metric));
-    }
-  }
-
-  private Map<String, Metric> getMetricsByName() {
-    if (metricsByName.isEmpty()) {
-      List<Metric> metrics = session.getResults(Metric.class);
-      for (Metric metric : metrics) {
-        metricsByName.put(metric.getKey(), metric);
-      }
-    }
-    return metricsByName;
-  }
-
-}
index 9278b7252a59f3a9a4d621ce6c1747125233f676..a91e4c49259f86a2209332c8672ba315629cd18f 100644 (file)
@@ -47,6 +47,7 @@
     </where>
     ORDER BY UPPER(m.short_name), m.short_name
   </select>
+
   <select id="countEnabled" resultType="Integer">
     SELECT COUNT(*)
     FROM metrics m
     val_type=#{valueType, jdbcType=VARCHAR},
     enabled=#{enabled, jdbcType=BOOLEAN},
     domain=#{domain, jdbcType=VARCHAR},
-    description=#{description, jdbcType=VARCHAR}
+    description=#{description, jdbcType=VARCHAR},
+    direction=#{direction, jdbcType=INTEGER},
+    hidden=#{hidden, jdbcType=BOOLEAN},
+    qualitative=#{qualitative, jdbcType=BOOLEAN}
     where id=#{id}
   </update>
 
@@ -95,7 +99,7 @@
     where m.domain is not null and m.enabled=${_true}
   </select>
 
-  <update id="disable">
+  <update id="disableByIds">
     update metrics
     set enabled=${_false}
     <where>
     </where>
   </update>
 
+  <update id="disableByKey" parameterType="string">
+    update metrics
+    set enabled=${_false}
+    where name=#{key}
+  </update>
+
   <select id="selectByKeys" resultType="org.sonar.core.metric.db.MetricDto">
     SELECT
     <include refid="metricColumns"/>
diff --git a/sonar-core/src/test/java/org/sonar/core/metric/DefaultMetricFinderTest.java b/sonar-core/src/test/java/org/sonar/core/metric/DefaultMetricFinderTest.java
deleted file mode 100644 (file)
index 34a00af..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.core.metric;
-
-import java.util.Arrays;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsNull.nullValue;
-import static org.junit.Assert.assertThat;
-
-public class DefaultMetricFinderTest extends AbstractDbUnitTestCase {
-
-  private DefaultMetricFinder finder;
-
-  @Before
-  public void setUp() {
-    setupData("shared");
-    finder = new DefaultMetricFinder(getSessionFactory());
-  }
-
-  @Test
-  public void shouldFindAll() {
-    assertThat(finder.findAll().size(), is(2));
-  }
-
-  @Test
-  public void shouldFindByKeys() {
-    assertThat(finder.findAll(Arrays.<String> asList("ncloc", "foo", "coverage")).size(), is(2));
-  }
-
-  @Test
-  public void shouldFindById() {
-    assertThat(finder.findById(1).getKey(), is("ncloc"));
-    assertThat(finder.findById(3), nullValue());
-  }
-
-  @Test
-  public void shouldFindByKey() {
-    assertThat(finder.findByKey("ncloc").getKey(), is("ncloc"));
-    assertThat(finder.findByKey("disabled"), nullValue());
-  }
-}
diff --git a/sonar-core/src/test/java/org/sonar/jpa/dao/MeasuresDaoTest.java b/sonar-core/src/test/java/org/sonar/jpa/dao/MeasuresDaoTest.java
deleted file mode 100644 (file)
index 3c9d299..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.jpa.dao;
-
-import java.util.Arrays;
-import java.util.Collection;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.database.model.ResourceModel;
-import org.sonar.api.measures.Metric;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-public class MeasuresDaoTest extends AbstractDbUnitTestCase {
-
-  private MeasuresDao service;
-  private ResourceModel project;
-
-  @Before
-  public void before() {
-    service = new MeasuresDao(getSession());
-    project = new ResourceModel(ResourceModel.SCOPE_PROJECT, "foo:bar", ResourceModel.QUALIFIER_PROJECT_TRUNK, null, "Foo");
-    project.setName("project name");
-    getSession().save(project);
-  }
-
-  @Test
-  public void shouldRegisterMetrics() {
-    Collection<Metric> newMetrics = createMetrics();
-    service.registerMetrics(newMetrics);
-
-    Collection<Metric> metrics = service.getEnabledMetrics();
-    assertThat(metrics.size(), is(newMetrics.size()));
-  }
-
-  private Collection<Metric> createMetrics() {
-    Metric m1 = new Metric("metric1");
-    m1.setEnabled(false);
-
-    Metric m2 = new Metric("metric2");
-    m2.setEnabled(true);
-
-    Metric m3 = new Metric("metric3");
-    m3.setEnabled(false);
-
-    Metric m4 = new Metric("metric4");
-    m4.setEnabled(true);
-
-    Metric m5 = new Metric("metric5");
-    m5.setEnabled(true);
-
-    return Arrays.asList(m1, m2, m3, m4, m5);
-  }
-}
diff --git a/sonar-core/src/test/resources/org/sonar/core/metric/DefaultMetricFinderTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/metric/DefaultMetricFinderTest/shared.xml
deleted file mode 100644 (file)
index dd645d6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<dataset>
-
-  <metrics delete_historical_data="[null]" id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0"
-           hidden="false"/>
-
-  <metrics delete_historical_data="[null]" id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="true" worst_value="0" optimized_best_value="true" best_value="100" direction="1" hidden="false"/>
-
-  <metrics delete_historical_data="[null]" id="3" name="disabled" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
-           enabled="false" worst_value="0" optimized_best_value="true" best_value="100" direction="1" hidden="false"/>
-</dataset>
\ No newline at end of file