From e88728fea0369029c6e197c347f3877d35a1a2ae Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Tue, 22 Jul 2014 15:26:27 +0200 Subject: [PATCH] SONAR-5477 First version of the global referentials WS : only metrics are returned for the moment --- server/sonar-server/pom.xml | 4 + .../java/org/sonar/server/batch/BatchWs.java | 11 +- .../batch/GlobalReferentialsAction.java | 80 ++++++++ .../java/org/sonar/server/db/DbClient.java | 7 + .../measure/persistence/MeasureDao.java | 8 +- .../server/measure/persistence/MetricDao.java | 78 ++++++++ .../server/platform/ServerComponents.java | 12 +- .../org/sonar/server/batch/BatchWsTest.java | 4 +- .../batch/GlobalReferentialsActionTest.java | 68 +++++++ .../measure/persistence/MeasureDaoTest.java | 5 + .../measure/persistence/MetricDaoTest.java | 79 ++++++++ .../return_global_referentials.json | 19 ++ .../persistence/MetricDaoTest/shared.xml | 32 ++++ .../org/sonar/core/measure/db/MetricDto.java | 173 ++++++++++++++++++ .../sonar/core/measure/db/MetricMapper.java | 33 ++++ .../org/sonar/core/persistence/MyBatis.java | 77 ++------ .../sonar/core/measure/db/MetricMapper.xml | 58 ++++++ 17 files changed, 670 insertions(+), 78 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/batch/GlobalReferentialsAction.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/batch/GlobalReferentialsActionTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MetricDaoTest.java create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalReferentialsActionTest/return_global_referentials.json create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MetricDaoTest/shared.xml create mode 100644 sonar-core/src/main/java/org/sonar/core/measure/db/MetricDto.java create mode 100644 sonar-core/src/main/java/org/sonar/core/measure/db/MetricMapper.java create mode 100644 sonar-core/src/main/resources/org/sonar/core/measure/db/MetricMapper.xml diff --git a/server/sonar-server/pom.xml b/server/sonar-server/pom.xml index ede2172bd84..e462e45623d 100644 --- a/server/sonar-server/pom.xml +++ b/server/sonar-server/pom.xml @@ -33,6 +33,10 @@ org.codehaus.sonar sonar-core + + org.codehaus.sonar + sonar-batch-protocol + org.codehaus.sonar sonar-deprecated diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java b/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java index 95c2facd33f..948ae241714 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java @@ -31,19 +31,22 @@ import java.io.IOException; public class BatchWs implements WebService { private final BatchIndex batchIndex; + private final GlobalReferentialsAction globalReferentialsAction; - public BatchWs(BatchIndex batchIndex) { + public BatchWs(BatchIndex batchIndex, GlobalReferentialsAction globalReferentialsAction) { this.batchIndex = batchIndex; + this.globalReferentialsAction = globalReferentialsAction; } @Override public void define(Context context) { NewController controller = context.createController("batch") .setSince("4.4") - .setDescription("Get JAR files for batch"); + .setDescription("Get JAR files and referentials for batch"); defineIndexAction(controller); defineFileAction(controller); + globalReferentialsAction.define(controller); controller.done(); } @@ -59,7 +62,7 @@ public class BatchWs implements WebService { response.stream().setMediaType("text/plain"); IOUtils.write(batchIndex.getIndex(), response.stream().output()); } catch (IOException e) { - throw new IllegalStateException("Fail to send batch index", e); + throw new IllegalStateException(e); } } }) @@ -78,7 +81,7 @@ public class BatchWs implements WebService { response.stream().setMediaType("application/java-archive"); FileUtils.copyFile(batchIndex.getFile(filename), response.stream().output()); } catch (IOException e) { - throw new IllegalStateException("Fail to send batch file " + filename, e); + throw new IllegalStateException(e); } } }) diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalReferentialsAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalReferentialsAction.java new file mode 100644 index 00000000000..1e8ad12599c --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalReferentialsAction.java @@ -0,0 +1,80 @@ +/* + * 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.batch; + +import org.apache.commons.io.IOUtils; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.RequestHandler; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.batch.protocol.input.GlobalReferentials; +import org.sonar.core.measure.db.MetricDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.server.db.DbClient; +import org.sonar.server.plugins.MimeTypes; + +public class GlobalReferentialsAction implements RequestHandler { + + private final DbClient dbClient; + + public GlobalReferentialsAction(DbClient dbClient) { + this.dbClient = dbClient; + } + + void define(WebService.NewController controller) { + controller.createAction("global") + .setDescription("Return global referentials") + .setSince("4.5") + .setInternal(true) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + // TODO check user permission + + DbSession session = dbClient.openSession(false); + try { + GlobalReferentials ref = new GlobalReferentials(); + for (MetricDto metric : dbClient.metricDao().findEnabled(session)) { + Boolean optimizedBestValue = metric.isOptimizedBestValue(); + ref.metrics().add( + new org.sonar.batch.protocol.input.Metric(metric.getId(), metric.getKey(), + metric.getValueType(), + metric.getDescription(), + metric.getDirection(), + metric.getName(), + metric.isQualitative(), + metric.isUserManaged(), + metric.getWorstValue(), + metric.getBestValue(), + optimizedBestValue != null ? optimizedBestValue : false)); + } + + response.stream().setMediaType(MimeTypes.JSON); + IOUtils.write(ref.toJson(), response.stream().output()); + } finally { + MyBatis.closeQuietly(session); + } + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java b/server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java index f1df9faa91e..2b7b1351f24 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java +++ b/server/sonar-server/src/main/java/org/sonar/server/db/DbClient.java @@ -35,6 +35,7 @@ import org.sonar.core.user.UserDao; import org.sonar.server.activity.db.ActivityDao; import org.sonar.server.component.persistence.ComponentDao; import org.sonar.server.measure.persistence.MeasureDao; +import org.sonar.server.measure.persistence.MetricDao; import org.sonar.server.qualityprofile.db.ActiveRuleDao; import org.sonar.server.rule.db.RuleDao; @@ -56,6 +57,7 @@ public class DbClient implements ServerComponent { private final ComponentDao componentDao; private final ResourceDao resourceDao; private final MeasureDao measureDao; + private final MetricDao metricDao; private final ActivityDao activityDao; private final AuthorizationDao authorizationDao; private final UserDao userDao; @@ -77,6 +79,7 @@ public class DbClient implements ServerComponent { componentDao = getDao(map, ComponentDao.class); resourceDao = getDao(map, ResourceDao.class); measureDao = getDao(map, MeasureDao.class); + metricDao = getDao(map, MetricDao.class); activityDao = getDao(map, ActivityDao.class); authorizationDao = getDao(map, AuthorizationDao.class); userDao = getDao(map, UserDao.class); @@ -126,6 +129,10 @@ public class DbClient implements ServerComponent { return measureDao; } + public MetricDao metricDao() { + return metricDao; + } + public ActivityDao activityDao() { return activityDao; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java b/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java index 80b279ec1cb..3067f32290f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java @@ -50,11 +50,11 @@ public class MeasureDao extends BaseDao i @Override protected MeasureDto doGetNullableByKey(DbSession session, MeasureKey key) { - return session.getMapper(MeasureMapper.class).selectByKey(key); + return mapper(session).selectByKey(key); } public boolean existsByKey(MeasureKey key, DbSession session) { - return session.getMapper(MeasureMapper.class).countByKey(key) > 0; + return mapper(session).countByKey(key) > 0; } public List findByComponentKeyAndMetricKeys(String componentKey, List metricKeys, DbSession session) { @@ -64,13 +64,13 @@ public class MeasureDao extends BaseDao i List dtos = newArrayList(); List> partitions = Lists.partition(newArrayList(metricKeys), 1000); for (List partition : partitions) { - dtos.addAll(session.getMapper(MeasureMapper.class).selectByComponentAndMetrics(componentKey, partition)); + dtos.addAll(mapper(session).selectByComponentAndMetrics(componentKey, partition)); } return dtos; } public MeasureDto findByComponentKeyAndMetricKey(String componentKey, String metricKey, DbSession session) { - return session.getMapper(MeasureMapper.class).selectByComponentAndMetric(componentKey, metricKey); + return mapper(session).selectByComponentAndMetric(componentKey, metricKey); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java b/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java new file mode 100644 index 00000000000..58e20d13557 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java @@ -0,0 +1,78 @@ +/* + * 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.measure.persistence; + +import com.google.common.annotations.VisibleForTesting; +import org.sonar.api.ServerComponent; +import org.sonar.api.utils.System2; +import org.sonar.core.measure.db.MetricDto; +import org.sonar.core.measure.db.MetricMapper; +import org.sonar.core.persistence.DaoComponent; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.db.BaseDao; + +import java.util.Date; +import java.util.List; + +public class MetricDao extends BaseDao implements ServerComponent, DaoComponent { + + public MetricDao() { + this(System2.INSTANCE); + } + + @VisibleForTesting + public MetricDao(System2 system) { + super(MetricMapper.class, system); + } + + @Override + protected MetricDto doGetNullableByKey(DbSession session, String key) { + return mapper(session).selectByKey(key); + } + + public List findEnabled(DbSession session) { + return mapper(session).selectAllEnabled(); + } + + @Override + protected MetricDto doInsert(DbSession session, MetricDto item) { + throw notImplemented(); + } + + @Override + protected MetricDto doUpdate(DbSession session, MetricDto item) { + throw notImplemented(); + } + + @Override + protected void doDeleteByKey(DbSession session, String key) { + throw notImplemented(); + } + + @Override + public void synchronizeAfter(DbSession session, Date date) { + throw notImplemented(); + } + + private static RuntimeException notImplemented() { + throw new IllegalStateException("Not implemented yet"); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index abbb80568c8..3b30ea64a68 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -80,6 +80,7 @@ import org.sonar.server.activity.ws.ActivityMapping; import org.sonar.server.authentication.ws.AuthenticationWs; import org.sonar.server.batch.BatchIndex; import org.sonar.server.batch.BatchWs; +import org.sonar.server.batch.GlobalReferentialsAction; import org.sonar.server.charts.ChartFactory; import org.sonar.server.component.DefaultComponentFinder; import org.sonar.server.component.DefaultRubyComponentService; @@ -110,6 +111,7 @@ import org.sonar.server.measure.MeasureFilterEngine; import org.sonar.server.measure.MeasureFilterExecutor; import org.sonar.server.measure.MeasureFilterFactory; import org.sonar.server.measure.persistence.MeasureDao; +import org.sonar.server.measure.persistence.MetricDao; import org.sonar.server.measure.ws.TimeMachineWs; import org.sonar.server.notifications.NotificationCenter; import org.sonar.server.notifications.NotificationService; @@ -203,6 +205,7 @@ class ServerComponents { RuleDao.class, ActiveRuleDao.class, MeasureDao.class, + MetricDao.class, ComponentDao.class, DbClient.class, MeasureFilterDao.class, @@ -238,10 +241,6 @@ class ServerComponents { DefaultServerUpgradeStatus.class, DatabaseMigrator.class, - // batch - BatchIndex.class, - BatchWs.class, - // plugins ServerPluginJarsInstaller.class, ServerPluginJarInstaller.class, @@ -294,6 +293,11 @@ class ServerComponents { pico.addSingleton(Periods.class); pico.addSingleton(ServerWs.class); + // batch + pico.addSingleton(BatchIndex.class); + pico.addSingleton(GlobalReferentialsAction.class); + pico.addSingleton(BatchWs.class); + // update center pico.addSingleton(UpdateCenterClient.class); pico.addSingleton(UpdateCenterMatrixFactory.class); diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java index eac56718fcb..689736c314b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java @@ -28,12 +28,14 @@ import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.server.db.DbClient; import org.sonar.server.ws.WsTester; import java.io.File; import java.io.IOException; import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) @@ -52,7 +54,7 @@ public class BatchWsTest { @Before public void before() throws IOException { - tester = new WsTester(new BatchWs(batchIndex)); + tester = new WsTester(new BatchWs(batchIndex, new GlobalReferentialsAction(mock(DbClient.class)))); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalReferentialsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalReferentialsActionTest.java new file mode 100644 index 00000000000..107a9f093ff --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalReferentialsActionTest.java @@ -0,0 +1,68 @@ +/* + * 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.batch; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.core.measure.db.MetricDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.db.DbClient; +import org.sonar.server.measure.persistence.MetricDao; +import org.sonar.server.ws.WsTester; + +import static com.google.common.collect.Lists.newArrayList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GlobalReferentialsActionTest { + + @Mock + DbSession session; + + @Mock + MetricDao metricDao; + + WsTester tester; + + @Before + public void setUp() throws Exception { + DbClient dbClient = mock(DbClient.class); + when(dbClient.openSession(false)).thenReturn(session); + when(dbClient.metricDao()).thenReturn(metricDao); + + tester = new WsTester(new BatchWs(mock(BatchIndex.class), new GlobalReferentialsAction(dbClient))); + } + + @Test + public void return_global_referentials() throws Exception { + when(metricDao.findEnabled(session)).thenReturn(newArrayList( + MetricDto.createFor("coverage").setDescription("Coverage by unit tests").setValueType("PERCENT").setQualitative(true) + .setWorstValue(0d).setBestValue(100d).setOptimizedBestValue(false).setDirection(1).setEnabled(true) + )); + + WsTester.TestRequest request = tester.newGetRequest("batch", "global"); + request.execute().assertJson(getClass(), "return_global_referentials.json"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java index a93f066059d..c343c550b79 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java @@ -124,4 +124,9 @@ public class MeasureDaoTest extends AbstractDaoTestCase { assertThat(dao.existsByKey(MeasureKey.of("org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc"), session)).isTrue(); assertThat(dao.existsByKey(MeasureKey.of("org.struts:struts-core:src/org/struts/RequestContext.java", "unknown"), session)).isFalse(); } + + @Test(expected = IllegalStateException.class) + public void insert() throws Exception { + dao.insert(session, MeasureDto.createFor(MeasureKey.of("org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc"))); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MetricDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MetricDaoTest.java new file mode 100644 index 00000000000..af2188460e7 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MetricDaoTest.java @@ -0,0 +1,79 @@ +/* + * 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.measure.persistence; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.sonar.core.measure.db.MetricDto; +import org.sonar.core.persistence.AbstractDaoTestCase; +import org.sonar.core.persistence.DbSession; + +import static org.fest.assertions.Assertions.assertThat; + +public class MetricDaoTest extends AbstractDaoTestCase { + + DbSession session; + + MetricDao dao; + + @Before + public void createDao() { + session = getMyBatis().openSession(false); + dao = new MetricDao(); + } + + @After + public void tearDown() throws Exception { + session.close(); + } + + @Test + public void get_by_key() throws Exception { + setupData("shared"); + + MetricDto result = dao.getNullableByKey(session, "coverage"); + assertThat(result.getId()).isEqualTo(2); + assertThat(result.getName()).isEqualTo("coverage"); + assertThat(result.getValueType()).isEqualTo("PERCENT"); + assertThat(result.getDescription()).isEqualTo("Coverage by unit tests"); + assertThat(result.getDirection()).isEqualTo(1); + assertThat(result.isQualitative()).isTrue(); + assertThat(result.isUserManaged()).isFalse(); + assertThat(result.getWorstValue()).isEqualTo(0d); + assertThat(result.getBestValue()).isEqualTo(100d); + assertThat(result.isOptimizedBestValue()).isFalse(); + assertThat(result.isEnabled()).isTrue(); + + // Disabled metrics are returned + result = dao.getNullableByKey(session, "disabled"); + assertThat(result.getId()).isEqualTo(3); + assertThat(result.isEnabled()).isFalse(); + } + + @Test + public void find_all_enabled() throws Exception { + setupData("shared"); + + assertThat(dao.findEnabled(session)).hasSize(2); + } + +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalReferentialsActionTest/return_global_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalReferentialsActionTest/return_global_referentials.json new file mode 100644 index 00000000000..ec34825d8c3 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalReferentialsActionTest/return_global_referentials.json @@ -0,0 +1,19 @@ +{ + "timestamp": 0, + "metrics": [ + { + "id": 0, + "key": "coverage", + "valueType": "PERCENT", + "description": "Coverage by unit tests", + "direction": 1, + "name": "coverage", + "qualitative": true, + "userManaged": false, + "worstValue": 0.0, + "bestValue": 100.0, + "optimizedBestValue": false + } + ], + "globalSettings": {} +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MetricDaoTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MetricDaoTest/shared.xml new file mode 100644 index 00000000000..50f05bf1946 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MetricDaoTest/shared.xml @@ -0,0 +1,32 @@ + + + + + diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MetricDto.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MetricDto.java new file mode 100644 index 00000000000..4f9d7cf5255 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/measure/db/MetricDto.java @@ -0,0 +1,173 @@ +/* + * 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.measure.db; + +import org.sonar.core.persistence.Dto; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +public class MetricDto extends Dto { + + private int id; + + private String name; + + private String valueType; + + private String description; + + private int direction; + + private boolean qualitative; + + private boolean userManaged; + + private Double worstValue; + + private Double bestValue; + + private Boolean optimizedBestValue; + + private boolean enabled; + + private MetricDto() { + // Nothing here + } + + public int getId() { + return id; + } + + public MetricDto setId(int id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public MetricDto setName(String name) { + this.name = name; + return this; + } + + public String getValueType() { + return valueType; + } + + public MetricDto setValueType(String valueType) { + this.valueType = valueType; + return this; + } + + /** + * @return null for manual metrics + */ + @CheckForNull + public String getDescription() { + return description; + } + + public MetricDto setDescription(@Nullable String description) { + this.description = description; + return this; + } + + public int getDirection() { + return direction; + } + + public MetricDto setDirection(int direction) { + this.direction = direction; + return this; + } + + public boolean isQualitative() { + return qualitative; + } + + public MetricDto setQualitative(boolean qualitative) { + this.qualitative = qualitative; + return this; + } + + public boolean isUserManaged() { + return userManaged; + } + + public MetricDto setUserManaged(boolean userManaged) { + this.userManaged = userManaged; + return this; + } + + @CheckForNull + public Double getWorstValue() { + return worstValue; + } + + public MetricDto setWorstValue(@Nullable Double worstValue) { + this.worstValue = worstValue; + return this; + } + + @CheckForNull + public Double getBestValue() { + return bestValue; + } + + public MetricDto setBestValue(@Nullable Double bestValue) { + this.bestValue = bestValue; + return this; + } + + /** + * @return null for manual metrics + */ + @CheckForNull + public Boolean isOptimizedBestValue() { + return optimizedBestValue; + } + + public MetricDto setOptimizedBestValue(@Nullable Boolean optimizedBestValue) { + this.optimizedBestValue = optimizedBestValue; + return this; + } + + public boolean isEnabled() { + return enabled; + } + + public MetricDto setEnabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + @Override + public String getKey() { + return name; + } + + public static MetricDto createFor(String key) { + return new MetricDto().setName(key); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MetricMapper.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MetricMapper.java new file mode 100644 index 00000000000..7282a917e50 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/measure/db/MetricMapper.java @@ -0,0 +1,33 @@ +/* + * 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.measure.db; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface MetricMapper { + + MetricDto selectByKey(@Param("key") String key); + + List selectAllEnabled(); + +} diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java index fa58e882c90..e8a97e02518 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java @@ -24,11 +24,7 @@ import com.google.common.io.Closeables; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.logging.LogFactory; import org.apache.ibatis.mapping.Environment; -import org.apache.ibatis.session.Configuration; -import org.apache.ibatis.session.ExecutorType; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; -import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.apache.ibatis.session.*; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.apache.ibatis.type.JdbcType; import org.slf4j.LoggerFactory; @@ -41,14 +37,7 @@ import org.sonar.core.cluster.WorkQueue; import org.sonar.core.component.ComponentDto; import org.sonar.core.component.db.ComponentMapper; import org.sonar.core.config.Logback; -import org.sonar.core.dashboard.ActiveDashboardDto; -import org.sonar.core.dashboard.ActiveDashboardMapper; -import org.sonar.core.dashboard.DashboardDto; -import org.sonar.core.dashboard.DashboardMapper; -import org.sonar.core.dashboard.WidgetDto; -import org.sonar.core.dashboard.WidgetMapper; -import org.sonar.core.dashboard.WidgetPropertyDto; -import org.sonar.core.dashboard.WidgetPropertyMapper; +import org.sonar.core.dashboard.*; import org.sonar.core.dependency.DependencyDto; import org.sonar.core.dependency.DependencyMapper; import org.sonar.core.dependency.ResourceSnapshotDto; @@ -57,53 +46,19 @@ import org.sonar.core.duplication.DuplicationMapper; import org.sonar.core.duplication.DuplicationUnitDto; import org.sonar.core.graph.jdbc.GraphDto; import org.sonar.core.graph.jdbc.GraphDtoMapper; -import org.sonar.core.issue.db.ActionPlanDto; -import org.sonar.core.issue.db.ActionPlanMapper; -import org.sonar.core.issue.db.ActionPlanStatsDto; -import org.sonar.core.issue.db.ActionPlanStatsMapper; -import org.sonar.core.issue.db.IssueChangeDto; -import org.sonar.core.issue.db.IssueChangeMapper; -import org.sonar.core.issue.db.IssueDto; -import org.sonar.core.issue.db.IssueFilterDto; -import org.sonar.core.issue.db.IssueFilterFavouriteDto; -import org.sonar.core.issue.db.IssueFilterFavouriteMapper; -import org.sonar.core.issue.db.IssueFilterMapper; -import org.sonar.core.issue.db.IssueMapper; -import org.sonar.core.issue.db.IssueStatsMapper; -import org.sonar.core.measure.db.MeasureDto; -import org.sonar.core.measure.db.MeasureFilterDto; -import org.sonar.core.measure.db.MeasureFilterMapper; -import org.sonar.core.measure.db.MeasureMapper; +import org.sonar.core.issue.db.*; +import org.sonar.core.measure.db.*; import org.sonar.core.notification.db.NotificationQueueDto; import org.sonar.core.notification.db.NotificationQueueMapper; -import org.sonar.core.permission.GroupWithPermissionDto; -import org.sonar.core.permission.PermissionTemplateDto; -import org.sonar.core.permission.PermissionTemplateGroupDto; -import org.sonar.core.permission.PermissionTemplateMapper; -import org.sonar.core.permission.PermissionTemplateUserDto; -import org.sonar.core.permission.UserWithPermissionDto; +import org.sonar.core.permission.*; import org.sonar.core.persistence.migration.v44.Migration44Mapper; import org.sonar.core.properties.PropertiesMapper; import org.sonar.core.properties.PropertyDto; import org.sonar.core.purge.PurgeMapper; import org.sonar.core.purge.PurgeableSnapshotDto; -import org.sonar.core.qualitygate.db.ProjectQgateAssociationDto; -import org.sonar.core.qualitygate.db.ProjectQgateAssociationMapper; -import org.sonar.core.qualitygate.db.QualityGateConditionDto; -import org.sonar.core.qualitygate.db.QualityGateConditionMapper; -import org.sonar.core.qualitygate.db.QualityGateDto; -import org.sonar.core.qualitygate.db.QualityGateMapper; -import org.sonar.core.qualityprofile.db.ActiveRuleDto; -import org.sonar.core.qualityprofile.db.ActiveRuleMapper; -import org.sonar.core.qualityprofile.db.ActiveRuleParamDto; -import org.sonar.core.qualityprofile.db.QualityProfileDto; -import org.sonar.core.qualityprofile.db.QualityProfileMapper; -import org.sonar.core.resource.ResourceDto; -import org.sonar.core.resource.ResourceIndexDto; -import org.sonar.core.resource.ResourceIndexerMapper; -import org.sonar.core.resource.ResourceKeyUpdaterMapper; -import org.sonar.core.resource.ResourceMapper; -import org.sonar.core.resource.SnapshotDto; +import org.sonar.core.qualitygate.db.*; +import org.sonar.core.qualityprofile.db.*; +import org.sonar.core.resource.*; import org.sonar.core.rule.RuleDto; import org.sonar.core.rule.RuleMapper; import org.sonar.core.rule.RuleParamDto; @@ -115,16 +70,7 @@ import org.sonar.core.technicaldebt.db.CharacteristicMapper; import org.sonar.core.technicaldebt.db.RequirementMigrationDto; import org.sonar.core.template.LoadedTemplateDto; import org.sonar.core.template.LoadedTemplateMapper; -import org.sonar.core.user.AuthorDto; -import org.sonar.core.user.AuthorMapper; -import org.sonar.core.user.GroupDto; -import org.sonar.core.user.GroupMembershipDto; -import org.sonar.core.user.GroupMembershipMapper; -import org.sonar.core.user.GroupRoleDto; -import org.sonar.core.user.RoleMapper; -import org.sonar.core.user.UserDto; -import org.sonar.core.user.UserMapper; -import org.sonar.core.user.UserRoleDto; +import org.sonar.core.user.*; import java.io.InputStream; @@ -134,7 +80,7 @@ public class MyBatis implements BatchComponent, ServerComponent { private final Logback logback; private SqlSessionFactory sessionFactory; - //TODO this queue should directly be an IndexQueue. Pending move of persistence to sonar-server + // TODO this queue should directly be an IndexQueue. Pending move of persistence to sonar-server private WorkQueue queue; public MyBatis(Database database, Logback logback, WorkQueue queue) { @@ -187,6 +133,7 @@ public class MyBatis implements BatchComponent, ServerComponent { loadAlias(conf, "WidgetProperty", WidgetPropertyDto.class); loadAlias(conf, "MeasureModel", MeasureModel.class); loadAlias(conf, "Measure", MeasureDto.class); + loadAlias(conf, "Metric", MetricDto.class); loadAlias(conf, "Issue", IssueDto.class); loadAlias(conf, "IssueChange", IssueChangeDto.class); loadAlias(conf, "IssueFilter", IssueFilterDto.class); @@ -221,7 +168,7 @@ public class MyBatis implements BatchComponent, ServerComponent { org.sonar.api.database.model.MeasureMapper.class, SnapshotDataMapper.class, SnapshotSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class, NotificationQueueMapper.class, CharacteristicMapper.class, GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class, - MeasureMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, ProjectQgateAssociationMapper.class + MeasureMapper.class, MetricMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, ProjectQgateAssociationMapper.class }; loadMappers(conf, mappers); configureLogback(mappers); diff --git a/sonar-core/src/main/resources/org/sonar/core/measure/db/MetricMapper.xml b/sonar-core/src/main/resources/org/sonar/core/measure/db/MetricMapper.xml new file mode 100644 index 00000000000..8feed30cc25 --- /dev/null +++ b/sonar-core/src/main/resources/org/sonar/core/measure/db/MetricMapper.xml @@ -0,0 +1,58 @@ + + + + + + + + + m.id, + m.name, + m.val_type as valueType, + m.description, + m.direction, + m.qualitative, + m.user_managed as userManaged, + m.worst_value as worstValue, + m.best_value as bestValue, + m.optimized_best_value as optimizedBestValue, + m.enabled + + + + + + + -- 2.39.5