--- /dev/null
+/*
+ * 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()));
+ }
+}
*/
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();
+ }
}
}
--- /dev/null
+/*
+ * 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);
+ }
+}
*/
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;
@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");
}
+
}
--- /dev/null
+<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>