Просмотр исходного кода

SONAR-8046 Validate settings of type METRIC

tags/6.1-RC1
Teryk Bellahsene 7 лет назад
Родитель
Сommit
1bb7566e97

+ 45
- 22
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingValidations.java Просмотреть файл

@@ -20,28 +20,33 @@

package org.sonar.server.setting.ws;

import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.i18n.I18n;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonarqube.ws.client.setting.SetRequest;
import org.sonar.db.metric.MetricDto;
import org.sonar.server.exceptions.BadRequestException;

import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static org.sonar.server.ws.WsUtils.checkRequest;

public class SettingValidations {
private final PropertyDefinitions definitions;
private final DbClient dbClient;
private final I18n i18n;

public SettingValidations(PropertyDefinitions definitions, I18n i18n) {
public SettingValidations(PropertyDefinitions definitions, DbClient dbClient, I18n i18n) {
this.definitions = definitions;
this.dbClient = dbClient;
this.i18n = i18n;
}

@@ -63,24 +68,7 @@ public class SettingValidations {
}

public SettingValidation valueType() {
return data -> {
PropertyDefinition definition = definitions.get(data.key);
if (definition == null) {
return;
}
Optional<PropertyDefinition.Result> failingResult = data.values.stream()
.map(definition::validate)
.filter(result -> !result.isValid())
.findAny();
String errorKey = failingResult.isPresent() ? failingResult.get().getErrorKey() : null;
checkRequest(errorKey == null,
i18n.message(Locale.ENGLISH, "property.error." + errorKey, "Error when validating setting with key '%s' and value [%s]"),
data.key, data.values.stream().collect(Collectors.joining(", ")));
};
}

private static List<String> valuesFromRequest(SetRequest request) {
return request.getValue() == null ? request.getValues() : Collections.singletonList(request.getValue());
return new ValueTypeValidation();
}

private static boolean isGlobal(PropertyDefinition definition) {
@@ -103,6 +91,41 @@ public class SettingValidations {
this.values = requireNonNull(values);
this.component = component;
}
}

private class ValueTypeValidation implements SettingValidation {

@Override
public void validate(SettingData data) {
PropertyDefinition definition = definitions.get(data.key);
if (definition == null) {
return;
}

if (definition.type() == PropertyType.METRIC) {
metric(data);
} else {
otherTypes(data, definition);
}
}

private void otherTypes(SettingData data, PropertyDefinition definition) {
data.values.stream()
.map(definition::validate)
.filter(result -> !result.isValid())
.findAny()
.ifPresent(result -> {
throw new BadRequestException(i18n.message(Locale.ENGLISH, "property.error." + result.getErrorKey(),
format("Error when validating setting with key '%s' and value [%s]", data.key, data.values.stream().collect(Collectors.joining(", ")))));
});
}

private void metric(SettingData data) {
try (DbSession dbSession = dbClient.openSession(false)) {
List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, data.values);
checkRequest(data.values.size() == metrics.size(), "Error when validating metric setting with key '%s' and values [%s]. A value is not a valid metric key.",
data.key, data.values.stream().collect(Collectors.joining(", ")));
}
}
}
}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/setting/ws/ResetActionTest.java Просмотреть файл

@@ -81,7 +81,7 @@ public class ResetActionTest {
ComponentFinder componentFinder = new ComponentFinder(dbClient);
PropertyDefinitions definitions = new PropertyDefinitions();
SettingsUpdater settingsUpdater = new SettingsUpdater(dbClient, definitions);
SettingValidations settingValidations = new SettingValidations(definitions, i18n);
SettingValidations settingValidations = new SettingValidations(definitions, dbClient, i18n);

ComponentDto project;


+ 44
- 1
server/sonar-server/src/test/java/org/sonar/server/setting/ws/SetActionTest.java Просмотреть файл

@@ -62,6 +62,7 @@ import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.db.metric.MetricTesting.newMetricDto;
import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto;
import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto;

@@ -86,7 +87,7 @@ public class SetActionTest {
PropertyDefinitions definitions = new PropertyDefinitions();
FakeSettingsNotifier settingsChangeNotifier = new FakeSettingsNotifier(dbClient);
SettingsUpdater settingsUpdater = new SettingsUpdater(dbClient, definitions);
SettingValidations validations = new SettingValidations(definitions, i18n);
SettingValidations validations = new SettingValidations(definitions, dbClient, i18n);

SetAction underTest = new SetAction(definitions, i18n, dbClient, componentFinder, userSession, settingsUpdater, settingsChangeNotifier, validations);

@@ -305,6 +306,27 @@ public class SetActionTest {
assertThat(settingsChangeNotifier.wasCalled).isFalse();
}

@Test
public void persist_multi_value_with_type_metric() {
definitions.addComponent(PropertyDefinition
.builder("my.key")
.name("foo")
.description("desc")
.category("cat")
.subCategory("subCat")
.type(PropertyType.METRIC)
.defaultValue("default")
.multiValues(true)
.build());
dbClient.metricDao().insert(dbSession, newMetricDto().setKey("metric.key.1"));
dbClient.metricDao().insert(dbSession, newMetricDto().setKey("metric.key.2"));
dbSession.commit();

callForMultiValueGlobalSetting("my.key", newArrayList("metric.key.1", "metric.key.2"));

assertGlobalSetting("my.key", "metric.key.1,metric.key.2");
}

@Test
public void user_setting_is_not_updated() {
propertyDb.insertProperty(newGlobalPropertyDto("my.key", "my user value").setUserId(42L));
@@ -391,6 +413,27 @@ public class SetActionTest {
callForGlobalSetting("my.key", "My Value");
}

@Test
public void fail_when_data_and_metric_type_with_invalid_key() {
definitions.addComponent(PropertyDefinition
.builder("my.key")
.name("foo")
.description("desc")
.category("cat")
.subCategory("subCat")
.type(PropertyType.METRIC)
.defaultValue("default")
.multiValues(true)
.build());
dbClient.metricDao().insert(dbSession, newMetricDto().setKey("metric.key"));
dbSession.commit();

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Error when validating metric setting with key 'my.key' and values [metric.key, My Value]. A value is not a valid metric key.");

callForMultiValueGlobalSetting("my.key", newArrayList("metric.key", "My Value"));
}

@Test
public void fail_when_data_and_type_do_not_match_with_unknown_error_key() {
definitions.addComponent(PropertyDefinition

Загрузка…
Отмена
Сохранить