aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-06-11 14:26:49 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-06-15 13:07:53 +0200
commit101e804c19f0ad0d70ee7bec43203948e5deb135 (patch)
tree75e2b5fd5d96b967739bdae6e59f5e673ef0a512
parent5ab09f814612b081c31222a2c0ada09673bf96f5 (diff)
downloadsonarqube-101e804c19f0ad0d70ee7bec43203948e5deb135.tar.gz
sonarqube-101e804c19f0ad0d70ee7bec43203948e5deb135.zip
SONAR-6620 MetricRepository now loads all metrics at startup
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java36
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricRepositoryImpl.java76
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricDtoToMetricTest.java63
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryImplTest.java108
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/computation/metric/MetricRepositoryImplTest/shared.xml7
5 files changed, 233 insertions, 57 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java
new file mode 100644
index 00000000000..39c2860458a
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricDtoToMetric.java
@@ -0,0 +1,36 @@
+/*
+ * 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.metric;
+
+import com.google.common.base.Function;
+import javax.annotation.Nonnull;
+import org.sonar.core.metric.db.MetricDto;
+
+enum MetricDtoToMetric implements Function<MetricDto, Metric> {
+ INSTANCE;
+
+ @Override
+ @Nonnull
+ public Metric apply(@Nonnull MetricDto metricDto) {
+ return new MetricImpl(
+ metricDto.getId(), metricDto.getKey(), metricDto.getShortName(),
+ Metric.MetricType.valueOf(metricDto.getValueType()));
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricRepositoryImpl.java
index 4e04de2b2af..3307bc40cb9 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricRepositoryImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/metric/MetricRepositoryImpl.java
@@ -19,47 +19,91 @@
*/
package org.sonar.server.computation.metric;
+import com.google.common.base.Function;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import org.picocontainer.Startable;
import org.sonar.core.metric.db.MetricDto;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.db.DbClient;
+import static com.google.common.collect.FluentIterable.from;
import static java.util.Objects.requireNonNull;
-public class MetricRepositoryImpl implements MetricRepository {
+public class MetricRepositoryImpl implements MetricRepository, Startable {
private final DbClient dbClient;
+ @CheckForNull
+ private Map<String, Metric> metricsByKey;
+ @CheckForNull
+ private Map<Long, Metric> metricsById;
public MetricRepositoryImpl(DbClient dbClient) {
this.dbClient = dbClient;
}
@Override
+ public void start() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ List<MetricDto> metricList = dbClient.metricDao().selectEnabled(dbSession);
+ this.metricsByKey = from(metricList).transform(MetricDtoToMetric.INSTANCE).uniqueIndex(MetricToKey.INSTANCE);
+ this.metricsById = from(metricList).transform(MetricDtoToMetric.INSTANCE).uniqueIndex(MetricToId.INSTANCE);
+ }
+ }
+
+ @Override
+ public void stop() {
+ // nothing to do when stopping
+ }
+
+ @Override
public Metric getByKey(String key) {
requireNonNull(key);
+ verifyMetricsInitialized();
- try (DbSession dbSession = dbClient.openSession(false)) {
- MetricDto metricDto = dbClient.metricDao().selectNullableByKey(dbSession, key);
- if (metricDto == null) {
- throw new IllegalStateException(String.format("Metric with key '%s' does not exist", key));
- }
-
- return toMetric(metricDto);
+ Metric res = this.metricsByKey.get(key);
+ if (res == null) {
+ throw new IllegalStateException(String.format("Metric with key '%s' does not exist", key));
}
+ return res;
}
@Override
public Metric getById(long id) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- MetricDto metricDto = dbClient.metricDao().selectNullableById(dbSession, id);
- if (metricDto == null) {
- throw new IllegalStateException(String.format("Metric with id '%s' does not exist", id));
- }
+ verifyMetricsInitialized();
+
+ Metric res = this.metricsById.get(id);
+ if (res == null) {
+ throw new IllegalStateException(String.format("Metric with id '%s' does not exist", id));
+ }
+ return res;
+ }
+
+ private void verifyMetricsInitialized() {
+ if (this.metricsByKey == null) {
+ throw new IllegalStateException("Metric cache has not been initialized");
+ }
+ }
+
+ private enum MetricToKey implements Function<Metric, String> {
+ INSTANCE;
- return toMetric(metricDto);
+ @Override
+ @Nonnull
+ public String apply(@Nonnull Metric metric) {
+ return metric.getKey();
}
}
- private static Metric toMetric(MetricDto metricDto) {
- return new MetricImpl(metricDto.getId(), metricDto.getKey(), metricDto.getShortName(), Metric.MetricType.valueOf(metricDto.getValueType()));
+ private enum MetricToId implements Function<Metric, Long> {
+ INSTANCE;
+
+ @Override
+ @Nonnull
+ public Long apply(@Nonnull Metric metric) {
+ return (long) metric.getId();
+ }
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricDtoToMetricTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricDtoToMetricTest.java
new file mode 100644
index 00000000000..9bca629f2f8
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricDtoToMetricTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.metric;
+
+import org.junit.Test;
+import org.sonar.core.metric.db.MetricDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MetricDtoToMetricTest {
+
+ private MetricDtoToMetric underTest = MetricDtoToMetric.INSTANCE;
+
+ @Test(expected = NullPointerException.class)
+ public void apply_throws_NPE_if_arg_is_null() {
+ underTest.apply(null);
+ }
+
+ @Test
+ public void verify_mapping_from_dto() {
+
+ for (Metric.MetricType metricType : Metric.MetricType.values()) {
+ MetricDto metricDto = createMetricDto(metricType);
+ Metric metric = underTest.apply(metricDto);
+
+ assertThat(metric.getId()).isEqualTo(metricDto.getId());
+ assertThat(metric.getKey()).isEqualTo(metricDto.getKey());
+ assertThat(metric.getName()).isEqualTo(metricDto.getShortName());
+ assertThat(metric.getType()).isEqualTo(metricType);
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void apply_throws_IAE_if_valueType_can_not_be_parsed() {
+ underTest.apply(new MetricDto().setId(1).setKey("key").setValueType("trololo"));
+ }
+
+ private static MetricDto createMetricDto(Metric.MetricType metricType) {
+ return new MetricDto()
+ .setId(metricType.name().hashCode())
+ .setKey(metricType.name() + "_key")
+ .setShortName(metricType.name() + "_name")
+ .setValueType(metricType.name())
+ .setEnabled(true);
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryImplTest.java
index e47c5adc2d4..e37b02cae19 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/metric/MetricRepositoryImplTest.java
@@ -19,14 +19,12 @@
*/
package org.sonar.server.computation.metric;
-import javax.annotation.CheckForNull;
-import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import org.sonar.core.metric.db.MetricDto;
-import org.sonar.core.persistence.DbSession;
+import org.junit.rules.ExpectedException;
import org.sonar.core.persistence.DbTester;
import org.sonar.server.db.DbClient;
import org.sonar.server.metric.persistence.MetricDao;
@@ -36,71 +34,99 @@ import static org.assertj.core.api.Assertions.assertThat;
@Category(DbTests.class)
public class MetricRepositoryImplTest {
- private static final String SOME_KEY = "some key";
- private static final String SOME_NAME = "the short name";
+ private static final String SOME_KEY = "some_key";
+ private static final long SOME_ID = 156;
@ClassRule
public static final DbTester dbTester = new DbTester();
+ @Rule
+ public final ExpectedException expectedException = ExpectedException.none();
private DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new MetricDao());
- private MetricRepository underTest = new MetricRepositoryImpl(dbClient);
-
- @CheckForNull
- private DbSession dbSession;
+ private MetricRepositoryImpl underTest = new MetricRepositoryImpl(dbClient);
@Before
public void setUp() throws Exception {
dbTester.truncateTables();
}
- @After
- public void tearDown() throws Exception {
- if (dbSession != null) {
- dbSession.close();
- }
- }
-
@Test(expected = NullPointerException.class)
- public void findByKey_throws_NPE_if_arg_is_null() {
+ public void getByKey_throws_NPE_if_arg_is_null() {
underTest.getByKey(null);
}
- @Test(expected = IllegalStateException.class)
- public void findByKey_throws_ISE_of_Metric_does_not_exist() {
+ @Test
+ public void getByKey_throws_ISE_if_start_has_not_been_called() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Metric cache has not been initialized");
+
underTest.getByKey(SOME_KEY);
}
@Test
- public void verify_mapping_and_valueType_conversion_from_DB() {
- dbSession = dbClient.openSession(false);
+ public void getByKey_throws_ISE_of_Metric_does_not_exist() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage(String.format("Metric with key '%s' does not exist", SOME_KEY));
- for (Metric.MetricType metricType : Metric.MetricType.values()) {
- verify_mapping_and_valueType_conversion_from_DB_impl(metricType.name(), metricType);
- }
+ underTest.start();
+ underTest.getByKey(SOME_KEY);
}
- private void verify_mapping_and_valueType_conversion_from_DB_impl(String valueType, Metric.MetricType expected) {
- MetricDto metricDto = new MetricDto().setId(SOME_KEY.hashCode()).setKey(SOME_KEY + valueType).setShortName(SOME_NAME).setValueType(valueType);
+ @Test
+ public void getByKey_throws_ISE_of_Metric_is_disabled() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage(String.format("Metric with key '%s' does not exist", "complexity"));
- dbClient.metricDao().insert(dbSession, metricDto);
- dbSession.commit();
+ dbTester.prepareDbUnit(getClass(), "shared.xml");
- Metric metric = underTest.getByKey(metricDto.getKey());
+ underTest.start();
+ underTest.getByKey("complexity");
+ }
+
+ @Test
+ public void getByKey_find_enabled_Metrics() {
+ dbTester.prepareDbUnit(getClass(), "shared.xml");
- assertThat(metric.getId()).isEqualTo(metricDto.getId());
- assertThat(metric.getKey()).isEqualTo(metricDto.getKey());
- assertThat(metric.getName()).isEqualTo(metricDto.getShortName());
- assertThat(metric.getType()).isEqualTo(expected);
+ underTest.start();
+ assertThat(underTest.getByKey("ncloc").getId()).isEqualTo(1);
+ assertThat(underTest.getByKey("coverage").getId()).isEqualTo(2);
}
- @Test(expected = IllegalArgumentException.class)
- public void findByKey_throws_IAE_if_valueType_can_not_be_parsed() {
- MetricDto metricDto = new MetricDto().setKey(SOME_KEY).setShortName(SOME_NAME).setValueType("trololo");
+ @Test
+ public void getById_throws_ISE_if_start_has_not_been_called() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Metric cache has not been initialized");
- dbSession = dbClient.openSession(false);
- dbClient.metricDao().insert(dbSession, metricDto);
- dbSession.commit();
+ underTest.getById(SOME_ID);
+ }
- underTest.getByKey(SOME_KEY);
+ @Test
+ public void getById_throws_ISE_of_Metric_does_not_exist() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage(String.format("Metric with id '%s' does not exist", SOME_ID));
+
+ underTest.start();
+ underTest.getById(SOME_ID);
+ }
+
+ @Test
+ public void getById_throws_ISE_of_Metric_is_disabled() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage(String.format("Metric with id '%s' does not exist", 3));
+
+ dbTester.prepareDbUnit(getClass(), "shared.xml");
+
+ underTest.start();
+ underTest.getById(3);
+ }
+
+ @Test
+ public void getById_find_enabled_Metrics() {
+ dbTester.prepareDbUnit(getClass(), "shared.xml");
+
+ underTest.start();
+ assertThat(underTest.getById(1).getKey()).isEqualTo("ncloc");
+ assertThat(underTest.getById(2).getKey()).isEqualTo("coverage");
}
+
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/metric/MetricRepositoryImplTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/metric/MetricRepositoryImplTest/shared.xml
new file mode 100644
index 00000000000..49bb4594af1
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/computation/metric/MetricRepositoryImplTest/shared.xml
@@ -0,0 +1,7 @@
+<dataset>
+ <!-- enabled metrics -->
+ <metrics id="1" name="ncloc" VAL_TYPE="INT" short_name="ncloc_name" enabled="[true]" />
+ <metrics id="2" name="coverage" VAL_TYPE="INT" short_name="coverage_name" enabled="[true]" />
+ <!-- disabled metric -->
+ <metrics id="3" name="complexity" VAL_TYPE="INT" short_name="complexity_name" enabled="[false]" />
+</dataset>