+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.task.projectanalysis.step;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.util.List;
-import org.apache.commons.lang.math.NumberUtils;
-import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.ComponentVisitor;
-import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit;
-import org.sonar.ce.task.projectanalysis.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
-import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter;
-import org.sonar.ce.task.projectanalysis.measure.Measure;
-import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
-import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
-import org.sonar.ce.task.step.ComputationStep;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-
-public class CustomMeasuresCopyStep implements ComputationStep {
-
- private final TreeRootHolder treeRootHolder;
- private final DbClient dbClient;
- private final MetricRepository metricRepository;
- private final MeasureRepository measureRepository;
-
- public CustomMeasuresCopyStep(TreeRootHolder treeRootHolder, DbClient dbClient,
- MetricRepository metricRepository, MeasureRepository measureRepository) {
- this.treeRootHolder = treeRootHolder;
- this.dbClient = dbClient;
- this.metricRepository = metricRepository;
- this.measureRepository = measureRepository;
- }
-
- @Override
- public void execute(ComputationStep.Context context) {
- try (DbSession session = dbClient.openSession(false)) {
- CrawlerDepthLimit depthLimit = new CrawlerDepthLimit.Builder(Component.Type.PROJECT)
- .withViewsMaxDepth(Component.Type.PROJECT_VIEW);
- new DepthTraversalTypeAwareCrawler(
- new TypeAwareVisitorAdapter(depthLimit, ComponentVisitor.Order.PRE_ORDER) {
- @Override
- public void visitAny(Component component) {
- copy(component, session);
- }
- }).visit(treeRootHolder.getRoot());
- }
- }
-
- private void copy(Component component, DbSession session) {
- for (CustomMeasureDto dto : loadCustomMeasures(component, session)) {
- Metric metric = metricRepository.getByUuid(dto.getMetricUuid());
- // else metric is not found and an exception is raised
- Measure measure = dtoToMeasure(dto, metric);
- measureRepository.add(component, metric, measure);
- }
- }
-
- private List<CustomMeasureDto> loadCustomMeasures(Component component, DbSession session) {
- return dbClient.customMeasureDao().selectByComponentUuid(session, component.getUuid());
- }
-
- @VisibleForTesting
- static Measure dtoToMeasure(CustomMeasureDto dto, Metric metric) {
- switch (metric.getType()) {
- case INT:
- case RATING:
- return Measure.newMeasureBuilder().create((int) dto.getValue());
- case MILLISEC:
- case WORK_DUR:
- return Measure.newMeasureBuilder().create((long) dto.getValue());
- case FLOAT:
- case PERCENT:
- return Measure.newMeasureBuilder().create(dto.getValue(), metric.getDecimalScale());
- case BOOL:
- return Measure.newMeasureBuilder().create(NumberUtils.compare(dto.getValue(), 1.0) == 0);
- case LEVEL:
- return Measure.newMeasureBuilder().create(Measure.Level.valueOf(dto.getTextValue()));
- case STRING:
- case DISTRIB:
- case DATA:
- String textValue = dto.getTextValue();
- if (textValue == null) {
- return Measure.newMeasureBuilder().createNoValue();
- }
- return Measure.newMeasureBuilder().create(textValue);
- default:
- throw new IllegalArgumentException(String.format("Custom measures do not support the metric type [%s]", metric.getType()));
- }
- }
-
- @Override
- public String getDescription() {
- return "Copy custom measures";
- }
-}
NewCoverageMeasuresStep.class,
CoverageMeasuresStep.class,
CommentMeasuresStep.class,
- CustomMeasuresCopyStep.class,
DuplicationMeasuresStep.class,
NewSizeMeasuresStep.class,
LanguageDistributionMeasuresStep.class,
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.task.projectanalysis.step;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.utils.System2;
-import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
-import org.sonar.ce.task.projectanalysis.component.ReportComponent;
-import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
-import org.sonar.ce.task.projectanalysis.component.ViewsComponent;
-import org.sonar.ce.task.projectanalysis.measure.Measure;
-import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
-import org.sonar.ce.task.projectanalysis.metric.Metric;
-import org.sonar.ce.task.projectanalysis.metric.MetricImpl;
-import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
-import org.sonar.ce.task.step.TestComputationStepContext;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbTester;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.measure.custom.CustomMeasureTesting;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY;
-import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
-import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
-import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT_VIEW;
-import static org.sonar.ce.task.projectanalysis.component.Component.Type.SUBVIEW;
-import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW;
-import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;
-import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
-import static org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry.entryOf;
-import static org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry.toEntries;
-import static org.sonar.ce.task.projectanalysis.step.CustomMeasuresCopyStep.dtoToMeasure;
-
-public class CustomMeasuresCopyStepTest {
-
- private static final int PROJECT_REF = 1;
- private static final int DIR_REF = 1111;
- private static final int FILE1_REF = 11111;
- private static final int FILE2_REF = 11112;
-
- private static final String PROJECT_UUID = "PROJECT";
- private static final String DIR_UUID = "DIR";
- private static final String FILE1_UUID = "FILE1";
- private static final String FILE2_UUID = "FILE2";
-
- private static final String VIEW_UUID = "VIEW";
- private static final String SUBVIEW_UUID = "SUBVIEW";
-
- private static final int VIEW_REF = 10;
- private static final int SUBVIEW_REF = 101;
- private static final int PROJECT_VIEW_REF = 1011;
-
- private static final Metric FLOAT_METRIC = new MetricImpl("10", "float_metric", "Float Metric", Metric.MetricType.FLOAT);
- private static final Metric STRING_METRIC = new MetricImpl("11", "string_metric", "String Metric", Metric.MetricType.STRING);
-
- @Rule
- public DbTester dbTester = DbTester.create(System2.INSTANCE);
- @Rule
- public BatchReportReaderRule reportReader = new BatchReportReaderRule();
- @Rule
- public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
- @Rule
- public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
- .add(FLOAT_METRIC)
- .add(STRING_METRIC);
- @Rule
- public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
-
- CustomMeasuresCopyStep underTest;
-
- @Before
- public void setUp() {
- DbClient dbClient = dbTester.getDbClient();
- underTest = new CustomMeasuresCopyStep(treeRootHolder, dbClient, metricRepository, measureRepository);
- }
-
- @Test
- public void copy_custom_measures_on_report() {
- insertCustomMeasure(FILE1_UUID, FLOAT_METRIC, 3.14);
- insertCustomMeasure(DIR_UUID, FLOAT_METRIC, 123d);
- insertCustomMeasure(PROJECT_UUID, STRING_METRIC, "project");
- // Module2 has no custom measure
-
- treeRootHolder.setRoot(
- builder(PROJECT, PROJECT_REF).setUuid(PROJECT_UUID)
- .addChildren(
- ReportComponent.builder(DIRECTORY, DIR_REF).setUuid(DIR_UUID)
- .addChildren(
- ReportComponent.builder(FILE, FILE1_REF).setUuid(FILE1_UUID).build(),
- ReportComponent.builder(FILE, FILE2_REF).setUuid(FILE2_UUID).build())
- .build())
- .build());
-
- underTest.execute(new TestComputationStepContext());
-
- assertNoRawMeasureValue(FILE1_REF);
- assertNoRawMeasureValue(FILE2_REF);
- assertNoRawMeasureValue(DIR_REF);
- assertRawMeasureValue(PROJECT_REF, STRING_METRIC.getKey(), "project");
-
- }
-
- @Test
- public void copy_custom_measures_on_view() {
- // View and subview have custom measures, but not project_view
- insertCustomMeasure(SUBVIEW_UUID, FLOAT_METRIC, 3.14);
- insertCustomMeasure(VIEW_UUID, STRING_METRIC, "good");
-
- treeRootHolder.setRoot(
- ViewsComponent.builder(VIEW, VIEW_REF).setUuid("VIEW")
- .addChildren(
- ViewsComponent.builder(SUBVIEW, SUBVIEW_REF).setUuid("SUBVIEW").build(),
- ViewsComponent.builder(PROJECT_VIEW, PROJECT_VIEW_REF).setUuid("PROJECT_VIEW").build())
- .build());
-
- underTest.execute(new TestComputationStepContext());
-
- assertNoRawMeasureValue(PROJECT_VIEW_REF);
- assertRawMeasureValue(SUBVIEW_REF, FLOAT_METRIC.getKey(), 3.1d);
- assertRawMeasureValue(VIEW_REF, STRING_METRIC.getKey(), "good");
- }
-
- @Test
- public void test_float_metric_type() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setValue(10.0);
- assertThat(dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.FLOAT)).getDoubleValue()).isEqualTo(10.0);
- }
-
- @Test
- public void test_int_metric_type() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setValue(10.0);
- assertThat(dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.INT)).getIntValue()).isEqualTo(10);
- }
-
- @Test
- public void test_long_metric_type() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setValue(10.0);
- assertThat(dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.WORK_DUR)).getLongValue()).isEqualTo(10);
- }
-
- @Test
- public void test_percent_metric_type() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setValue(10.0);
- assertThat(dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.PERCENT)).getDoubleValue()).isEqualTo(10);
- }
-
- @Test
- public void test_string_metric_type() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setTextValue("foo");
- assertThat(dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.STRING)).getStringValue()).isEqualTo("foo");
- }
-
- @Test
- public void test_string_metric_type_with_null_value() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setTextValue(null);
-
- Measure measure = dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.STRING));
- assertThat(measure.getValueType()).isEqualTo(Measure.ValueType.NO_VALUE);
- }
-
- @Test
- public void test_data_metric_type_with_null_value() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setTextValue(null);
-
- Measure measure = dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.DATA));
- assertThat(measure.getValueType()).isEqualTo(Measure.ValueType.NO_VALUE);
- }
-
- @Test
- public void test_ditrib_metric_type_with_null_value() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setTextValue(null);
-
- Measure measure = dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.DISTRIB));
- assertThat(measure.getValueType()).isEqualTo(Measure.ValueType.NO_VALUE);
- }
-
- @Test
- public void test_LEVEL_metric_type() {
- CustomMeasureDto dto = new CustomMeasureDto();
- dto.setTextValue("OK");
- assertThat(dtoToMeasure(dto, new MetricImpl("1", "m", "M", Metric.MetricType.LEVEL)).getLevelValue()).isEqualTo(Measure.Level.OK);
- }
-
- @Test
- public void test_boolean_metric_type() {
- MetricImpl booleanMetric = new MetricImpl("1", "m", "M", Metric.MetricType.BOOL);
- CustomMeasureDto dto = new CustomMeasureDto();
- assertThat(dtoToMeasure(dto.setValue(1.0), booleanMetric).getBooleanValue()).isTrue();
- assertThat(dtoToMeasure(dto.setValue(0.0), booleanMetric).getBooleanValue()).isFalse();
- }
-
- private void assertNoRawMeasureValue(int componentRef) {
- assertThat(measureRepository.getAddedRawMeasures(componentRef)).isEmpty();
- }
-
- private void assertRawMeasureValue(int componentRef, String metricKey, double value) {
- assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly(entryOf(metricKey, newMeasureBuilder().create(value, 1)));
- }
-
- private void assertRawMeasureValue(int componentRef, String metricKey, String value) {
- assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly(entryOf(metricKey, newMeasureBuilder().create(value)));
- }
-
- private void insertCustomMeasure(String componentUuid, Metric metric, double value) {
- dbTester.getDbClient().customMeasureDao().insert(dbTester.getSession(), CustomMeasureTesting.newCustomMeasureDto()
- .setComponentUuid(componentUuid)
- .setMetricUuid(metric.getUuid())
- .setValue(value));
- dbTester.getSession().commit();
- }
-
- private void insertCustomMeasure(String componentUuid, Metric metric, String value) {
- dbTester.getDbClient().customMeasureDao().insert(dbTester.getSession(), CustomMeasureTesting.newCustomMeasureDto()
- .setComponentUuid(componentUuid)
- .setMetricUuid(metric.getUuid())
- .setTextValue(value));
- dbTester.getSession().commit();
- }
-
-}
import org.sonar.db.mapping.ProjectMappingsDao;
import org.sonar.db.measure.LiveMeasureDao;
import org.sonar.db.measure.MeasureDao;
-import org.sonar.db.measure.custom.CustomMeasureDao;
import org.sonar.db.metric.MetricDao;
import org.sonar.db.newcodeperiod.NewCodePeriodDao;
import org.sonar.db.notification.NotificationQueueDao;
CeTaskMessageDao.class,
ComponentDao.class,
ComponentKeyUpdaterDao.class,
- CustomMeasureDao.class,
DefaultQProfileDao.class,
DuplicationDao.class,
EsQueueDao.class,
import org.sonar.db.mapping.ProjectMappingsDao;
import org.sonar.db.measure.LiveMeasureDao;
import org.sonar.db.measure.MeasureDao;
-import org.sonar.db.measure.custom.CustomMeasureDao;
import org.sonar.db.metric.MetricDao;
import org.sonar.db.newcodeperiod.NewCodePeriodDao;
import org.sonar.db.notification.NotificationQueueDao;
private final ProjectQgateAssociationDao projectQgateAssociationDao;
private final DuplicationDao duplicationDao;
private final NotificationQueueDao notificationQueueDao;
- private final CustomMeasureDao customMeasureDao;
private final MetricDao metricDao;
private final GroupDao groupDao;
private final RuleDao ruleDao;
projectQgateAssociationDao = getDao(map, ProjectQgateAssociationDao.class);
duplicationDao = getDao(map, DuplicationDao.class);
notificationQueueDao = getDao(map, NotificationQueueDao.class);
- customMeasureDao = getDao(map, CustomMeasureDao.class);
metricDao = getDao(map, MetricDao.class);
groupDao = getDao(map, GroupDao.class);
ruleDao = getDao(map, RuleDao.class);
return notificationQueueDao;
}
- public CustomMeasureDao customMeasureDao() {
- return customMeasureDao;
- }
-
public MetricDao metricDao() {
return metricDao;
}
import org.sonar.db.measure.LiveMeasureMapper;
import org.sonar.db.measure.MeasureDto;
import org.sonar.db.measure.MeasureMapper;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.measure.custom.CustomMeasureMapper;
import org.sonar.db.metric.MetricMapper;
import org.sonar.db.newcodeperiod.NewCodePeriodMapper;
import org.sonar.db.notification.NotificationQueueDto;
confBuilder.loadAlias("Component", ComponentDto.class);
confBuilder.loadAlias("ComponentWithModuleUuid", ComponentWithModuleUuidDto.class);
confBuilder.loadAlias("ComponentWithSnapshot", ComponentDtoWithSnapshotId.class);
- confBuilder.loadAlias("CustomMeasure", CustomMeasureDto.class);
confBuilder.loadAlias("DuplicationUnit", DuplicationUnitDto.class);
confBuilder.loadAlias("Event", EventDto.class);
confBuilder.loadAlias("FilePathWithHash", FilePathWithHashDto.class);
ComponentKeyUpdaterMapper.class,
ComponentMapper.class,
LiveMeasureMapper.class,
- CustomMeasureMapper.class,
DefaultQProfileMapper.class,
DuplicationMapper.class,
EsQueueMapper.class,
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.db.measure.custom;
-
-import java.util.List;
-import java.util.Optional;
-import org.apache.ibatis.session.RowBounds;
-import org.sonar.core.util.UuidFactory;
-import org.sonar.db.Dao;
-import org.sonar.db.DatabaseUtils;
-import org.sonar.db.DbSession;
-
-import static java.util.Optional.ofNullable;
-
-public class CustomMeasureDao implements Dao {
- private final UuidFactory uuidFactory;
-
- public CustomMeasureDao(UuidFactory uuidFactory) {
- this.uuidFactory = uuidFactory;
- }
-
- public void insert(DbSession session, CustomMeasureDto customMeasureDto) {
- customMeasureDto.setUuid(uuidFactory.create());
- mapper(session).insert(customMeasureDto);
- }
-
- public void update(DbSession session, CustomMeasureDto customMeasure) {
- mapper(session).update(customMeasure);
- }
-
- public void delete(DbSession session, String uuid) {
- mapper(session).delete(uuid);
- }
-
- public void deleteByMetricUuids(DbSession session, List<String> metricUuids) {
- DatabaseUtils.executeLargeInputsWithoutOutput(metricUuids, input -> mapper(session).deleteByMetricUuids(metricUuids));
- }
-
- public Optional<CustomMeasureDto> selectByUuid(DbSession session, String uuid) {
- return ofNullable(mapper(session).selectByUuid(uuid));
- }
-
- public List<CustomMeasureDto> selectByMetricUuid(DbSession session, String metricUuid) {
- return mapper(session).selectByMetricUuid(metricUuid);
- }
-
- public int countByComponentIdAndMetricUuid(DbSession session, String componentUuid, String metricUuid) {
- return mapper(session).countByComponentIdAndMetricUuid(componentUuid, metricUuid);
- }
-
- public List<CustomMeasureDto> selectByComponentUuid(DbSession session, String componentUuid, int offset, int limit) {
- return mapper(session).selectByComponentUuid(componentUuid, new RowBounds(offset, limit));
- }
-
- public List<CustomMeasureDto> selectByComponentUuid(DbSession session, String componentUuid) {
- return mapper(session).selectByComponentUuid(componentUuid);
- }
-
- /**
- * Used by Views plugin
- */
- public List<CustomMeasureDto> selectByMetricKeyAndTextValue(DbSession session, String metricKey, String textValue) {
- return mapper(session).selectByMetricKeyAndTextValue(metricKey, textValue);
- }
-
- private static CustomMeasureMapper mapper(DbSession session) {
- return session.getMapper(CustomMeasureMapper.class);
- }
-
- public int countByComponentUuid(DbSession dbSession, String uuid) {
- return mapper(dbSession).countByComponentUuid(uuid);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.db.measure.custom;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-public class CustomMeasureDto {
- private String uuid = null;
- private String metricUuid = null;
- private String componentUuid = null;
- private double value = 0.0D;
- private String textValue = null;
- private String userUuid = null;
- private String description = null;
- private long createdAt = 0L;
- private long updatedAt = 0L;
-
- public String getUuid() {
- return uuid;
- }
-
- public CustomMeasureDto setUuid(String uuid) {
- this.uuid = uuid;
- return this;
- }
-
- @CheckForNull
- public String getDescription() {
- return description;
- }
-
- public CustomMeasureDto setDescription(@Nullable String description) {
- this.description = description;
- return this;
- }
-
- public String getUserUuid() {
- return userUuid;
- }
-
- public CustomMeasureDto setUserUuid(String userUuid) {
- this.userUuid = userUuid;
- return this;
- }
-
- @CheckForNull
- public String getTextValue() {
- return textValue;
- }
-
- public CustomMeasureDto setTextValue(@Nullable String textValue) {
- this.textValue = textValue;
- return this;
- }
-
- public double getValue() {
- return value;
- }
-
- public CustomMeasureDto setValue(double value) {
- this.value = value;
- return this;
- }
-
- public String getMetricUuid() {
- return metricUuid;
- }
-
- public CustomMeasureDto setMetricUuid(String metricUuid) {
- this.metricUuid = metricUuid;
- return this;
- }
-
- public long getUpdatedAt() {
- return updatedAt;
- }
-
- public CustomMeasureDto setUpdatedAt(long updatedAt) {
- this.updatedAt = updatedAt;
- return this;
- }
-
- public long getCreatedAt() {
- return createdAt;
- }
-
- public CustomMeasureDto setCreatedAt(long createdAt) {
- this.createdAt = createdAt;
- return this;
- }
-
- public String getComponentUuid() {
- return componentUuid;
- }
-
- public CustomMeasureDto setComponentUuid(String componentUuid) {
- this.componentUuid = componentUuid;
- return this;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.db.measure.custom;
-
-import java.util.List;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.session.RowBounds;
-
-public interface CustomMeasureMapper {
- void insert(CustomMeasureDto customMeasure);
-
- void update(CustomMeasureDto customMeasure);
-
- void delete(String uuid);
-
- void deleteByMetricUuids(@Param("metricUuids") List<String> metricUuids);
-
- CustomMeasureDto selectByUuid(String uuid);
-
- List<CustomMeasureDto> selectByMetricUuid(String uuid);
-
- List<CustomMeasureDto> selectByComponentUuid(String s);
-
- List<CustomMeasureDto> selectByComponentUuid(String s, RowBounds rowBounds);
-
- List<CustomMeasureDto> selectByMetricKeyAndTextValue(@Param("metricKey") String metricKey, @Param("textValue") String textValue);
-
- int countByComponentUuid(String componentUuid);
-
- int countByComponentIdAndMetricUuid(@Param("componentUuid") String componentUuid, @Param("metricUuid") String metricUuid);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.db.measure.custom;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.db.measure.custom;
-
-import java.util.List;
-import java.util.Optional;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.utils.System2;
-import org.sonar.core.util.UuidFactory;
-import org.sonar.core.util.UuidFactoryFast;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
-
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.offset;
-import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.db.measure.custom.CustomMeasureTesting.newCustomMeasureDto;
-
-public class CustomMeasureDaoTest {
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
-
- private DbSession session = db.getSession();
-
- private UuidFactory uuidFactory = UuidFactoryFast.getInstance();
- private CustomMeasureDao underTest = new CustomMeasureDao(uuidFactory);
-
- @Test
- public void insert() {
- UserDto user = db.users().insertUser();
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true));
- CustomMeasureDto measure = newCustomMeasureDto()
- .setComponentUuid(project.uuid())
- .setMetricUuid(metric.getUuid())
- .setUserUuid(user.getUuid());
-
- underTest.insert(session, measure);
-
- Optional<CustomMeasureDto> optionalResult = underTest.selectByUuid(session, measure.getUuid());
- assertThat(optionalResult).isNotEmpty();
- CustomMeasureDto result = optionalResult.get();
- assertThat(result.getUuid()).isEqualTo(measure.getUuid());
- assertThat(result.getMetricUuid()).isEqualTo(metric.getUuid());
- assertThat(result.getComponentUuid()).isEqualTo(project.uuid());
- assertThat(result.getUserUuid()).isEqualTo(user.getUuid());
- assertThat(result.getDescription()).isEqualTo(measure.getDescription());
- assertThat(result.getTextValue()).isEqualTo(measure.getTextValue());
- assertThat(result.getValue()).isCloseTo(measure.getValue(), offset(0.001d));
- assertThat(result.getCreatedAt()).isEqualTo(measure.getCreatedAt());
- assertThat(result.getUpdatedAt()).isEqualTo(measure.getUpdatedAt());
- }
-
- @Test
- public void delete_by_metric_id() {
- UserDto user = db.users().insertUser();
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true));
- CustomMeasureDto measure = db.measures().insertCustomMeasure(user, project, metric);
-
- underTest.deleteByMetricUuids(session, singletonList(measure.getMetricUuid()));
-
- assertThat(underTest.selectByUuid(session, measure.getUuid())).isEmpty();
- }
-
- @Test
- public void update() {
- UserDto user = db.users().insertUser();
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true));
- CustomMeasureDto measure = db.measures().insertCustomMeasure(user, project, metric, m -> m.setDescription("old-description"));
-
- underTest.update(session, measure.setDescription("new-description"));
-
- Optional<CustomMeasureDto> result = underTest.selectByUuid(session, measure.getUuid());
- assertThat(result).isNotEmpty();
- assertThat(result.get().getDescription()).isEqualTo("new-description");
- }
-
- @Test
- public void delete() {
- UserDto user = db.users().insertUser();
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true));
- CustomMeasureDto measure = db.measures().insertCustomMeasure(user, project, metric);
-
- underTest.delete(session, measure.getUuid());
-
- assertThat(underTest.selectByUuid(session, measure.getUuid())).isEmpty();
- }
-
- @Test
- public void select_by_component_uuid() {
- UserDto user = db.users().insertUser();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true));
- ComponentDto project1 = db.components().insertPrivateProject();
- CustomMeasureDto measure1 = db.measures().insertCustomMeasure(user, project1, metric);
- CustomMeasureDto measure2 = db.measures().insertCustomMeasure(user, project1, metric);
- ComponentDto project2 = db.components().insertPrivateProject();
- CustomMeasureDto measure3 = db.measures().insertCustomMeasure(user, project2, metric);
-
- assertThat(underTest.selectByComponentUuid(session, project1.uuid()))
- .extracting(CustomMeasureDto::getUuid, CustomMeasureDto::getComponentUuid)
- .containsOnly(
- tuple(measure1.getUuid(), project1.uuid()),
- tuple(measure2.getUuid(), project1.uuid()))
- .doesNotContain(tuple(measure3.getUuid(), project2.uuid()));
-
- assertThat(underTest.countByComponentUuid(session, project1.uuid())).isEqualTo(2);
- }
-
- @Test
- public void select_by_component_uuid_with_options() {
- UserDto user = db.users().insertUser();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true));
- ComponentDto project1 = db.components().insertPrivateProject();
- CustomMeasureDto measure1 = db.measures().insertCustomMeasure(user, project1, metric);
- CustomMeasureDto measure2 = db.measures().insertCustomMeasure(user, project1, metric);
- ComponentDto project2 = db.components().insertPrivateProject();
- CustomMeasureDto measure3 = db.measures().insertCustomMeasure(user, project2, metric);
-
- assertThat(underTest.selectByComponentUuid(session, project1.uuid(), 0, 100))
- .extracting(CustomMeasureDto::getUuid, CustomMeasureDto::getComponentUuid)
- .containsOnly(
- tuple(measure1.getUuid(), project1.uuid()),
- tuple(measure2.getUuid(), project1.uuid()))
- .doesNotContain(tuple(measure3.getUuid(), project2.uuid()));
- }
-
- @Test
- public void select_by_metric_id() {
- underTest.insert(session, newCustomMeasureDto().setMetricUuid("metric"));
- underTest.insert(session, newCustomMeasureDto().setMetricUuid("metric"));
-
- List<CustomMeasureDto> result = underTest.selectByMetricUuid(session, "metric");
-
- assertThat(result).hasSize(2);
- }
-
- @Test
- public void count_by_component_uuid_and_metric_id() {
- underTest.insert(session, newCustomMeasureDto().setMetricUuid("metric").setComponentUuid("123"));
- underTest.insert(session, newCustomMeasureDto().setMetricUuid("metric").setComponentUuid("123"));
-
- int count = underTest.countByComponentIdAndMetricUuid(session, "123", "metric");
-
- assertThat(count).isEqualTo(2);
- }
-
- @Test
- public void select_by_metric_key_and_text_value() {
- UserDto user = db.users().insertUser();
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true));
- CustomMeasureDto customMeasure1 = db.measures().insertCustomMeasure(user, project, metric, m -> m.setTextValue("value"));
- CustomMeasureDto customMeasure2 = db.measures().insertCustomMeasure(user, project, metric, m -> m.setTextValue("value"));
- CustomMeasureDto customMeasure3 = db.measures().insertCustomMeasure(user, project, metric, m -> m.setTextValue("other value"));
-
- assertThat(underTest.selectByMetricKeyAndTextValue(session, metric.getKey(), "value"))
- .extracting(CustomMeasureDto::getUuid)
- .containsExactlyInAnyOrder(customMeasure1.getUuid(), customMeasure2.getUuid())
- .doesNotContain(customMeasure3.getUuid());
-
- assertThat(underTest.selectByMetricKeyAndTextValue(session, metric.getKey(), "unknown")).isEmpty();
- assertThat(underTest.selectByMetricKeyAndTextValue(session, "unknown", "value")).isEmpty();
- }
-}
import org.sonar.db.issue.IssueDto;
import org.sonar.db.measure.LiveMeasureDto;
import org.sonar.db.measure.MeasureDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.newcodeperiod.NewCodePeriodType;
.containsOnly(view.uuid(), pc.uuid());
}
- @Test
- public void deleteNonRootComponentsInView_deletes_manual_measures_of_subviews_of_a_view() {
- ComponentDto view = db.components().insertPrivatePortfolio();
- ComponentDto subview1 = db.components().insertComponent(newSubView(view));
- ComponentDto subview2 = db.components().insertComponent(newSubView(subview1));
- ComponentDto subview3 = db.components().insertComponent(newSubView(view));
- ComponentDto pc = db.components().insertComponent(newProjectCopy("a", db.components().insertPrivateProject(), view));
- insertManualMeasureFor(view, subview1, subview2, subview3, pc);
- assertThat(getComponentUuidsOfManualMeasures()).containsOnly(view.uuid(), subview1.uuid(), subview2.uuid(), subview3.uuid(), pc.uuid());
-
- underTest.deleteNonRootComponentsInView(dbSession, singletonList(subview1));
- assertThat(getComponentUuidsOfManualMeasures())
- .containsOnly(view.uuid(), subview2.uuid(), subview3.uuid(), pc.uuid());
-
- underTest.deleteNonRootComponentsInView(dbSession, asList(subview2, subview3, pc));
- assertThat(getComponentUuidsOfManualMeasures())
- .containsOnly(view.uuid(), pc.uuid());
- }
-
@Test
public void purgeCeActivities_deletes_activity_older_than_180_days_and_their_scanner_context() {
LocalDateTime now = LocalDateTime.now();
db.getSession().commit();
}
- private void insertManualMeasureFor(ComponentDto... componentDtos) {
- Arrays.stream(componentDtos).forEach(componentDto -> dbClient.customMeasureDao().insert(dbSession, new CustomMeasureDto()
- .setComponentUuid(componentDto.uuid())
- .setMetricUuid(randomAlphabetic(3))));
- dbSession.commit();
- }
-
private Stream<String> getComponentUuidsOfManualMeasures() {
return db.select("select component_uuid as \"COMPONENT_UUID\" from manual_measures").stream()
.map(row -> (String) row.get("COMPONENT_UUID"));
*/
package org.sonar.db.measure;
-import com.google.common.base.Preconditions;
import java.util.Arrays;
import java.util.function.Consumer;
-import javax.annotation.Nullable;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
import static org.sonar.db.measure.MeasureTesting.newLiveMeasure;
import static org.sonar.db.measure.MeasureTesting.newMeasureDto;
-import static org.sonar.db.measure.custom.CustomMeasureTesting.newCustomMeasureDto;
import static org.sonar.db.metric.MetricTesting.newMetricDto;
public class MeasureDbTester {
return dto;
}
- @SafeVarargs
- public final CustomMeasureDto insertCustomMeasure(@Nullable UserDto user, ComponentDto component, MetricDto metricDto, Consumer<CustomMeasureDto>... consumers) {
- Preconditions.checkArgument(metricDto.isUserManaged(),"Custom measure must be created from a custom metric");
- CustomMeasureDto dto = newCustomMeasureDto()
- .setComponentUuid(component.uuid())
- .setMetricUuid(metricDto.getUuid());
- if (user != null) {
- dto.setUserUuid(user.getUuid());
- }
- Arrays.stream(consumers).forEach(c -> c.accept(dto));
- dbClient.customMeasureDao().insert(dbSession, dto);
- dbSession.commit();
- return dto;
- }
-
@SafeVarargs
public final MetricDto insertMetric(Consumer<MetricDto>... consumers) {
MetricDto metricDto = newMetricDto();
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.db.measure.custom;
-
-import org.apache.commons.lang.RandomStringUtils;
-import org.apache.commons.lang.math.RandomUtils;
-import org.sonar.api.utils.System2;
-import org.sonar.core.util.Uuids;
-
-public class CustomMeasureTesting {
- private CustomMeasureTesting() {
- // static stuff only
- }
-
- public static CustomMeasureDto newCustomMeasureDto() {
- return new CustomMeasureDto()
- .setUuid(Uuids.createFast())
- .setDescription(RandomStringUtils.randomAlphanumeric(255))
- .setTextValue(RandomStringUtils.randomAlphanumeric(255))
- .setUserUuid("userUuid" + RandomStringUtils.randomAlphanumeric(100))
- .setValue(RandomUtils.nextDouble())
- .setMetricUuid(RandomStringUtils.randomAlphanumeric(40))
- .setComponentUuid(RandomStringUtils.randomAlphanumeric(50))
- .setCreatedAt(System2.INSTANCE.now())
- .setUpdatedAt(System2.INSTANCE.now());
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.System2;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.user.UserSession;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
-import static org.sonar.server.component.ComponentFinder.ParamNames.PROJECT_ID_AND_KEY;
-import static org.sonar.server.exceptions.BadRequestException.checkRequest;
-import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions;
-import static org.sonar.server.measure.custom.ws.CustomMeasureValueDescription.measureValueDescription;
-import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
-
-public class CreateAction implements CustomMeasuresWsAction {
- public static final String ACTION = "create";
- public static final String PARAM_PROJECT_ID = "projectId";
- public static final String PARAM_PROJECT_KEY = "projectKey";
- public static final String PARAM_METRIC_ID = "metricId";
- public static final String PARAM_METRIC_KEY = "metricKey";
- public static final String PARAM_VALUE = "value";
- public static final String PARAM_DESCRIPTION = "description";
-
- private final DbClient dbClient;
- private final UserSession userSession;
- private final System2 system;
- private final CustomMeasureValidator validator;
- private final CustomMeasureJsonWriter customMeasureJsonWriter;
- private final ComponentFinder componentFinder;
-
- public CreateAction(DbClient dbClient, UserSession userSession, System2 system, CustomMeasureValidator validator, CustomMeasureJsonWriter customMeasureJsonWriter,
- ComponentFinder componentFinder) {
- this.dbClient = dbClient;
- this.userSession = userSession;
- this.system = system;
- this.validator = validator;
- this.customMeasureJsonWriter = customMeasureJsonWriter;
- this.componentFinder = componentFinder;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION)
- .setDescription("Create a custom measure.<br /> " +
- "The project id or the project key must be provided (only project and module custom measures can be created). The metric id or the metric key must be provided.<br/>" +
- "Requires 'Administer' permission on the project.")
- .setSince("5.2")
- .setDeprecatedSince("7.4")
- .setPost(true)
- .setHandler(this)
- .setChangelog(
- new Change("8.4", "Param 'metricId' data type changes from integer to string."));
-
- action.createParam(PARAM_PROJECT_ID)
- .setDescription("Project id")
- .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
-
- action.createParam(PARAM_PROJECT_KEY)
- .setDescription("Project key")
- .setExampleValue(KEY_PROJECT_EXAMPLE_001);
-
- action.createParam(PARAM_METRIC_ID)
- .setDescription("Metric uuid")
- .setExampleValue(UUID_EXAMPLE_01);
-
- action.createParam(PARAM_METRIC_KEY)
- .setDescription("Metric key")
- .setExampleValue("ncloc");
-
- action.createParam(PARAM_VALUE)
- .setRequired(true)
- .setDescription(measureValueDescription())
- .setExampleValue("47");
-
- action.createParam(PARAM_DESCRIPTION)
- .setDescription("Description")
- .setExampleValue("Team size growing.");
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- String valueAsString = request.mandatoryParam(PARAM_VALUE);
- String description = request.param(PARAM_DESCRIPTION);
- long now = system.now();
-
- try (DbSession dbSession = dbClient.openSession(false)) {
- ComponentDto component = componentFinder.getByUuidOrKey(dbSession, request.param(PARAM_PROJECT_ID), request.param(PARAM_PROJECT_KEY), PROJECT_ID_AND_KEY);
- MetricDto metric = searchMetric(dbSession, request);
- checkPermissions(userSession, component);
- checkIsProjectOrModule(component);
- checkMeasureDoesNotExistAlready(dbSession, component, metric);
- String userUuid = requireNonNull(userSession.getUuid(), "User uuid should not be null");
- UserDto user = dbClient.userDao().selectByUuid(dbSession, userUuid);
- checkState(user != null, "User with uuid '%s' does not exist", userUuid);
- CustomMeasureDto measure = new CustomMeasureDto()
- .setComponentUuid(component.uuid())
- .setMetricUuid(metric.getUuid())
- .setDescription(description)
- .setUserUuid(user.getUuid())
- .setCreatedAt(now)
- .setUpdatedAt(now);
- validator.setMeasureValue(measure, valueAsString, metric);
- dbClient.customMeasureDao().insert(dbSession, measure);
- dbSession.commit();
-
- JsonWriter json = response.newJsonWriter();
- customMeasureJsonWriter.write(json, measure, metric, component, user, true, CustomMeasureJsonWriter.OPTIONAL_FIELDS);
- json.close();
- }
- }
-
- private static void checkIsProjectOrModule(ComponentDto component) {
- checkRequest(Scopes.PROJECT.equals(component.scope()), "Component '%s' must be a project or a module.", component.getDbKey());
- }
-
- private void checkMeasureDoesNotExistAlready(DbSession dbSession, ComponentDto component, MetricDto metric) {
- int nbMeasuresOnSameMetricAndMeasure = dbClient.customMeasureDao().countByComponentIdAndMetricUuid(dbSession, component.uuid(), metric.getUuid());
- checkRequest(nbMeasuresOnSameMetricAndMeasure == 0,
- "A measure already exists for project '%s' and metric '%s'",
- component.getDbKey(), metric.getKey());
- }
-
- private MetricDto searchMetric(DbSession dbSession, Request request) {
- String metricUuid = request.param(PARAM_METRIC_ID);
- String metricKey = request.param(PARAM_METRIC_KEY);
- checkArgument(metricUuid != null ^ metricKey != null, "Either the metric uuid or the metric key must be provided");
-
- if (metricUuid == null) {
- MetricDto metric = dbClient.metricDao().selectByKey(dbSession, metricKey);
- checkArgument(metric != null, "Metric with key '%s' does not exist", metricKey);
- return metric;
- }
- MetricDto metric = dbClient.metricDao().selectByUuid(dbSession, metricUuid);
- checkArgument(metric != null, "Metric with uuid '%s' does not exist", metricUuid);
- return metric;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Set;
-import javax.annotation.Nullable;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.metric.ws.MetricJsonWriter;
-import org.sonar.server.user.ws.UserJsonWriter;
-
-import static org.sonar.server.ws.JsonWriterUtils.isFieldNeeded;
-import static org.sonar.server.ws.JsonWriterUtils.writeIfNeeded;
-
-public class CustomMeasureJsonWriter {
- private static final String FIELD_ID = "id";
- private static final String FIELD_PROJECT_ID = "projectId";
- private static final String FIELD_PROJECT_KEY = "projectKey";
- private static final String FIELD_VALUE = "value";
- private static final String FIELD_DESCRIPTION = "description";
- private static final String FIELD_METRIC = "metric";
- private static final String FIELD_CREATED_AT = "createdAt";
- private static final String FIELD_UPDATED_AT = "updatedAt";
- private static final String FIELD_USER = "user";
- private static final String FIELD_PENDING = "pending";
-
- public static final Set<String> OPTIONAL_FIELDS = ImmutableSet.of(FIELD_PROJECT_ID, FIELD_PROJECT_KEY, FIELD_VALUE, FIELD_DESCRIPTION, FIELD_METRIC, FIELD_CREATED_AT,
- FIELD_UPDATED_AT, FIELD_USER, FIELD_PENDING);
-
- private final UserJsonWriter userJsonWriter;
-
- public CustomMeasureJsonWriter(UserJsonWriter userJsonWriter) {
- this.userJsonWriter = userJsonWriter;
- }
-
- public void write(JsonWriter json, CustomMeasureDto measure, MetricDto metric, ComponentDto component, UserDto user, boolean isPending,
- @Nullable Collection<String> fieldsToReturn) {
- json.beginObject();
- json.prop(FIELD_ID, String.valueOf(measure.getUuid()));
- writeIfNeeded(json, measureValue(measure, metric), FIELD_VALUE, fieldsToReturn);
- writeIfNeeded(json, measure.getDescription(), FIELD_DESCRIPTION, fieldsToReturn);
- if (isFieldNeeded(FIELD_METRIC, fieldsToReturn)) {
- json.name(FIELD_METRIC);
- MetricJsonWriter.write(json, metric, MetricJsonWriter.MANDATORY_FIELDS);
- }
- writeIfNeeded(json, component.uuid(), FIELD_PROJECT_ID, fieldsToReturn);
- writeIfNeeded(json, component.getDbKey(), FIELD_PROJECT_KEY, fieldsToReturn);
- writeIfNeeded(json, new Date(measure.getCreatedAt()), FIELD_CREATED_AT, fieldsToReturn);
- writeIfNeeded(json, new Date(measure.getUpdatedAt()), FIELD_UPDATED_AT, fieldsToReturn);
- writeIfNeeded(json, isPending, FIELD_PENDING, fieldsToReturn);
-
- if (isFieldNeeded(FIELD_USER, fieldsToReturn)) {
- json.name(FIELD_USER);
- userJsonWriter.write(json, user);
- }
-
- json.endObject();
- }
-
- private static String measureValue(CustomMeasureDto measure, MetricDto metric) {
- Metric.ValueType metricType = Metric.ValueType.valueOf(metric.getValueType());
- double doubleValue = measure.getValue();
- String stringValue = measure.getTextValue();
-
- switch (metricType) {
- case BOOL:
- return Double.compare(doubleValue, 1.0D) == 0 ? "true" : "false";
- case INT:
- case MILLISEC:
- return String.valueOf((int) doubleValue);
- case WORK_DUR:
- case FLOAT:
- case PERCENT:
- case RATING:
- return String.valueOf(doubleValue);
- case LEVEL:
- case STRING:
- case DATA:
- case DISTRIB:
- return stringValue;
- default:
- throw new IllegalArgumentException("Unsupported metric type: " + metricType.name());
- }
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.sonar.api.PropertyType;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.server.ServerSide;
-import org.sonar.api.web.UserRole;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.server.user.UserSession;
-import org.sonar.server.util.TypeValidations;
-
-@ServerSide
-public class CustomMeasureValidator {
- private final TypeValidations typeValidations;
-
- public CustomMeasureValidator(TypeValidations typeValidations) {
- this.typeValidations = typeValidations;
- }
-
- public void setMeasureValue(CustomMeasureDto measure, String valueAsString, MetricDto metric) {
- Metric.ValueType metricType = Metric.ValueType.valueOf(metric.getValueType());
- switch (metricType) {
- case BOOL:
- checkAndSetBooleanMeasureValue(measure, valueAsString);
- break;
- case INT:
- case MILLISEC:
- checkAndSetIntegerMeasureValue(measure, valueAsString);
- break;
- case WORK_DUR:
- checkAndSetLongMeasureValue(measure, valueAsString);
- break;
- case FLOAT:
- case PERCENT:
- case RATING:
- checkAndSetFloatMeasureValue(measure, valueAsString);
- break;
- case LEVEL:
- checkAndSetLevelMeasureValue(measure, valueAsString);
- break;
- case STRING:
- case DATA:
- case DISTRIB:
- measure.setTextValue(valueAsString);
- break;
- default:
- throw new IllegalArgumentException("Unsupported metric type:" + metricType.name());
- }
- }
-
- private void checkAndSetLevelMeasureValue(CustomMeasureDto measure, String valueAsString) {
- typeValidations.validate(valueAsString, PropertyType.METRIC_LEVEL.name(), null);
- measure.setTextValue(valueAsString);
- }
-
- private void checkAndSetFloatMeasureValue(CustomMeasureDto measure, String valueAsString) {
- typeValidations.validate(valueAsString, PropertyType.FLOAT.name(), null);
- measure.setValue(Double.parseDouble(valueAsString));
- }
-
- private void checkAndSetLongMeasureValue(CustomMeasureDto measure, String valueAsString) {
- typeValidations.validate(valueAsString, PropertyType.LONG.name(), null);
- measure.setValue(Long.parseLong(valueAsString));
- }
-
- private void checkAndSetIntegerMeasureValue(CustomMeasureDto measure, String valueAsString) {
- typeValidations.validate(valueAsString, PropertyType.INTEGER.name(), null);
- measure.setValue(Integer.parseInt(valueAsString));
- }
-
- private void checkAndSetBooleanMeasureValue(CustomMeasureDto measure, String valueAsString) {
- typeValidations.validate(valueAsString, PropertyType.BOOLEAN.name(), null);
- measure.setValue(Boolean.parseBoolean(valueAsString) ? 1.0d : 0.0d);
- }
-
- public static void checkPermissions(UserSession userSession, ComponentDto component) {
- userSession.checkLoggedIn().checkComponentPermission(UserRole.ADMIN, component);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import com.google.common.base.Joiner;
-import org.sonar.api.measures.Metric;
-
-class CustomMeasureValueDescription {
- private CustomMeasureValueDescription() {
- // utility class
- }
-
- static String measureValueDescription() {
- StringBuilder description = new StringBuilder("Measure value. Value type depends on metric type:");
- description.append("<ul>");
- for (Metric.ValueType metricType : Metric.ValueType.values()) {
- description.append("<li>");
- description.append(String.format("%s - %s", metricType.name(), metricTypeWsDescription(metricType)));
- description.append("</li>");
- }
- description.append("</ul>");
-
- return description.toString();
- }
-
- private static String metricTypeWsDescription(Metric.ValueType metricType) {
- switch (metricType) {
- case BOOL:
- return "the possible values are true or false";
- case INT:
- case MILLISEC:
- return "type: integer";
- case FLOAT:
- case PERCENT:
- case RATING:
- return "type: double";
- case LEVEL:
- return "the possible values are " + formattedMetricLevelNames();
- case STRING:
- case DATA:
- case DISTRIB:
- return "type: string";
- case WORK_DUR:
- return "long representing the number of minutes";
- default:
- return "metric type not supported";
- }
- }
-
- private static String formattedMetricLevelNames() {
- return Joiner.on(", ").join(Metric.Level.names());
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.sonar.api.server.ws.WebService;
-
-public class CustomMeasuresWs implements WebService {
- public static final String ENDPOINT = "api/custom_measures";
-
- private final CustomMeasuresWsAction[] actions;
-
- public CustomMeasuresWs(CustomMeasuresWsAction... actions) {
- this.actions = actions;
- }
-
- @Override
- public void define(Context context) {
- NewController controller = context.createController(ENDPOINT)
- .setDescription("Manage custom measures for a project. See also api/metrics.<br/>" +
- "Custom measures are deprecated. Please use projects tags instead.")
- .setSince("5.2");
-
- for (CustomMeasuresWsAction action : actions) {
- action.define(controller);
- }
-
- controller.done();
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.sonar.server.ws.WsAction;
-
-public interface CustomMeasuresWsAction extends WsAction {
- // marker interface
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.sonar.core.platform.Module;
-
-public class CustomMeasuresWsModule extends Module {
- @Override
- protected void configureModule() {
- add(
- CustomMeasuresWs.class,
- CreateAction.class,
- UpdateAction.class,
- DeleteAction.class,
- SearchAction.class,
- MetricsAction.class,
- CustomMeasureJsonWriter.class,
- CustomMeasureValidator.class);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.util.Uuids;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.server.user.UserSession;
-
-import static java.lang.String.format;
-
-public class DeleteAction implements CustomMeasuresWsAction {
-
- private static final String ACTION = "delete";
- public static final String PARAM_ID = "id";
-
- private final DbClient dbClient;
- private final UserSession userSession;
-
- public DeleteAction(DbClient dbClient, UserSession userSession) {
- this.dbClient = dbClient;
- this.userSession = userSession;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION)
- .setPost(true)
- .setHandler(this)
- .setSince("5.2")
- .setDeprecatedSince("7.4")
- .setDescription("Delete a custom measure.<br /> Requires 'Administer System' permission or 'Administer' permission on the project.")
- .setChangelog(
- new Change("8.4", "Param 'id' data type changes from integer to string."));
-
- action.createParam(PARAM_ID)
- .setDescription("id")
- .setExampleValue(Uuids.UUID_EXAMPLE_01)
- .setRequired(true);
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- String id = request.mandatoryParam(PARAM_ID);
-
- try (DbSession dbSession = dbClient.openSession(false)) {
- CustomMeasureDto customMeasure = dbClient.customMeasureDao().selectByUuid(dbSession, id)
- .orElseThrow(() -> new IllegalArgumentException(format("Custom measure with id '%s' does not exist", id)));
- checkPermission(dbSession, customMeasure);
- dbClient.customMeasureDao().delete(dbSession, id);
- dbSession.commit();
- }
-
- response.noContent();
- }
-
- private void checkPermission(DbSession dbSession, CustomMeasureDto customMeasure) {
- userSession.checkLoggedIn();
-
- ComponentDto component = dbClient.componentDao().selectOrFailByUuid(dbSession, customMeasure.getComponentUuid());
- userSession.checkComponentPermission(UserRole.ADMIN, component);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import com.google.common.io.Resources;
-import java.util.List;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.metric.ws.MetricJsonWriter;
-import org.sonar.server.user.UserSession;
-
-import static org.sonar.server.component.ComponentFinder.ParamNames.PROJECT_ID_AND_KEY;
-import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions;
-import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
-
-public class MetricsAction implements CustomMeasuresWsAction {
- public static final String ACTION = "metrics";
- public static final String PARAM_PROJECT_ID = "projectId";
- public static final String PARAM_PROJECT_KEY = "projectKey";
-
- private final DbClient dbClient;
- private final UserSession userSession;
- private final ComponentFinder componentFinder;
-
- public MetricsAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) {
- this.dbClient = dbClient;
- this.userSession = userSession;
- this.componentFinder = componentFinder;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION)
- .setSince("5.2")
- .setDeprecatedSince("7.4")
- .setInternal(true)
- .setHandler(this)
- .setResponseExample(Resources.getResource(getClass(), "example-metrics.json"))
- .setDescription("List all custom metrics for which no custom measure already exists on a given project.<br /> " +
- "The project id or project key must be provided.<br />" +
- "Requires 'Administer System' permission or 'Administer' permission on the project.");
-
- action.createParam(PARAM_PROJECT_ID)
- .setDescription("Project id")
- .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
-
- action.createParam(PARAM_PROJECT_KEY)
- .setDescription("Project key")
- .setExampleValue(KEY_PROJECT_EXAMPLE_001);
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- try (DbSession dbSession = dbClient.openSession(false)) {
- ComponentDto project = componentFinder.getByUuidOrKey(dbSession, request.param(CreateAction.PARAM_PROJECT_ID), request.param(CreateAction.PARAM_PROJECT_KEY),
- PROJECT_ID_AND_KEY);
- checkPermissions(userSession, project);
- List<MetricDto> metrics = searchMetrics(dbSession, project);
-
- writeResponse(response, metrics);
- }
- }
-
- private static void writeResponse(Response response, List<MetricDto> metrics) {
- JsonWriter json = response.newJsonWriter();
- json.beginObject();
- MetricJsonWriter.write(json, metrics, MetricJsonWriter.ALL_FIELDS);
- json.endObject();
- json.close();
- }
-
- private List<MetricDto> searchMetrics(DbSession dbSession, ComponentDto project) {
- return dbClient.metricDao().selectAvailableCustomMetricsByComponentUuid(dbSession, project.uuid());
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.core.util.stream.MoreCollectors;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.SnapshotDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.user.UserSession;
-
-import static org.sonar.server.component.ComponentFinder.ParamNames.PROJECT_ID_AND_KEY;
-import static org.sonar.server.es.SearchOptions.MAX_PAGE_SIZE;
-import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions;
-import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
-
-public class SearchAction implements CustomMeasuresWsAction {
-
- public static final String ACTION = "search";
- public static final String PARAM_PROJECT_ID = "projectId";
- public static final String PARAM_PROJECT_KEY = "projectKey";
-
- private final DbClient dbClient;
- private final CustomMeasureJsonWriter customMeasureJsonWriter;
- private final UserSession userSession;
- private final ComponentFinder componentFinder;
-
- public SearchAction(DbClient dbClient, CustomMeasureJsonWriter customMeasureJsonWriter, UserSession userSession, ComponentFinder componentFinder) {
- this.dbClient = dbClient;
- this.customMeasureJsonWriter = customMeasureJsonWriter;
- this.userSession = userSession;
- this.componentFinder = componentFinder;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION)
- .setDescription("List custom measures. The project id or project key must be provided.<br />" +
- "Requires 'Administer System' permission or 'Administer' permission on the project.")
- .setSince("5.2")
- .setDeprecatedSince("7.4")
- .addFieldsParam(CustomMeasureJsonWriter.OPTIONAL_FIELDS)
- .addPagingParams(100, MAX_PAGE_SIZE)
- .setResponseExample(getClass().getResource("example-search.json"))
- .setHandler(this);
-
- action.createParam(PARAM_PROJECT_ID)
- .setDescription("Project id")
- .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
-
- action.createParam(PARAM_PROJECT_KEY)
- .setDescription("Project key")
- .setExampleValue(KEY_PROJECT_EXAMPLE_001);
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- String projectUuid = request.param(PARAM_PROJECT_ID);
- String projectKey = request.param(PARAM_PROJECT_KEY);
- List<String> fieldsToReturn = request.paramAsStrings(WebService.Param.FIELDS);
- SearchOptions searchOptions = new SearchOptions()
- .setPage(request.mandatoryParamAsInt(WebService.Param.PAGE),
- request.mandatoryParamAsInt(WebService.Param.PAGE_SIZE));
-
- try (DbSession dbSession = dbClient.openSession(false)) {
- ComponentDto component = componentFinder.getByUuidOrKey(dbSession, projectUuid, projectKey, PROJECT_ID_AND_KEY);
- checkPermissions(userSession, component);
- Long lastAnalysisDateMs = searchLastSnapshotDate(dbSession, component);
- List<CustomMeasureDto> customMeasures = searchCustomMeasures(dbSession, component, searchOptions);
- int nbCustomMeasures = countTotalOfCustomMeasures(dbSession, component);
- Map<String, UserDto> usersByUuid = usersByUuid(dbSession, customMeasures);
- Map<String, MetricDto> metricsByUuid = metricsByUuid(dbSession, customMeasures);
-
- writeResponse(response, customMeasures, nbCustomMeasures, component, metricsByUuid, usersByUuid, lastAnalysisDateMs, searchOptions, fieldsToReturn);
- }
- }
-
- @CheckForNull
- private Long searchLastSnapshotDate(DbSession dbSession, ComponentDto component) {
- Optional<SnapshotDto> lastSnapshot = dbClient.snapshotDao().selectLastAnalysisByComponentUuid(dbSession, component.projectUuid());
-
- return lastSnapshot.isPresent() ? lastSnapshot.get().getBuildDate() : null;
- }
-
- private int countTotalOfCustomMeasures(DbSession dbSession, ComponentDto project) {
- return dbClient.customMeasureDao().countByComponentUuid(dbSession, project.uuid());
- }
-
- private List<CustomMeasureDto> searchCustomMeasures(DbSession dbSession, ComponentDto project, SearchOptions searchOptions) {
- return dbClient.customMeasureDao().selectByComponentUuid(dbSession, project.uuid(), searchOptions.getOffset(), searchOptions.getLimit());
- }
-
- private void writeResponse(Response response, List<CustomMeasureDto> customMeasures, int nbCustomMeasures, ComponentDto project, Map<String, MetricDto> metricsByUuid,
- Map<String, UserDto> usersByUuid, @Nullable Long lastAnalysisDate, SearchOptions searchOptions, @Nullable List<String> fieldsToReturn) {
- JsonWriter json = response.newJsonWriter();
- json.beginObject();
- writeUsers(json, customMeasures, project, metricsByUuid, usersByUuid, lastAnalysisDate, fieldsToReturn);
- searchOptions.writeJson(json, nbCustomMeasures);
- json.endObject();
- json.close();
- }
-
- private void writeUsers(JsonWriter json, List<CustomMeasureDto> customMeasures, ComponentDto project, Map<String, MetricDto> metricsByUuid, Map<String, UserDto> usersByUuids,
- @Nullable Long lastAnalysisTimestamp, @Nullable Collection<String> fieldsToReturn) {
- json.name("customMeasures");
- json.beginArray();
- for (CustomMeasureDto customMeasure : customMeasures) {
- boolean pending = lastAnalysisTimestamp == null || lastAnalysisTimestamp < customMeasure.getUpdatedAt();
- customMeasureJsonWriter.write(json, customMeasure, metricsByUuid.get(customMeasure.getMetricUuid()), project, usersByUuids.get(customMeasure.getUserUuid()), pending,
- fieldsToReturn);
- }
- json.endArray();
- }
-
- private Map<String, MetricDto> metricsByUuid(DbSession dbSession, List<CustomMeasureDto> customMeasures) {
- Set<String> uuids = customMeasures.stream().map(CustomMeasureDto::getMetricUuid).collect(Collectors.toSet());
- List<MetricDto> metrics = dbClient.metricDao().selectByUuids(dbSession, uuids);
- return metrics.stream().collect(Collectors.toMap(MetricDto::getUuid, m -> m));
- }
-
- private Map<String, UserDto> usersByUuid(DbSession dbSession, List<CustomMeasureDto> customMeasures) {
- Set<String> userUuids = customMeasures.stream().map(CustomMeasureDto::getUserUuid).collect(MoreCollectors.toSet());
- List<UserDto> users = dbClient.userDao().selectByUuids(dbSession, userUuids);
- return users.stream().collect(MoreCollectors.uniqueIndex(UserDto::getUuid));
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import javax.annotation.Nullable;
-import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.System2;
-import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.core.util.Uuids;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.user.UserSession;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions;
-import static org.sonar.server.measure.custom.ws.CustomMeasureValueDescription.measureValueDescription;
-
-public class UpdateAction implements CustomMeasuresWsAction {
- public static final String ACTION = "update";
- public static final String PARAM_ID = "id";
- public static final String PARAM_VALUE = "value";
- public static final String PARAM_DESCRIPTION = "description";
-
- private final DbClient dbClient;
- private final UserSession userSession;
- private final System2 system;
- private final CustomMeasureValidator validator;
- private final CustomMeasureJsonWriter customMeasureJsonWriter;
-
- public UpdateAction(DbClient dbClient, UserSession userSession, System2 system, CustomMeasureValidator validator, CustomMeasureJsonWriter customMeasureJsonWriter) {
- this.dbClient = dbClient;
- this.userSession = userSession;
- this.system = system;
- this.validator = validator;
- this.customMeasureJsonWriter = customMeasureJsonWriter;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION)
- .setPost(true)
- .setDescription("Update a custom measure. Value and/or description must be provided<br />" +
- "Requires 'Administer System' permission or 'Administer' permission on the project.")
- .setHandler(this)
- .setSince("5.2")
- .setDeprecatedSince("7.4")
- .setChangelog(
- new Change("8.4", "Param 'id' data type changes from integer to string."));
-
- action.createParam(PARAM_ID)
- .setRequired(true)
- .setDescription("id")
- .setExampleValue(Uuids.UUID_EXAMPLE_01);
-
- action.createParam(PARAM_VALUE)
- .setExampleValue("true")
- .setDescription(measureValueDescription());
-
- action.createParam(PARAM_DESCRIPTION)
- .setExampleValue("Team size growing.");
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- String uuid = request.mandatoryParam(PARAM_ID);
- String value = request.param(PARAM_VALUE);
- String description = request.param(PARAM_DESCRIPTION);
- checkParameters(value, description);
-
- try (DbSession dbSession = dbClient.openSession(true)) {
- CustomMeasureDto customMeasure = dbClient.customMeasureDao().selectByUuid(dbSession, uuid)
- .orElseThrow(() -> new IllegalArgumentException(format("Custom measure with id '%s' does not exist", uuid)));
- String customMetricUuid = customMeasure.getMetricUuid();
- MetricDto metric = dbClient.metricDao().selectByUuid(dbSession, customMetricUuid);
- checkState(metric != null, "Metric with uuid '%s' does not exist", customMetricUuid);
- ComponentDto component = dbClient.componentDao().selectOrFailByUuid(dbSession, customMeasure.getComponentUuid());
- checkPermissions(userSession, component);
- String userUuid = requireNonNull(userSession.getUuid(), "User uuid should not be null");
- UserDto user = dbClient.userDao().selectByUuid(dbSession, userUuid);
- checkState(user != null, "User with uuid '%s' does not exist", userUuid);
-
- setValue(customMeasure, value, metric);
- setDescription(customMeasure, description);
- customMeasure.setUserUuid(user.getUuid());
- customMeasure.setUpdatedAt(system.now());
- dbClient.customMeasureDao().update(dbSession, customMeasure);
- dbSession.commit();
-
- JsonWriter json = response.newJsonWriter();
- customMeasureJsonWriter.write(json, customMeasure, metric, component, user, true, CustomMeasureJsonWriter.OPTIONAL_FIELDS);
- json.close();
- }
- }
-
- private void setValue(CustomMeasureDto customMeasure, @Nullable String value, MetricDto metric) {
- if (value != null) {
- validator.setMeasureValue(customMeasure, value, metric);
- }
- }
-
- private static void setDescription(CustomMeasureDto customMeasure, @Nullable String description) {
- if (description != null) {
- customMeasure.setDescription(description);
- }
- }
-
- private static void checkParameters(@Nullable String value, @Nullable String description) {
- if (value == null && description == null) {
- throw new IllegalArgumentException("Value or description must be provided.");
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.server.measure.custom.ws;
-
-import javax.annotation.ParametersAreNonnullByDefault;
*/
package org.sonar.server.metric.ws;
-import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.measures.Metric;
import org.sonar.api.server.ws.Request;
import org.sonar.core.util.UuidFactory;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.measure.custom.CustomMeasureDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.server.user.UserSession;
}
checkRequest(!isMetricEnabled(metricInDb), "An active metric already exist with key: " + metricInDb.getKey());
checkRequest(!isMetricNonCustom(metricInDb), "An non custom metric already exist with key: %s", metricInDb.getKey());
- if (hasMetricTypeChanged(metricInDb, template)) {
- List<CustomMeasureDto> customMeasures = dbClient.customMeasureDao().selectByMetricUuid(dbSession, metricInDb.getUuid());
- checkRequest(!hasAssociatedCustomMeasures(customMeasures), "You're trying to change the type '%s' while there are associated measures.", metricInDb.getValueType());
- }
- }
-
- private static boolean hasAssociatedCustomMeasures(List<CustomMeasureDto> customMeasures) {
- return !customMeasures.isEmpty();
- }
-
- private static boolean hasMetricTypeChanged(MetricDto metricInDb, MetricDto template) {
- return !metricInDb.getValueType().equals(template.getValueType());
}
private static boolean isMetricNonCustom(MetricDto metricInDb) {
try (DbSession dbSession = dbClient.openSession(false)) {
List<String> uuids = loadUuids(dbSession, request);
dbClient.metricDao().disableCustomByUuids(dbSession, uuids);
- dbClient.customMeasureDao().deleteByMetricUuids(dbSession, uuids);
dbClient.gateConditionDao().deleteConditionsWithInvalidMetrics(dbSession);
dbSession.commit();
}
*/
package org.sonar.server.metric.ws;
-import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.measures.Metric;
import org.sonar.api.server.ws.Change;
import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.measure.custom.CustomMeasureDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.server.user.UserSession;
checkRequest(isMetricFoundInDb(metricInDb) && !isMetricDisabled(metricInDb) && isMetricCustom(metricInDb),
"No active custom metric has been found for uuid '%s'.", template.getUuid());
checkNoOtherMetricWithTargetKey(dbSession, metricInDb, template);
- if (haveMetricTypeChanged(metricInDb, template)) {
- List<CustomMeasureDto> customMeasures = dbClient.customMeasureDao().selectByMetricUuid(dbSession, metricInDb.getUuid());
- checkRequest(!haveAssociatedCustomMeasures(customMeasures), "You're trying to change the type '%s' while there are associated custom measures.", metricInDb.getValueType());
- }
}
private void checkNoOtherMetricWithTargetKey(DbSession dbSession, MetricDto metricInDb, MetricDto template) {
return metricInDb != null;
}
- private static boolean haveAssociatedCustomMeasures(List<CustomMeasureDto> customMeasures) {
- return !customMeasures.isEmpty();
- }
-
- private static boolean haveMetricTypeChanged(MetricDto metricInDb, MetricDto template) {
- return !metricInDb.getValueType().equals(template.getValueType()) && template.getValueType() != null;
- }
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.WebService.Action;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.component.TestComponentFinder;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.user.ws.UserJsonWriter;
-import org.sonar.server.ws.WsActionTester;
-
-import static java.lang.String.format;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.api.measures.Metric.ValueType.BOOL;
-import static org.sonar.api.measures.Metric.ValueType.FLOAT;
-import static org.sonar.api.measures.Metric.ValueType.INT;
-import static org.sonar.api.measures.Metric.ValueType.LEVEL;
-import static org.sonar.api.measures.Metric.ValueType.STRING;
-import static org.sonar.api.measures.Metric.ValueType.WORK_DUR;
-import static org.sonar.api.web.UserRole.ADMIN;
-import static org.sonar.db.component.ComponentTesting.newModuleDto;
-import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations;
-import static org.sonar.test.JsonAssert.assertJson;
-
-public class CreateActionTest {
-
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
- @Rule
- public EsTester es = EsTester.create();
-
- private final WsActionTester ws = new WsActionTester(
- new CreateAction(db.getDbClient(), userSession, System2.INSTANCE, new CustomMeasureValidator(newFullTypeValidations()),
- new CustomMeasureJsonWriter(new UserJsonWriter(userSession)), TestComponentFinder.from(db)));
-
- @Test
- public void verify_definition() {
- Action wsDef = ws.getDef();
-
- assertThat(wsDef.deprecatedSince()).isEqualTo("7.4");
- assertThat(wsDef.isInternal()).isFalse();
- assertThat(wsDef.since()).isEqualTo("5.2");
- assertThat(wsDef.isPost()).isTrue();
- assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly(
- tuple("8.4", "Param 'metricId' data type changes from integer to string."));
- }
-
- @Test
- public void create_boolean_custom_measure_in_db() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
- .setParam(CreateAction.PARAM_VALUE, "true")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple("custom-measure-description", null, 1d, project.uuid()));
- }
-
- @Test
- public void create_int_custom_measure_in_db() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(INT.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "42")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple(null, null, 42d, project.uuid()));
- }
-
- @Test
- public void create_text_custom_measure_in_db() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "custom-measure-free-text")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple(null, "custom-measure-free-text", 0d, project.uuid()));
- }
-
- @Test
- public void create_text_custom_measure_with_metric_key() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_KEY, metric.getKey())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple(null, "whatever-value", 0d, project.uuid()));
- }
-
- @Test
- public void create_text_custom_measure_with_project_key() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_KEY, project.getKey())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple(null, "whatever-value", 0d, project.uuid()));
- }
-
- @Test
- public void create_float_custom_measure_in_db() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(FLOAT.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "4.2")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple(null, null, 4.2d, project.uuid()));
- }
-
- @Test
- public void create_work_duration_custom_measure_in_db() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(WORK_DUR.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "253")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple(null, null, 253d, project.uuid()));
- }
-
- @Test
- public void create_level_type_custom_measure_in_db() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(LEVEL.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, Metric.Level.ERROR.name())
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple(null, Metric.Level.ERROR.name(), 0d, project.uuid()));
- }
-
- @Test
- public void response_with_object_and_id() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- String response = ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
- .setParam(CreateAction.PARAM_VALUE, "custom-measure-free-text")
- .execute()
- .getInput();
-
- CustomMeasureDto customMeasure = db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()).get(0);
- assertJson(response).isSimilarTo("{\n" +
- " \"id\": \"" + customMeasure.getUuid() + "\",\n" +
- " \"value\": \"custom-measure-free-text\",\n" +
- " \"description\": \"custom-measure-description\",\n" +
- " \"metric\": {\n" +
- " \"id\": \"" + metric.getUuid() + "\",\n" +
- " \"key\": \"" + metric.getKey() + "\",\n" +
- " \"type\": \"" + metric.getValueType() + "\",\n" +
- " \"name\": \"" + metric.getShortName() + "\",\n" +
- " \"domain\": \"" + metric.getDomain() + "\"\n" +
- " },\n" +
- " \"projectId\": \"" + project.uuid() + "\",\n" +
- " \"projectKey\": \"" + project.getKey() + "\",\n" +
- " \"pending\": true\n" +
- "}");
- }
-
- @Test
- public void create_custom_measure_on_module() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
- ComponentDto project = db.components().insertPrivateProject();
- ComponentDto module = db.components().insertComponent(newModuleDto(project));
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, module.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
- .setParam(CreateAction.PARAM_VALUE, "true")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple("custom-measure-description", null, 1d, module.uuid()));
- }
-
- @Test
- public void create_custom_measure_on_a_view() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
- ComponentDto view = db.components().insertPrivatePortfolio();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, view);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, view.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
- .setParam(CreateAction.PARAM_VALUE, "true")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple("custom-measure-description", null, 1d, view.uuid()));
- }
-
- @Test
- public void create_custom_measure_on_a_sub_view() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
- ComponentDto view = db.components().insertPrivatePortfolio();
- ComponentDto subView = db.components().insertSubView(view);
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, view);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, subView.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
- .setParam(CreateAction.PARAM_VALUE, "true")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
- .containsExactlyInAnyOrder(tuple("custom-measure-description", null, 1d, subView.uuid()));
- }
-
- @Test
- public void fail_when_project_id_nor_project_key_provided() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Either 'projectId' or 'projectKey' must be provided");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_METRIC_ID, "whatever-id")
- .setParam(CreateAction.PARAM_VALUE, metric.getUuid())
- .execute();
- }
-
- @Test
- public void fail_when_project_id_and_project_key_are_provided() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Either 'projectId' or 'projectKey' must be provided");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_PROJECT_KEY, project.getKey())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_project_key_does_not_exist_in_db() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(NotFoundException.class);
- expectedException.expectMessage("Component key 'another-project-key' not found");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_KEY, "another-project-key")
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_project_id_does_not_exist_in_db() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(NotFoundException.class);
- expectedException.expectMessage("Component id 'another-project-uuid' not found");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, "another-project-uuid")
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_metric_uuid_nor_metric_key_is_provided() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Either the metric uuid or the metric key must be provided");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_metric_uuid_and_metric_key_are_provided() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Either the metric uuid or the metric key must be provided");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_METRIC_KEY, metric.getKey())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_metric_key_is_not_found_in_db() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Metric with key 'unknown' does not exist");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_KEY, "unknown")
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_metric_uuid_is_not_found_in_db() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Metric with uuid '42' does not exist");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, "42")
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_measure_already_exists_on_same_project_and_same_metric() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userMeasureCreator = db.users().insertUser();
- db.measures().insertCustomMeasure(userMeasureCreator, project, metric);
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
-
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage(format("A measure already exists for project '%s' and metric '%s'", project.getKey(), metric.getKey()));
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_value_is_not_well_formatted() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Value 'non-correct-boolean-value' must be one of \"true\" or \"false\"");
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "non-correct-boolean-value")
- .execute();
- }
-
- @Test
- public void fail_when_system_administrator() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).setSystemAdministrator();
-
- expectedException.expect(ForbiddenException.class);
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-
- @Test
- public void fail_when_not_a_project() {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
- ComponentDto project = db.components().insertPrivateProject();
- ComponentDto directory = db.components().insertComponent(ComponentTesting.newDirectory(project, "dir"));
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage(format("Component '%s' must be a project or a module.", directory.getKey()));
-
- ws.newRequest()
- .setParam(CreateAction.PARAM_PROJECT_ID, directory.uuid())
- .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
- .setParam(CreateAction.PARAM_VALUE, "whatever-value")
- .execute();
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.assertj.core.data.Offset;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.db.measure.custom.CustomMeasureTesting;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.api.measures.Metric.Level.ERROR;
-import static org.sonar.api.measures.Metric.ValueType.BOOL;
-import static org.sonar.api.measures.Metric.ValueType.FLOAT;
-import static org.sonar.api.measures.Metric.ValueType.INT;
-import static org.sonar.api.measures.Metric.ValueType.LEVEL;
-import static org.sonar.api.measures.Metric.ValueType.STRING;
-import static org.sonar.api.measures.Metric.ValueType.WORK_DUR;
-import static org.sonar.db.metric.MetricTesting.newMetricDto;
-import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations;
-
-public class CustomMeasureValidatorTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- CustomMeasureValidator underTest = new CustomMeasureValidator(newFullTypeValidations());
- CustomMeasureDto customMeasure = CustomMeasureTesting.newCustomMeasureDto();
-
- @Test
- public void set_boolean_true_value() {
- underTest.setMeasureValue(customMeasure, "true", newMetricDto().setValueType(BOOL.name()));
-
- assertThat(customMeasure.getValue()).isCloseTo(1.0d, defaultOffset());
- }
-
- @Test
- public void set_boolean_false_value() {
- underTest.setMeasureValue(customMeasure, "false", newMetricDto().setValueType(BOOL.name()));
-
- assertThat(customMeasure.getValue()).isCloseTo(0.0d, defaultOffset());
- }
-
- @Test
- public void set_integer_value() {
- underTest.setMeasureValue(customMeasure, "1984", newMetricDto().setValueType(INT.name()));
-
- assertThat(customMeasure.getValue()).isCloseTo(1984d, defaultOffset());
- }
-
- @Test
- public void set_float_value() {
- underTest.setMeasureValue(customMeasure, "3.14", newMetricDto().setValueType(FLOAT.name()));
-
- assertThat(customMeasure.getValue()).isCloseTo(3.14d, defaultOffset());
- }
-
- @Test
- public void set_long_value() {
- underTest.setMeasureValue(customMeasure, "123456789", newMetricDto().setValueType(WORK_DUR.name()));
-
- assertThat(customMeasure.getValue()).isCloseTo(123456789d, defaultOffset());
- }
-
- @Test
- public void set_level_value() {
- underTest.setMeasureValue(customMeasure, ERROR.name(), newMetricDto().setValueType(LEVEL.name()));
-
- assertThat(customMeasure.getTextValue()).isEqualTo(ERROR.name());
- }
-
- @Test
- public void set_string_value() {
- underTest.setMeasureValue(customMeasure, "free-text-string", newMetricDto().setValueType(STRING.name()));
-
- assertThat(customMeasure.getTextValue()).isEqualTo("free-text-string");
- }
-
- @Test
- public void fail_when_non_compliant_value() {
- expectedException.expect(BadRequestException.class);
-
- underTest.setMeasureValue(customMeasure, "non-compliant-boolean-value", newMetricDto().setValueType(BOOL.name()));
- }
-
- @Test
- public void fail_when_non_compliant_level_value() {
- expectedException.expect(BadRequestException.class);
-
- underTest.setMeasureValue(customMeasure, "non-compliant-level-value", newMetricDto().setValueType(LEVEL.name()));
- }
-
- private Offset<Double> defaultOffset() {
- return Offset.offset(0.01d);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.junit.Test;
-import org.sonar.core.platform.ComponentContainer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class CustomMeasuresWsModuleTest {
- @Test
- public void verify_count_of_added_components() {
- ComponentContainer container = new ComponentContainer();
- new CustomMeasuresWsModule().configure(container);
- assertThat(container.size()).isEqualTo(10);
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.junit.Test;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class CustomMeasuresWsTest {
- private CustomMeasuresWs underTest = new CustomMeasuresWs(new CustomMeasuresWsAction() {
- @Override
- public void define(WebService.NewController context) {
- context.createAction("foo").setHandler(this);
- }
-
- @Override
- public void handle(Request request, Response response) {
-
- }
- });
-
- @Test
- public void define_ws() {
- WebService.Context context = new WebService.Context();
-
- underTest.define(context);
-
- WebService.Controller controller = context.controller("api/custom_measures");
- assertThat(controller).isNotNull();
- assertThat(controller.description()).isNotEmpty();
- assertThat(controller.actions()).hasSize(1);
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.WebService.Action;
-import org.sonar.api.utils.System2;
-import org.sonar.api.web.UserRole;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsActionTester;
-
-import static java.lang.String.valueOf;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.db.measure.custom.CustomMeasureTesting.newCustomMeasureDto;
-import static org.sonar.server.measure.custom.ws.DeleteAction.PARAM_ID;
-
-public class DeleteActionTest {
-
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
-
- private DbClient dbClient = db.getDbClient();
- private final DbSession dbSession = db.getSession();
- private DeleteAction underTest = new DeleteAction(dbClient, userSession);
- private WsActionTester ws = new WsActionTester(underTest);
-
- @Test
- public void verify_definition() {
- Action wsDef = ws.getDef();
-
- assertThat(wsDef.deprecatedSince()).isEqualTo("7.4");
- assertThat(wsDef.isInternal()).isFalse();
- assertThat(wsDef.since()).isEqualTo("5.2");
- assertThat(wsDef.isPost()).isTrue();
- assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly(
- tuple("8.4", "Param 'id' data type changes from integer to string."));
- }
-
- @Test
- public void project_administrator_can_delete_custom_measures() {
- ComponentDto project = db.components().insertPrivateProject();
- userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
- String id = insertCustomMeasure(project);
-
- ws.newRequest().setParam(PARAM_ID, valueOf(id)).execute();
-
- assertThat(dbClient.customMeasureDao().selectByUuid(dbSession, id)).isEmpty();
- }
-
- @Test
- public void throw_RowNotFoundException_if_id_does_not_exist() {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Custom measure with id '42' does not exist");
-
- ws.newRequest().setParam(PARAM_ID, "42").execute();
- }
-
- @Test
- public void throw_ForbiddenException_if_not_system_administrator() {
- ComponentDto project = db.components().insertPrivateProject();
- String uuid = insertCustomMeasure(project);
- userSession.logIn().setNonSystemAdministrator();
-
- expectedException.expect(ForbiddenException.class);
- ws.newRequest().setParam(PARAM_ID, valueOf(uuid)).execute();
- }
-
- @Test
- public void throw_UnauthorizedException_if_not_logged_in() {
- ComponentDto project = db.components().insertPrivateProject();
- String uuid = insertCustomMeasure(project);
- userSession.anonymous();
-
- expectedException.expect(UnauthorizedException.class);
- ws.newRequest().setParam(PARAM_ID, valueOf(uuid)).execute();
- }
-
- private String insertCustomMeasure(ComponentDto component) {
- CustomMeasureDto dto = newCustomMeasureDto().setComponentUuid(component.uuid());
- dbClient.customMeasureDao().insert(dbSession, dto);
- dbSession.commit();
- return dto.getUuid();
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.utils.System2;
-import org.sonar.api.web.UserRole;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.server.component.TestComponentFinder;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.TestResponse;
-import org.sonar.server.ws.WsActionTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.db.measure.custom.CustomMeasureTesting.newCustomMeasureDto;
-import static org.sonar.db.metric.MetricTesting.newMetricDto;
-
-public class MetricsActionTest {
- private static final String DEFAULT_PROJECT_UUID = "project-uuid";
- private static final String DEFAULT_PROJECT_KEY = "project-key";
-
- @Rule
- public EsTester es = EsTester.create();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
-
- private final DbClient dbClient = db.getDbClient();
- private final DbSession dbSession = db.getSession();
- private ComponentDto defaultProject;
- private final MetricsAction underTest = new MetricsAction(dbClient, userSession, TestComponentFinder.from(db));
- private final WsActionTester tester = new WsActionTester(underTest);
-
- @Before
- public void setUp() {
- defaultProject = insertDefaultProject();
- userSession.logIn().addProjectPermission(UserRole.ADMIN, defaultProject);
- }
-
- @Test
- public void list_metrics() {
- insertCustomMetric("metric-key-1");
- insertCustomMetric("metric-key-2");
- insertCustomMetric("metric-key-3");
-
- String response = newRequest().getInput();
-
- assertThat(response).contains("metric-key-1", "metric-key-2", "metric-key-3");
- }
-
- @Test
- public void list_metrics_active_and_custom_only() {
- insertCustomMetric("metric-key-1");
- dbClient.metricDao().insert(dbSession, newMetricDto().setEnabled(true).setUserManaged(false).setKey("metric-key-2"));
- dbClient.metricDao().insert(dbSession, newMetricDto().setEnabled(false).setUserManaged(true).setKey("metric-key-3"));
- dbSession.commit();
-
- String response = newRequest().getInput();
-
- assertThat(response).contains("metric-key-1")
- .doesNotContain("metric-key-2")
- .doesNotContain("metric-key-3");
- }
-
- @Test
- public void list_metrics_where_no_existing_custom_measure() {
- MetricDto metric = insertCustomMetric("metric-key-1");
- insertCustomMetric("metric-key-2");
- insertProject("project-uuid-2", "project-key-2");
-
- CustomMeasureDto customMeasure = newCustomMeasureDto()
- .setComponentUuid(defaultProject.uuid())
- .setMetricUuid(metric.getUuid());
- dbClient.customMeasureDao().insert(dbSession, customMeasure);
- dbSession.commit();
-
- String response = newRequest().getInput();
-
- assertThat(response).contains("metric-key-2")
- .doesNotContain("metric-key-1");
- }
-
- @Test
- public void list_metrics_based_on_project_key() {
- MetricDto metric = insertCustomMetric("metric-key-1");
- insertCustomMetric("metric-key-2");
- insertProject("project-uuid-2", "project-key-2");
-
- CustomMeasureDto customMeasure = newCustomMeasureDto()
- .setComponentUuid(defaultProject.uuid())
- .setMetricUuid(metric.getUuid());
- dbClient.customMeasureDao().insert(dbSession, customMeasure);
- dbSession.commit();
-
- String response = tester.newRequest()
- .setParam(MetricsAction.PARAM_PROJECT_KEY, DEFAULT_PROJECT_KEY)
- .execute().getInput();
-
- assertThat(response).contains("metric-key-2")
- .doesNotContain("metric-key-1");
- }
-
- @Test
- public void list_metrics_as_a_project_admin() {
- insertCustomMetric("metric-key-1");
- userSession.logIn("login").addProjectPermission(UserRole.ADMIN, defaultProject);
-
- String response = newRequest().getInput();
-
- assertThat(response).contains("metric-key-1");
- }
-
- @Test
- public void response_with_correct_formatting() {
- dbClient.metricDao().insert(dbSession, newCustomMetric("custom-key-1")
- .setShortName("custom-name-1")
- .setDescription("custom-description-1")
- .setDomain("custom-domain-1")
- .setValueType(Metric.ValueType.INT.name())
- .setDirection(1)
- .setQualitative(false)
- .setHidden(false));
- dbClient.metricDao().insert(dbSession, newCustomMetric("custom-key-2")
- .setShortName("custom-name-2")
- .setDescription("custom-description-2")
- .setDomain("custom-domain-2")
- .setValueType(Metric.ValueType.INT.name())
- .setDirection(-1)
- .setQualitative(true)
- .setHidden(true));
- dbClient.metricDao().insert(dbSession, newCustomMetric("custom-key-3")
- .setShortName("custom-name-3")
- .setDescription("custom-description-3")
- .setDomain("custom-domain-3")
- .setValueType(Metric.ValueType.INT.name())
- .setDirection(0)
- .setQualitative(false)
- .setHidden(false));
- dbSession.commit();
-
- TestResponse response = tester.newRequest()
- .setParam(MetricsAction.PARAM_PROJECT_ID, DEFAULT_PROJECT_UUID)
- .execute();
-
- response.assertJson(getClass(), "metrics.json");
- }
-
- @Test
- public void fail_if_project_id_nor_project_key_provided() {
- expectedException.expect(IllegalArgumentException.class);
-
- tester.newRequest().execute();
- }
-
- @Test
- public void fail_if_insufficient_privilege() {
- expectedException.expect(ForbiddenException.class);
- userSession.logIn("login");
-
- insertCustomMetric("metric-key-1");
-
- newRequest();
- }
-
- private TestResponse newRequest() {
- return tester.newRequest()
- .setParam(MetricsAction.PARAM_PROJECT_ID, DEFAULT_PROJECT_UUID)
- .execute();
- }
-
- private MetricDto insertCustomMetric(String metricKey) {
- MetricDto metric = newCustomMetric(metricKey);
- dbClient.metricDao().insert(dbSession, metric);
- dbSession.commit();
-
- return metric;
- }
-
- private static MetricDto newCustomMetric(String metricKey) {
- return newMetricDto().setEnabled(true).setUserManaged(true).setKey(metricKey);
- }
-
- private ComponentDto insertDefaultProject() {
- return insertProject(DEFAULT_PROJECT_UUID, DEFAULT_PROJECT_KEY);
- }
-
- private ComponentDto insertProject(String projectUuid, String projectKey) {
- ComponentDto project = ComponentTesting.newPrivateProjectDto(projectUuid)
- .setDbKey(projectKey);
- db.components().insertComponent(project);
- return project;
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.stream.IntStream;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.component.TestComponentFinder;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.user.ws.UserJsonWriter;
-import org.sonar.server.ws.WsActionTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.api.measures.Metric.ValueType.STRING;
-import static org.sonar.api.web.UserRole.ADMIN;
-import static org.sonar.api.web.UserRole.USER;
-import static org.sonar.test.JsonAssert.assertJson;
-
-public class SearchActionTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
- @Rule
- public EsTester es = EsTester.create();
-
- private WsActionTester ws = new WsActionTester(
- new SearchAction(db.getDbClient(), new CustomMeasureJsonWriter(new UserJsonWriter(userSession)), userSession, TestComponentFinder.from(db)));
-
- @Test
- public void json_well_formatted() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- UserDto userMeasureCreator = db.users().insertUser();
- MetricDto metric1 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- MetricDto metric2 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- MetricDto metric3 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- CustomMeasureDto customMeasure1 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric1, m -> m.setValue(0d));
- CustomMeasureDto customMeasure2 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric2, m -> m.setValue(0d));
- CustomMeasureDto customMeasure3 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric3, m -> m.setValue(0d));
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_ID, project.uuid())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"customMeasures\": [\n" +
- " {\n" +
- " \"id\": \"" + customMeasure1.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure1.getTextValue() + "\",\n" +
- " \"description\": \"" + customMeasure1.getDescription() + "\",\n" +
- " \"metric\": {\n" +
- " \"id\": \"" + metric1.getUuid() + "\",\n" +
- " \"key\": \"" + metric1.getKey() + "\",\n" +
- " \"type\": \"" + metric1.getValueType() + "\",\n" +
- " \"name\": \"" + metric1.getShortName() + "\",\n" +
- " \"domain\": \"" + metric1.getDomain() + "\"\n" +
- " },\n" +
- " \"projectId\": \"" + project.uuid() + "\",\n" +
- " \"projectKey\": \"" + project.getKey() + "\",\n" +
- " \"pending\": true,\n" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + customMeasure2.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure2.getTextValue() + "\",\n" +
- " \"description\": \"" + customMeasure2.getDescription() + "\",\n" +
- " \"metric\": {\n" +
- " \"id\": \"" + metric2.getUuid() + "\",\n" +
- " \"key\": \"" + metric2.getKey() + "\",\n" +
- " \"type\": \"" + metric2.getValueType() + "\",\n" +
- " \"name\": \"" + metric2.getShortName() + "\",\n" +
- " \"domain\": \"" + metric2.getDomain() + "\"\n" +
- " },\n" +
- " \"projectId\": \"" + project.uuid() + "\",\n" +
- " \"projectKey\": \"" + project.getKey() + "\",\n" +
- " \"pending\": true,\n" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + customMeasure3.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure3.getTextValue() + "\",\n" +
- " \"description\": \"" + customMeasure3.getDescription() + "\",\n" +
- " \"metric\": {\n" +
- " \"id\": \"" + metric3.getUuid() + "\",\n" +
- " \"key\": \"" + metric3.getKey() + "\",\n" +
- " \"type\": \"" + metric3.getValueType() + "\",\n" +
- " \"name\": \"" + metric3.getShortName() + "\",\n" +
- " \"domain\": \"" + metric3.getDomain() + "\"\n" +
- " },\n" +
- " \"projectId\": \"" + project.uuid() + "\",\n" +
- " \"projectKey\": \"" + project.getKey() + "\",\n" +
- " \"pending\": true,\n" +
- " }\n" +
- " ],\n" +
- " \"total\": 3,\n" +
- " \"p\": 1,\n" +
- " \"ps\": 100\n" +
- "}");
- }
-
- @Test
- public void return_users() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- UserDto user1 = db.users().insertUser();
- UserDto user2 = db.users().insertUser();
- MetricDto metric1 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- MetricDto metric2 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- MetricDto metric3 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- CustomMeasureDto customMeasure1 = db.measures().insertCustomMeasure(user1, project, metric1, m -> m.setValue(0d));
- CustomMeasureDto customMeasure2 = db.measures().insertCustomMeasure(user1, project, metric2, m -> m.setValue(0d));
- CustomMeasureDto customMeasure3 = db.measures().insertCustomMeasure(user2, project, metric3, m -> m.setValue(0d));
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_ID, project.uuid())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"customMeasures\": [\n" +
- " {\n" +
- " \"id\": \"" + customMeasure1.getUuid() + "\",\n" +
- " \"user\": {\n" +
- " \"login\": \"" + user1.getLogin() + "\",\n" +
- " \"name\": \"" + user1.getName() + "\",\n" +
- " \"email\": \"" + user1.getEmail() + "\",\n" +
- " \"active\": true\n" +
- " }" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + customMeasure2.getUuid() + "\",\n" +
- " \"user\": {\n" +
- " \"login\": \"" + user1.getLogin() + "\",\n" +
- " \"name\": \"" + user1.getName() + "\",\n" +
- " \"email\": \"" + user1.getEmail() + "\",\n" +
- " \"active\": true\n" +
- " }" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + customMeasure3.getUuid() + "\",\n" +
- " \"user\": {\n" +
- " \"login\": \"" + user2.getLogin() + "\",\n" +
- " \"name\": \"" + user2.getName() + "\",\n" +
- " \"email\": \"" + user2.getEmail() + "\",\n" +
- " \"active\": true\n" +
- " }" +
- " }\n" +
- " ]\n" +
- "}");
- }
-
- @Test
- public void search_by_project_uuid() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- UserDto userMeasureCreator = db.users().insertUser();
- MetricDto metric1 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- MetricDto metric2 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- MetricDto metric3 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- CustomMeasureDto customMeasure1 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric1, m -> m.setValue(0d));
- CustomMeasureDto customMeasure2 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric2, m -> m.setValue(0d));
- CustomMeasureDto customMeasure3 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric3, m -> m.setValue(0d));
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_ID, project.uuid())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"customMeasures\": [\n" +
- " {\n" +
- " \"id\": \"" + customMeasure1.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure1.getTextValue() + "\"\n" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + customMeasure2.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure2.getTextValue() + "\"\n" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + customMeasure3.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure3.getTextValue() + "\"\n" +
- " }\n" +
- " ],\n" +
- " \"total\": 3,\n" +
- " \"p\": 1,\n" +
- " \"ps\": 100\n" +
- "}");
- }
-
- @Test
- public void search_by_project_key() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- UserDto userMeasureCreator = db.users().insertUser();
- MetricDto metric1 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- MetricDto metric2 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- MetricDto metric3 = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- CustomMeasureDto customMeasure1 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric1, m -> m.setValue(0d));
- CustomMeasureDto customMeasure2 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric2, m -> m.setValue(0d));
- CustomMeasureDto customMeasure3 = db.measures().insertCustomMeasure(userMeasureCreator, project, metric3, m -> m.setValue(0d));
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_KEY, project.getKey())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"customMeasures\": [\n" +
- " {\n" +
- " \"id\": \"" + customMeasure1.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure1.getTextValue() + "\"\n" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + customMeasure2.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure2.getTextValue() + "\"\n" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + customMeasure3.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure3.getTextValue() + "\"\n" +
- " }\n" +
- " ],\n" +
- " \"total\": 3,\n" +
- " \"p\": 1,\n" +
- " \"ps\": 100\n" +
- "}");
- }
-
- @Test
- public void search_with_pagination() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- UserDto userMeasureCreator = db.users().insertUser();
- List<CustomMeasureDto> measureById = new ArrayList<>();
- IntStream.range(0, 10).forEach(i -> {
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true));
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(userMeasureCreator, project, metric);
- measureById.add(customMeasure);
- });
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_KEY, project.getKey())
- .setParam(WebService.Param.PAGE, "3")
- .setParam(WebService.Param.PAGE_SIZE, "4")
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"customMeasures\": [\n" +
- " {\n" +
- " \"id\": \"" + measureById.get(8).getUuid() + "\",\n" +
- " },\n" +
- " {\n" +
- " \"id\": \"" + measureById.get(9).getUuid() + "\",\n" +
- " },\n" +
- " ],\n" +
- " \"total\": 10,\n" +
- " \"p\": 3,\n" +
- " \"ps\": 4\n" +
- "}");
- }
-
- @Test
- public void search_with_selectable_fields() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- UserDto userMeasureCreator = db.users().insertUser();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- db.measures().insertCustomMeasure(userMeasureCreator, project, metric, m -> m.setValue(0d));
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_KEY, project.getKey())
- .setParam(WebService.Param.FIELDS, "value, description")
- .execute()
- .getInput();
-
- assertThat(response).contains("id", "value", "description")
- .doesNotContain("createdAt")
- .doesNotContain("updatedAt")
- .doesNotContain("user")
- .doesNotContain("metric");
- }
-
- @Test
- public void search_with_more_recent_analysis() {
- long yesterday = DateUtils.addDays(new Date(), -1).getTime();
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- UserDto userMeasureCreator = db.users().insertUser();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(userMeasureCreator, project, metric, m -> m.setCreatedAt(yesterday).setUpdatedAt(yesterday));
- db.components().insertSnapshot(project);
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_ID, project.uuid())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"customMeasures\": [\n" +
- " {\n" +
- " \"id\": \"" + customMeasure.getUuid() + "\",\n" +
- " \"value\": \"" + customMeasure.getTextValue() + "\",\n" +
- " \"pending\": false\n" +
- " },\n" +
- " ]\n" +
- "}");
- }
-
- @Test
- public void empty_json_when_no_measure() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_KEY, project.getKey())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"customMeasures\": [],\n" +
- " \"total\": 0,\n" +
- " \"p\": 1,\n" +
- " \"ps\": 100\n" +
- "}");
- }
-
- @Test
- public void fail_when_project_id_and_project_key_provided() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Either 'projectId' or 'projectKey' must be provided");
-
- ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_ID, project.uuid())
- .setParam(SearchAction.PARAM_PROJECT_KEY, project.getKey())
- .execute();
- }
-
- @Test
- public void fail_when_project_id_nor_project_key_provided() {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Either 'projectId' or 'projectKey' must be provided");
-
- ws.newRequest()
- .execute();
- }
-
- @Test
- public void fail_when_project_not_found_in_db() {
- expectedException.expect(NotFoundException.class);
- expectedException.expectMessage("Component id 'wrong-project-uuid' not found");
-
- ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_ID, "wrong-project-uuid")
- .execute();
- }
-
- @Test
- public void fail_when_not_enough_privileges() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(USER, project);
-
- expectedException.expect(ForbiddenException.class);
-
- String response = ws.newRequest()
- .setParam(SearchAction.PARAM_PROJECT_ID, project.uuid())
- .execute()
- .getInput();
-
- assertThat(response).contains("text-value-1");
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.custom.ws;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.impl.utils.TestSystem2;
-import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.WebService.Action;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.measure.custom.CustomMeasureDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.user.ws.UserJsonWriter;
-import org.sonar.server.ws.WsActionTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.api.measures.Metric.ValueType.INT;
-import static org.sonar.api.measures.Metric.ValueType.STRING;
-import static org.sonar.api.web.UserRole.ADMIN;
-import static org.sonar.api.web.UserRole.USER;
-import static org.sonar.server.measure.custom.ws.UpdateAction.PARAM_DESCRIPTION;
-import static org.sonar.server.measure.custom.ws.UpdateAction.PARAM_ID;
-import static org.sonar.server.measure.custom.ws.UpdateAction.PARAM_VALUE;
-import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations;
-import static org.sonar.test.JsonAssert.assertJson;
-
-public class UpdateActionTest {
-
- private static final long NOW = 10_000_000_000L;
-
- private System2 system = new TestSystem2().setNow(NOW);
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
- public DbTester db = DbTester.create();
- @Rule
- public EsTester es = EsTester.create();
-
- private WsActionTester ws = new WsActionTester(new UpdateAction(db.getDbClient(), userSession, system, new CustomMeasureValidator(newFullTypeValidations()),
- new CustomMeasureJsonWriter(new UserJsonWriter(userSession))));
-
- @Test
- public void verify_definition() {
- Action wsDef = ws.getDef();
-
- assertThat(wsDef.deprecatedSince()).isEqualTo("7.4");
- assertThat(wsDef.isInternal()).isFalse();
- assertThat(wsDef.since()).isEqualTo("5.2");
- assertThat(wsDef.isPost()).isTrue();
- assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly(
- tuple("8.4", "Param 'id' data type changes from integer to string."));
- }
-
- @Test
- public void update_text_value_and_description_in_db() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- UserDto userMeasureCreator = db.users().insertUser();
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(userMeasureCreator, project, metric, m -> m.setValue(0d));
-
- ws.newRequest()
- .setParam(PARAM_ID, String.valueOf(customMeasure.getUuid()))
- .setParam(PARAM_DESCRIPTION, "new-custom-measure-description")
- .setParam(PARAM_VALUE, "new-text-measure-value")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getUserUuid, CustomMeasureDto::getComponentUuid,
- CustomMeasureDto::getCreatedAt, CustomMeasureDto::getUpdatedAt)
- .containsExactlyInAnyOrder(
- tuple("new-custom-measure-description", "new-text-measure-value", 0d, userAuthenticated.getUuid(), project.uuid(), customMeasure.getCreatedAt(), NOW));
- }
-
- @Test
- public void update_int_value_and_description_in_db() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(INT.name()));
- UserDto userMeasureCreator = db.users().insertUser();
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(userMeasureCreator, project, metric, m -> m.setValue(42d).setTextValue(null));
-
- ws.newRequest()
- .setParam(PARAM_ID, String.valueOf(customMeasure.getUuid()))
- .setParam(PARAM_DESCRIPTION, "new-custom-measure-description")
- .setParam(PARAM_VALUE, "1984")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getUserUuid, CustomMeasureDto::getComponentUuid,
- CustomMeasureDto::getCreatedAt, CustomMeasureDto::getUpdatedAt)
- .containsExactlyInAnyOrder(
- tuple("new-custom-measure-description", null, 1984d, userAuthenticated.getUuid(), project.uuid(), customMeasure.getCreatedAt(), NOW));
- }
-
- @Test
- public void returns_full_object_in_response() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto userAuthenticated = db.users().insertUser();
- userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- UserDto userMeasureCreator = db.users().insertUser();
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(userMeasureCreator, project, metric, m -> m.setValue(0d).setCreatedAt(100_000_000L));
-
- String response = ws.newRequest()
- .setParam(PARAM_ID, String.valueOf(customMeasure.getUuid()))
- .setParam(PARAM_DESCRIPTION, "new-custom-measure-description")
- .setParam(PARAM_VALUE, "new-text-measure-value")
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"id\": \"" + customMeasure.getUuid() + "\",\n" +
- " \"value\": \"new-text-measure-value\",\n" +
- " \"description\": \"new-custom-measure-description\",\n" +
- " \"metric\": {\n" +
- " \"id\": \"" + metric.getUuid() + "\",\n" +
- " \"key\": \"" + metric.getKey() + "\",\n" +
- " \"type\": \"" + metric.getValueType() + "\",\n" +
- " \"name\": \"" + metric.getShortName() + "\",\n" +
- " \"domain\": \"" + metric.getDomain() + "\"\n" +
- " },\n" +
- " \"projectId\": \"" + project.uuid() + "\",\n" +
- " \"projectKey\": \"" + project.getKey() + "\",\n" +
- "}");
- }
-
- @Test
- public void update_description_only() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(user, project, metric);
-
- ws.newRequest()
- .setParam(PARAM_ID, String.valueOf(customMeasure.getUuid()))
- .setParam(PARAM_DESCRIPTION, "new-custom-measure-description")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue)
- .containsExactlyInAnyOrder(
- tuple("new-custom-measure-description", customMeasure.getTextValue(), customMeasure.getValue()));
- }
-
- @Test
- public void update_value_only() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(ADMIN, project);
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(user, project, metric);
-
- ws.newRequest()
- .setParam(PARAM_ID, String.valueOf(customMeasure.getUuid()))
- .setParam(PARAM_VALUE, "new-text-measure-value")
- .execute();
-
- assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
- .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue)
- .containsExactlyInAnyOrder(
- tuple(customMeasure.getDescription(), "new-text-measure-value", customMeasure.getValue()));
- }
-
- @Test
- public void fail_if_measure_is_not_in_db() {
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- UserDto user = db.users().insertUser();
- db.measures().insertCustomMeasure(user, project, metric);
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Custom measure with id '0' does not exist");
-
- ws.newRequest()
- .setParam(PARAM_ID, "0")
- .setParam(PARAM_DESCRIPTION, "new-custom-measure-description")
- .setParam(PARAM_VALUE, "1984")
- .execute();
- }
-
- @Test
- public void fail_if_insufficient_privileges() {
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- UserDto user = db.users().insertUser();
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(user, project, metric);
- userSession.logIn(user).addProjectPermission(USER, project);
-
- expectedException.expect(ForbiddenException.class);
-
- ws.newRequest()
- .setParam(PARAM_ID, String.valueOf(customMeasure.getUuid()))
- .setParam(PARAM_DESCRIPTION, "new-custom-measure-description")
- .setParam(PARAM_VALUE, "1984")
- .execute();
- }
-
- @Test
- public void fail_if_not_logged_in() {
- ComponentDto project = db.components().insertPrivateProject();
- UserDto user = db.users().insertUser();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- CustomMeasureDto customMeasure = db.measures().insertCustomMeasure(user, project, metric);
- userSession.anonymous();
-
- expectedException.expect(UnauthorizedException.class);
-
- ws.newRequest()
- .setParam(PARAM_ID, String.valueOf(customMeasure.getUuid()))
- .setParam(PARAM_DESCRIPTION, "new-custom-measure-description")
- .setParam(PARAM_VALUE, "1984")
- .execute();
- }
-
- @Test
- public void fail_if_custom_measure_id_is_missing_in_request() {
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- UserDto user = db.users().insertUser();
- db.measures().insertCustomMeasure(user, project, metric);
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("The 'id' parameter is missing");
-
- ws.newRequest()
- .setParam(PARAM_DESCRIPTION, "new-custom-measure-description")
- .setParam(PARAM_VALUE, "1984")
- .execute();
- }
-
- @Test
- public void fail_if_custom_measure_value_and_description_are_missing_in_request() {
- ComponentDto project = db.components().insertPrivateProject();
- MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
- UserDto user = db.users().insertUser();
- db.measures().insertCustomMeasure(user, project, metric);
- userSession.logIn(user).addProjectPermission(ADMIN, project);
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Value or description must be provided.");
-
- ws.newRequest()
- .setParam(PARAM_ID, "42")
- .execute();
- }
-
-}
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
-import org.sonar.db.measure.custom.CustomMeasureTesting;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.metric.MetricTesting;
import org.sonar.server.exceptions.ForbiddenException;
.setParam(PARAM_TYPE, DEFAULT_TYPE).execute();
}
- @Test
- public void fail_when_metric_type_is_changed_and_associated_measures_exist() {
- expectedException.expect(ServerException.class);
- MetricDto metric = MetricTesting.newMetricDto()
- .setKey(DEFAULT_KEY)
- .setValueType(ValueType.BOOL.name())
- .setUserManaged(true)
- .setEnabled(false);
- dbClient.metricDao().insert(dbSession, metric);
- dbClient.customMeasureDao().insert(dbSession, CustomMeasureTesting.newCustomMeasureDto().setMetricUuid(metric.getUuid()));
- dbSession.commit();
-
- tester.newRequest()
- .setParam(PARAM_KEY, DEFAULT_KEY)
- .setParam(PARAM_NAME, "any-name")
- .setParam(PARAM_TYPE, ValueType.INT.name())
- .execute();
- }
-
@Test
public void fail_when_missing_key() {
expectedException.expect(IllegalArgumentException.class);
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
-import org.sonar.db.measure.custom.CustomMeasureDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.qualitygate.QualityGateConditionDto;
import org.sonar.db.qualitygate.QualityGateDto;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.db.measure.custom.CustomMeasureTesting.newCustomMeasureDto;
import static org.sonar.db.metric.MetricTesting.newMetricDto;
public class DeleteActionTest {
assertThat(metric.isEnabled()).isTrue();
}
- @Test
- public void delete_associated_measures() {
- loggedAsSystemAdministrator();
- MetricDto metric = insertCustomMetric("custom-key");
- CustomMeasureDto customMeasure = newCustomMeasureDto().setMetricUuid(metric.getUuid());
- CustomMeasureDto undeletedCustomMeasure = newCustomMeasureDto().setMetricUuid("unknown");
- dbClient.customMeasureDao().insert(db.getSession(), customMeasure);
- dbClient.customMeasureDao().insert(db.getSession(), undeletedCustomMeasure);
- db.getSession().commit();
-
- newRequest().setParam("keys", "custom-key").execute();
-
- assertThat(dbClient.customMeasureDao().selectByUuid(db.getSession(), customMeasure.getUuid())).isEmpty();
- assertThat(dbClient.customMeasureDao().selectByUuid(db.getSession(), undeletedCustomMeasure.getUuid())).isNotEmpty();
- }
-
@Test
public void delete_associated_quality_gate_conditions() {
loggedAsSystemAdministrator();
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.db.measure.custom.CustomMeasureTesting.newCustomMeasureDto;
import static org.sonar.server.metric.ws.UpdateAction.PARAM_DESCRIPTION;
import static org.sonar.server.metric.ws.UpdateAction.PARAM_DOMAIN;
import static org.sonar.server.metric.ws.UpdateAction.PARAM_ID;
@Test
public void update_one_field() {
String uuid = insertMetric(newDefaultMetric());
- dbClient.customMeasureDao().insert(dbSession, newCustomMeasureDto().setMetricUuid(uuid));
dbSession.commit();
ws.newRequest()
ws.newRequest().setParam(PARAM_ID, uuid).execute();
}
- @Test
- public void fail_when_custom_measures_and_type_changed() {
- expectedException.expect(ServerException.class);
- String uuid = insertMetric(newDefaultMetric());
- dbClient.customMeasureDao().insert(dbSession, newCustomMeasureDto().setMetricUuid(uuid));
- dbSession.commit();
-
- ws.newRequest()
- .setParam(PARAM_ID, uuid)
- .setParam(PARAM_TYPE, ValueType.BOOL.name())
- .execute();
- }
-
@Test
public void fail_when_no_id() {
expectedException.expect(IllegalArgumentException.class);
@Test
public void fail_when_metric_key_is_not_well_formatted() {
String uuid = insertMetric(newDefaultMetric());
- dbClient.customMeasureDao().insert(dbSession, newCustomMeasureDto().setMetricUuid(uuid));
dbSession.commit();
expectedException.expect(IllegalArgumentException.class);
import org.sonar.server.language.LanguageValidation;
import org.sonar.server.language.ws.LanguageWs;
import org.sonar.server.log.ServerLogging;
-import org.sonar.server.measure.custom.ws.CustomMeasuresWsModule;
import org.sonar.server.measure.index.ProjectsEsModule;
import org.sonar.server.measure.live.LiveMeasureModule;
import org.sonar.server.measure.ws.MeasuresWsModule;
// measure
MetricsWsModule.class,
MeasuresWsModule.class,
- CustomMeasuresWsModule.class,
CoreCustomMetrics.class,
MetricFinder.class,
UnanalyzedLanguageMetrics.class,
import org.sonarqube.ws.client.batch.BatchService;
import org.sonarqube.ws.client.ce.CeService;
import org.sonarqube.ws.client.components.ComponentsService;
-import org.sonarqube.ws.client.custommeasures.CustomMeasuresService;
import org.sonarqube.ws.client.developers.DevelopersService;
import org.sonarqube.ws.client.duplications.DuplicationsService;
import org.sonarqube.ws.client.editions.EditionsService;
private final AuthenticationService authenticationService;
private final CeService ceService;
private final ComponentsService componentsService;
- private final CustomMeasuresService customMeasuresService;
private final DevelopersService developersService;
private final DuplicationsService duplicationsService;
private final EditionsService editionsService;
this.authenticationService = new AuthenticationService(wsConnector);
this.ceService = new CeService(wsConnector);
this.componentsService = new ComponentsService(wsConnector);
- this.customMeasuresService = new CustomMeasuresService(wsConnector);
this.developersService = new DevelopersService(wsConnector);
this.duplicationsService = new DuplicationsService(wsConnector);
this.editionsService = new EditionsService(wsConnector);
return componentsService;
}
- @Override
- public CustomMeasuresService customMeasures() {
- return customMeasuresService;
- }
-
@Override
public DevelopersService developers() {
return developersService;
import org.sonarqube.ws.client.batch.BatchService;
import org.sonarqube.ws.client.ce.CeService;
import org.sonarqube.ws.client.components.ComponentsService;
-import org.sonarqube.ws.client.custommeasures.CustomMeasuresService;
import org.sonarqube.ws.client.developers.DevelopersService;
import org.sonarqube.ws.client.duplications.DuplicationsService;
import org.sonarqube.ws.client.editions.EditionsService;
ComponentsService components();
- CustomMeasuresService customMeasures();
-
DevelopersService developers();
DuplicationsService duplications();
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sonarqube.ws.client.custommeasures;
-
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/create">Further information about this action online (including a response example)</a>
- * @since 5.2
- */
-@Generated("sonar-ws-generator")
-public class CreateRequest {
-
- private String description;
- private String metricId;
- private String metricKey;
- private String projectId;
- private String projectKey;
- private String value;
-
- /**
- * Example value: "Team size growing."
- */
- public CreateRequest setDescription(String description) {
- this.description = description;
- return this;
- }
-
- public String getDescription() {
- return description;
- }
-
- /**
- * Example value: "16"
- */
- public CreateRequest setMetricId(String metricId) {
- this.metricId = metricId;
- return this;
- }
-
- public String getMetricId() {
- return metricId;
- }
-
- /**
- * Example value: "ncloc"
- */
- public CreateRequest setMetricKey(String metricKey) {
- this.metricKey = metricKey;
- return this;
- }
-
- public String getMetricKey() {
- return metricKey;
- }
-
- /**
- * Example value: "ce4c03d6-430f-40a9-b777-ad877c00aa4d"
- */
- public CreateRequest setProjectId(String projectId) {
- this.projectId = projectId;
- return this;
- }
-
- public String getProjectId() {
- return projectId;
- }
-
- /**
- * Example value: "my_project"
- */
- public CreateRequest setProjectKey(String projectKey) {
- this.projectKey = projectKey;
- return this;
- }
-
- public String getProjectKey() {
- return projectKey;
- }
-
- /**
- * This is a mandatory parameter.
- * Example value: "47"
- */
- public CreateRequest setValue(String value) {
- this.value = value;
- return this;
- }
-
- public String getValue() {
- return value;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sonarqube.ws.client.custommeasures;
-
-import java.util.stream.Collectors;
-import javax.annotation.Generated;
-import org.sonarqube.ws.MediaTypes;
-import org.sonarqube.ws.client.BaseService;
-import org.sonarqube.ws.client.GetRequest;
-import org.sonarqube.ws.client.PostRequest;
-import org.sonarqube.ws.client.WsConnector;
-
-/**
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures">Further information about this web service online</a>
- */
-@Generated("sonar-ws-generator")
-public class CustomMeasuresService extends BaseService {
-
- public CustomMeasuresService(WsConnector wsConnector) {
- super(wsConnector, "api/custom_measures");
- }
-
- /**
- *
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/create">Further information about this action online (including a response example)</a>
- * @since 5.2
- * @deprecated since 7.4
- */
- public void create(CreateRequest request) {
- call(
- new PostRequest(path("create"))
- .setParam("description", request.getDescription())
- .setParam("metricId", request.getMetricId())
- .setParam("metricKey", request.getMetricKey())
- .setParam("projectId", request.getProjectId())
- .setParam("projectKey", request.getProjectKey())
- .setParam("value", request.getValue())
- .setMediaType(MediaTypes.JSON)
- ).content();
- }
-
- /**
- *
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/delete">Further information about this action online (including a response example)</a>
- * @since 5.2
- * @deprecated since 7.4
- */
- public void delete(DeleteRequest request) {
- call(
- new PostRequest(path("delete"))
- .setParam("id", request.getId())
- .setMediaType(MediaTypes.JSON)
- ).content();
- }
-
- /**
- *
- * This is part of the internal API.
- * This is a GET request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/metrics">Further information about this action online (including a response example)</a>
- * @since 5.2
- * @deprecated since 7.4
- */
- public String metrics(MetricsRequest request) {
- return call(
- new GetRequest(path("metrics"))
- .setParam("projectId", request.getProjectId())
- .setParam("projectKey", request.getProjectKey())
- .setMediaType(MediaTypes.JSON)
- ).content();
- }
-
- /**
- *
- * This is part of the internal API.
- * This is a GET request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/search">Further information about this action online (including a response example)</a>
- * @since 5.2
- * @deprecated since 7.4
- */
- public String search(SearchRequest request) {
- return call(
- new GetRequest(path("search"))
- .setParam("f", request.getF() == null ? null : request.getF().stream().collect(Collectors.joining(",")))
- .setParam("p", request.getP())
- .setParam("projectId", request.getProjectId())
- .setParam("projectKey", request.getProjectKey())
- .setParam("ps", request.getPs())
- .setMediaType(MediaTypes.JSON)
- ).content();
- }
-
- /**
- *
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/update">Further information about this action online (including a response example)</a>
- * @since 5.2
- * @deprecated since 7.4
- */
- public void update(UpdateRequest request) {
- call(
- new PostRequest(path("update"))
- .setParam("description", request.getDescription())
- .setParam("id", request.getId())
- .setParam("value", request.getValue())
- .setMediaType(MediaTypes.JSON)
- ).content();
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sonarqube.ws.client.custommeasures;
-
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/delete">Further information about this action online (including a response example)</a>
- * @since 5.2
- */
-@Generated("sonar-ws-generator")
-public class DeleteRequest {
-
- private String id;
-
- /**
- * This is a mandatory parameter.
- * Example value: "24"
- */
- public DeleteRequest setId(String id) {
- this.id = id;
- return this;
- }
-
- public String getId() {
- return id;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sonarqube.ws.client.custommeasures;
-
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/metrics">Further information about this action online (including a response example)</a>
- * @since 5.2
- */
-@Generated("sonar-ws-generator")
-public class MetricsRequest {
-
- private String projectId;
- private String projectKey;
-
- /**
- * Example value: "ce4c03d6-430f-40a9-b777-ad877c00aa4d"
- */
- public MetricsRequest setProjectId(String projectId) {
- this.projectId = projectId;
- return this;
- }
-
- public String getProjectId() {
- return projectId;
- }
-
- /**
- * Example value: "my_project"
- */
- public MetricsRequest setProjectKey(String projectKey) {
- this.projectKey = projectKey;
- return this;
- }
-
- public String getProjectKey() {
- return projectKey;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sonarqube.ws.client.custommeasures;
-
-import java.util.List;
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/search">Further information about this action online (including a response example)</a>
- * @since 5.2
- */
-@Generated("sonar-ws-generator")
-public class SearchRequest {
-
- private List<String> f;
- private String p;
- private String projectId;
- private String projectKey;
- private String ps;
-
- /**
- * Possible values:
- * <ul>
- * <li>"projectId"</li>
- * <li>"projectKey"</li>
- * <li>"value"</li>
- * <li>"description"</li>
- * <li>"metric"</li>
- * <li>"createdAt"</li>
- * <li>"updatedAt"</li>
- * <li>"user"</li>
- * <li>"pending"</li>
- * </ul>
- */
- public SearchRequest setF(List<String> f) {
- this.f = f;
- return this;
- }
-
- public List<String> getF() {
- return f;
- }
-
- /**
- * Example value: "42"
- */
- public SearchRequest setP(String p) {
- this.p = p;
- return this;
- }
-
- public String getP() {
- return p;
- }
-
- /**
- * Example value: "ce4c03d6-430f-40a9-b777-ad877c00aa4d"
- */
- public SearchRequest setProjectId(String projectId) {
- this.projectId = projectId;
- return this;
- }
-
- public String getProjectId() {
- return projectId;
- }
-
- /**
- * Example value: "my_project"
- */
- public SearchRequest setProjectKey(String projectKey) {
- this.projectKey = projectKey;
- return this;
- }
-
- public String getProjectKey() {
- return projectKey;
- }
-
- /**
- * Example value: "20"
- */
- public SearchRequest setPs(String ps) {
- this.ps = ps;
- return this;
- }
-
- public String getPs() {
- return ps;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sonarqube.ws.client.custommeasures;
-
-import javax.annotation.Generated;
-
-/**
- * This is part of the internal API.
- * This is a POST request.
- * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/custom_measures/update">Further information about this action online (including a response example)</a>
- * @since 5.2
- */
-@Generated("sonar-ws-generator")
-public class UpdateRequest {
-
- private String description;
- private String id;
- private String value;
-
- /**
- * Example value: "Team size growing."
- */
- public UpdateRequest setDescription(String description) {
- this.description = description;
- return this;
- }
-
- public String getDescription() {
- return description;
- }
-
- /**
- * This is a mandatory parameter.
- * Example value: "42"
- */
- public UpdateRequest setId(String id) {
- this.id = id;
- return this;
- }
-
- public String getId() {
- return id;
- }
-
- /**
- * Example value: "true"
- */
- public UpdateRequest setValue(String value) {
- this.value = value;
- return this;
- }
-
- public String getValue() {
- return value;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.
- */
-@ParametersAreNonnullByDefault
-@Generated("sonar-ws-generator")
-package org.sonarqube.ws.client.custommeasures;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.Generated;
-