group=org.sonarsource.sonarqube
version=10.2
-pluginApiVersion=9.17.0.587
+pluginApiVersion=10.0.0.695
description=Open source platform for continuous inspection of code quality
projectTitle=SonarQube
org.gradle.jvmargs=-Xmx2048m
public void send_global_new_issues_notification() {
analysisMetadataHolder.setProject(new Project(PROJECT.getUuid(), PROJECT.getKey(), PROJECT.getName(), null, emptyList()));
protoIssueCache.newAppender().append(
- createIssue().setType(randomRuleType).setEffort(ISSUE_DURATION)
- .setCreationDate(new Date(ANALYSE_DATE)))
+ createIssue().setType(randomRuleType).setEffort(ISSUE_DURATION)
+ .setCreationDate(new Date(ANALYSE_DATE)))
.close();
when(notificationService.hasProjectSubscribersForTypes(eq(PROJECT.getUuid()), any())).thenReturn(true);
public void do_not_send_global_new_issues_notification_if_issue_has_been_backdated() {
analysisMetadataHolder.setProject(new Project(PROJECT.getUuid(), PROJECT.getKey(), PROJECT.getName(), null, emptyList()));
protoIssueCache.newAppender().append(
- createIssue().setType(randomRuleType).setEffort(ISSUE_DURATION)
- .setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS)))
+ createIssue().setType(randomRuleType).setEffort(ISSUE_DURATION)
+ .setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS)))
.close();
when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(true);
analysisMetadataHolder.setProject(new Project(PROJECT.getUuid(), PROJECT.getKey(), PROJECT.getName(), null, emptyList()));
protoIssueCache.newAppender().append(
- createIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setAssigneeUuid(user.getUuid()).setCreationDate(new Date(ANALYSE_DATE)))
+ createIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setAssigneeUuid(user.getUuid()).setCreationDate(new Date(ANALYSE_DATE)))
.close();
when(notificationService.hasProjectSubscribersForTypes(eq(PROJECT.getUuid()), any())).thenReturn(true);
analysisMetadataHolder.setProject(new Project(PROJECT.getUuid(), PROJECT.getKey(), PROJECT.getName(), null, emptyList()));
UserDto user = db.users().insertUser();
protoIssueCache.newAppender().append(
- createIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setAssigneeUuid(user.getUuid())
- .setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS)))
+ createIssue().setType(randomRuleType).setEffort(ISSUE_DURATION).setAssigneeUuid(user.getUuid())
+ .setCreationDate(new Date(ANALYSE_DATE - FIVE_MINUTES_IN_MS)))
.close();
when(notificationService.hasProjectSubscribersForTypes(PROJECT.getUuid(), NOTIF_TYPES)).thenReturn(true);
private final String metricKey;
private final QualityGate.Operator operator;
private final String errorThreshold;
- private final boolean onLeakPeriod;
@CheckForNull
private final String value;
this.metricKey = builder.metricKey;
this.operator = builder.operator;
this.errorThreshold = builder.errorThreshold;
- this.onLeakPeriod = builder.metricKey.startsWith("new_");
this.value = builder.value;
}
return this;
}
- /**
- * @deprecated in 7.6. This method has no longer any effect.
- */
- @Deprecated
- public Builder setWarningThreshold(String warningThreshold) {
- return this;
- }
-
- /**
- * @deprecated in 7.6. This method has no longer any effect.
- */
- @Deprecated
- public Builder setOnLeakPeriod(boolean onLeakPeriod) {
- return this;
- }
-
public Builder setValue(String value) {
this.value = value;
return this;
return errorThreshold;
}
- @Deprecated
- @Override
- public String getWarningThreshold() {
- return null;
- }
-
- /**
- * @deprecated in 7.6. Conditions "on leak period" were removed. Use "New X" conditions instead.
- */
- @Deprecated
- @Override
- public boolean isOnLeakPeriod() {
- return onLeakPeriod;
- }
-
@Override
public String getValue() {
checkState(status != NO_VALUE, "There is no value when status is %s", NO_VALUE);
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.ce.measure.MeasureComputer;
-import org.sonar.api.ce.measure.test.TestMeasureComputerDefinitionContext;
+import org.sonar.api.testfixtures.measure.TestMeasureComputerDefinitionContext;
import org.sonar.ce.task.projectanalysis.api.measurecomputer.MeasureComputerDefinitionImpl;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
@Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(CoreMetrics.FILES)
- .add(CoreMetrics.DIRECTORIES)
.add(CoreMetrics.LINES)
.add(CoreMetrics.GENERATED_LINES)
.add(CoreMetrics.NCLOC)
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.measures.CoreMetrics.CLASSES;
import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY;
-import static org.sonar.api.measures.CoreMetrics.DIRECTORIES;
import static org.sonar.api.measures.CoreMetrics.FILES;
import static org.sonar.api.measures.CoreMetrics.FILES_KEY;
import static org.sonar.api.measures.CoreMetrics.FUNCTIONS;
builder(PROJECT_VIEW, PROJECTVIEW_3_REF).build())
.build(),
builder(SUBVIEW, SUB_SUBVIEW_3_REF).addChildren(
- builder(PROJECT_VIEW, PROJECTVIEW_4_REF).build())
+ builder(PROJECT_VIEW, PROJECTVIEW_4_REF).build())
.build())
.build(),
builder(SUBVIEW, SUBVIEW_2_REF).build(),
@Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(FILES)
- .add(DIRECTORIES)
.add(LINES)
.add(GENERATED_LINES)
.add(NCLOC)
import org.sonar.api.ce.posttask.Branch;
import org.sonar.api.ce.posttask.CeTask;
import org.sonar.api.ce.posttask.PostProjectAnalysisTask.LogStatistics;
-import org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester;
import org.sonar.api.ce.posttask.Project;
import org.sonar.api.ce.posttask.QualityGate;
import org.sonar.api.config.Configuration;
import org.sonar.api.measures.Metric;
+import org.sonar.api.testfixtures.posttask.PostProjectAnalysisTaskTester;
import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;
import org.sonar.server.qualitygate.Condition;
import org.sonar.server.qualitygate.EvaluatedCondition;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newBranchBuilder;
-import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newCeTaskBuilder;
-import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newConditionBuilder;
-import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newProjectBuilder;
-import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newQualityGateBuilder;
-import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newScannerContextBuilder;
+import static org.sonar.api.testfixtures.posttask.PostProjectAnalysisTaskTester.newBranchBuilder;
+import static org.sonar.api.testfixtures.posttask.PostProjectAnalysisTaskTester.newCeTaskBuilder;
+import static org.sonar.api.testfixtures.posttask.PostProjectAnalysisTaskTester.newConditionBuilder;
+import static org.sonar.api.testfixtures.posttask.PostProjectAnalysisTaskTester.newProjectBuilder;
+import static org.sonar.api.testfixtures.posttask.PostProjectAnalysisTaskTester.newQualityGateBuilder;
+import static org.sonar.api.testfixtures.posttask.PostProjectAnalysisTaskTester.newScannerContextBuilder;
public class WebhookPostTaskTest {
.setMetricKey(randomAlphanumeric(96))
.setOperator(QualityGate.Operator.LESS_THAN)
.setErrorThreshold(randomAlphanumeric(22))
- .setOnLeakPeriod(random.nextBoolean())
.build(QualityGate.EvaluationStatus.OK, randomAlphanumeric(33));
QualityGate qualityGate = newQualityGateBuilder()
.setId(randomAlphanumeric(23))
when(notificationService.hasProjectSubscribersForTypes(projectData.projectUuid(), singleton(ReportAnalysisFailureNotification.class)))
.thenReturn(true);
-
Duration randomDuration = randomDuration();
assertThatThrownBy(() -> underTest.onEnd(ceTaskMock, CeActivityDto.Status.FAILED, randomDuration, ceTaskResultMock, throwableMock))
.isInstanceOf(RowNotFoundException.class)
long executedAt = random.nextInt(999_999);
ProjectData project = random.nextBoolean() ? dbTester.components().insertPrivateProject() : dbTester.components().insertPublicProject();
- ComponentDto branchComponent = dbTester.components().insertProjectBranch(project.getMainBranchComponent(), b->b.setKey("otherbranch"));
+ ComponentDto branchComponent = dbTester.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setKey("otherbranch"));
initMocksToPassConditionsForBranch(branchComponent, project, taskUuid, createdAt, executedAt);
Notification notificationMock = mockSerializer();
import org.sonar.api.config.EmailSettings;
import org.sonar.api.internal.MetadataLoader;
import org.sonar.api.internal.SonarRuntimeImpl;
-import org.sonar.api.profiles.XMLProfileParser;
-import org.sonar.api.profiles.XMLProfileSerializer;
import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.rules.AnnotationRuleParser;
import org.sonar.api.server.profile.BuiltInQualityProfileAnnotationLoader;
import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
import org.sonar.api.utils.Durations;
import org.sonar.server.l18n.ServerI18n;
import org.sonar.server.log.ServerLogging;
import org.sonar.server.measure.index.ProjectMeasuresIndexer;
-import org.sonar.server.metric.MetricFinder;
import org.sonar.server.metric.UnanalyzedLanguageMetrics;
import org.sonar.server.notification.DefaultNotificationManager;
import org.sonar.server.notification.NotificationService;
// quality profile
ActiveRuleIndexer.class,
- XMLProfileParser.class,
- XMLProfileSerializer.class,
BuiltInQualityProfileAnnotationLoader.class,
Rules.QProfiles.class,
// rule
- AnnotationRuleParser.class,
DefaultRuleFinder.class,
RulesDefinitionXmlLoader.class,
AdHocRuleCreator.class,
LanguagesProvider.class,
// measure
- MetricFinder.class,
UnanalyzedLanguageMetrics.class,
// components,
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.api.notifications;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+/**
+ * This class represents a notification that will be delivered to users. This is a general concept and it has no
+ * knowledge of the possible ways to be delivered (see {@link NotificationChannel}).
+ * <p>
+ * When creating a new notification, it is strongly advised to give a default message that can be used by channels
+ * that don't want to specifically format messages for different notification types. You can use
+ * {@link Notification#setDefaultMessage(String)} for that purpose.
+ *
+ * Note: This class used to be part of the plugin API but is no longer part of it and plugins can no longer implement it.
+ * However, since notifications get serialized into the DB, it was moved here keeping the same package name.
+ */
+public class Notification implements Serializable {
+
+ private static final String DEFAULT_MESSAGE_KEY = "default_message";
+
+ private final String type;
+ private final Map<String, String> fields = new HashMap<>();
+
+ /**
+ * <p>
+ * Create a new {@link Notification} of the given type.
+ *
+ * Example: type = "new-violations"
+ *
+ * @param type the type of notification
+ */
+ public Notification(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns the type of the notification
+ *
+ * @return the type
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * <p>
+ * When creating a new notification, it is strongly advised to give a default message that can be
+ * used by channels that don't want to specifically format messages for different notification types.
+ *
+ * <p>
+ * This method is equivalent to setting a value for the field {@link #DEFAULT_MESSAGE_KEY} with
+ * {@link #setFieldValue(String, String)}.
+ *
+ *
+ * @since 3.5
+ */
+ public Notification setDefaultMessage(String value) {
+ setFieldValue(DEFAULT_MESSAGE_KEY, value);
+ return this;
+ }
+
+ /**
+ * Returns the default message to display for this notification.
+ */
+ public String getDefaultMessage() {
+ String defaultMessage = getFieldValue(DEFAULT_MESSAGE_KEY);
+ if (defaultMessage == null) {
+ defaultMessage = this.toString();
+ }
+ return defaultMessage;
+ }
+
+ /**
+ * Adds a field (kind of property) to the notification
+ *
+ * @param field the name of the field (= the key)
+ * @param value the value of the field
+ * @return the notification itself
+ */
+ public Notification setFieldValue(String field, @Nullable String value) {
+ fields.put(field, value);
+ return this;
+ }
+
+ /**
+ * Returns the value of a field.
+ *
+ * @param field the field
+ * @return the value of the field
+ */
+ @CheckForNull
+ public String getFieldValue(String field) {
+ return fields.get(field);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Notification)) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ Notification other = (Notification) obj;
+ return this.type.equals(other.type) && this.fields.equals(other.fields);
+ }
+
+ @Override
+ public int hashCode() {
+ return type.hashCode() * 31 + fields.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Notification{");
+ sb.append("type='").append(type).append('\'');
+ sb.append(", fields=").append(fields);
+ sb.append('}');
+ return sb.toString();
+ }
+}
\ No newline at end of file
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.utils.SonarException;
/**
* @since 3.7.1
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
- public static <T extends Notification> NotificationQueueDto toNotificationQueueDto(T notification) {
+ public static NotificationQueueDto toNotificationQueueDto(Notification notification) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)) {
objectOutputStream.writeObject(notification);
return new NotificationQueueDto().setData(byteArrayOutputStream.toByteArray());
} catch (IOException e) {
- throw new SonarException("Unable to write notification", e);
+ throw new IllegalStateException("Unable to write notification", e);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.api.notifications;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class NotificationTest {
+ @Test
+ public void getType_shouldReturnTypePassedInConstructor() {
+ Notification notification = new Notification("type");
+ assertThat(notification.getType()).isEqualTo("type");
+ }
+
+ @Test
+ public void getDefaultMessage_whenNotDefined_returnToString() {
+ Notification notification = new Notification("type");
+ assertThat(notification.getDefaultMessage()).isEqualTo("Notification{type='type', fields={}}");
+ }
+
+ @Test
+ public void getDefaultMessage_whenDefined_returnDefinedMessage() {
+ Notification notification = new Notification("type");
+ notification.setDefaultMessage("default");
+ assertThat(notification.getDefaultMessage()).isEqualTo("default");
+ }
+
+ @Test
+ public void getFieldValue_whenNotDefined_shouldReturnNull() {
+ Notification notification = new Notification("type");
+ assertThat(notification.getFieldValue("unknown")).isNull();
+ }
+
+ @Test
+ public void getFieldValue_whenDefined_shouldReturnValue() {
+ Notification notification = new Notification("type");
+ notification.setFieldValue("key", "value");
+ assertThat(notification.getFieldValue("key")).isEqualTo("value");
+ }
+
+ @Test
+ public void equals_whenTypeAndFieldsMatch_shouldReturnTrue() {
+ Notification notification1 = new Notification("type");
+ Notification notification2 = new Notification("type");
+
+ notification1.setFieldValue("key", "value");
+ notification2.setFieldValue("key", "value");
+
+ assertThat(notification1)
+ .hasSameHashCodeAs(notification2)
+ .isEqualTo(notification2);
+ }
+
+ @Test
+ public void equals_whenTypeDontMatch_shouldReturnFalse() {
+ Notification notification1 = new Notification("type1");
+ Notification notification2 = new Notification("type2");
+
+ assertThat(notification1).isNotEqualTo(notification2);
+ }
+
+ @Test
+ public void equals_whenFieldsDontMatch_shouldReturnFalse() {
+ Notification notification1 = new Notification("type");
+ Notification notification2 = new Notification("type");
+
+ notification1.setFieldValue("key", "value1");
+ notification2.setFieldValue("key", "value2");
+
+ assertThat(notification1).isNotEqualTo(notification2);
+ }
+
+ @Test
+ public void toString_shouldReturnTypeAndFields() {
+ Notification notification1 = new Notification("type");
+
+ notification1.setFieldValue("key", "value1");
+
+ assertThat(notification1).hasToString("Notification{type='type', fields={key=value1}}");
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.metric;
-
-import java.util.Arrays;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbTester;
-import org.sonar.db.metric.MetricDto;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.db.metric.MetricTesting.newMetricDto;
-
-public class MetricFinderIT {
-
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
-
- private final MetricFinder underTest = new MetricFinder(db.getDbClient());
-
- @Test
- public void findAll_enabled() {
- db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- db.getDbClient().metricDao().insert(db.getSession(), newMetricDto().setEnabled(false));
- db.commit();
-
- assertThat(underTest.findAll()).hasSize(2);
- }
-
- @Test
- public void findAll_by_keys() {
- db.getDbClient().metricDao().insert(db.getSession(), newMetricDto().setKey("ncloc"));
- db.getDbClient().metricDao().insert(db.getSession(), newMetricDto().setKey("foo"));
- db.getDbClient().metricDao().insert(db.getSession(), newMetricDto().setKey("coverage"));
- db.commit();
-
- assertThat(underTest.findAll(Arrays.asList("ncloc", "foo"))).extracting(Metric::getKey).containsExactlyInAnyOrder("ncloc", "foo")
- .doesNotContain("coverage");
-
- }
-
- @Test
- public void findById() {
- MetricDto firstMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- MetricDto secondMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- db.commit();
-
- assertThat(underTest.findByUuid(firstMetric.getUuid())).extracting(Metric::getKey).isEqualTo(firstMetric.getKey());
- }
-
- @Test
- public void findById_filters_out_disabled() {
- MetricDto firstMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- MetricDto secondMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto().setEnabled(false));
- db.commit();
-
- assertThat(underTest.findByUuid(secondMetric.getUuid())).isNull();
- }
-
- @Test
- public void findById_doesnt_find_anything() {
- MetricDto firstMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- MetricDto secondMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- db.commit();
-
- assertThat(underTest.findByUuid("non existing")).isNull();
- }
-
- @Test
- public void findByKey() {
- MetricDto firstMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- MetricDto secondMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- db.commit();
-
- assertThat(underTest.findByKey(secondMetric.getKey())).extracting(Metric::getKey).isEqualTo(secondMetric.getKey());
- }
-
- @Test
- public void findByKey_filters_out_disabled() {
- MetricDto firstMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- MetricDto secondMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto().setEnabled(false));
- db.commit();
-
- assertThat(underTest.findByKey(secondMetric.getKey())).isNull();
- }
-
- @Test
- public void findByKey_doesnt_find_anything() {
- MetricDto firstMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- MetricDto secondMetric = db.getDbClient().metricDao().insert(db.getSession(), newMetricDto());
- db.commit();
-
- assertThat(underTest.findByKey("doesnt exist")).isNull();
- }
-}
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleParam;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleDto.Scope;
+import org.sonar.db.rule.RuleParamDto;
import static java.util.Collections.emptySet;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.groups.Tuple.tuple;
import static org.mockito.Mockito.mock;
public class DefaultRuleFinderIT {
assertThat(underTest.findDtoByUuid(rule4.getUuid())).isPresent();
}
+ @Test
+ public void should_include_rule_params() {
+ RuleParamDto ruleParamDto = dbTester.rules().insertRuleParam(rule1, p -> p.setType("type").setName("name").setDescription("desc"));
+ dbTester.getSession().commit();
+ Rule rule = underTest.findByKey("checkstyle", "com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck");
+ assertThat(rule).isNotNull();
+ assertThat(rule.getParams())
+ .extracting(RuleParam::getKey, RuleParam::getType, RuleParam::getDescription)
+ .containsOnly(tuple("name", "type", "desc"));
+ }
+
@Test
public void should_fail_find() {
assertThat(underTest.findDtoByKey(RuleKey.of("pmd", "unknown"))).isEmpty();
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.FIELD_ANALYSED_AT;
import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.FIELD_KEY;
import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.FIELD_LANGUAGES;
public class ProjectMeasuresDoc extends BaseDoc {
- public static final Map<String, Integer> QUALITY_GATE_STATUS = ImmutableMap.of(OK.name(), 1, WARN.name(), 2, ERROR.name(), 3);
+ public static final Map<String, Integer> QUALITY_GATE_STATUS = Map.of(OK.name(), 1, ERROR.name(), 3);
public ProjectMeasuresDoc() {
super(TYPE_PROJECT_MEASURES, new HashMap<>(8));
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.metric;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import javax.annotation.Nonnull;
-import org.sonar.api.measures.Metric;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.metric.MetricDto;
-
-public class MetricFinder {
-
- private final DbClient dbClient;
-
- public MetricFinder(DbClient dbClient) {
- this.dbClient = dbClient;
- }
-
- public Metric findByUuid(String uuid) {
- try (DbSession session = dbClient.openSession(false)) {
- MetricDto dto = dbClient.metricDao().selectByUuid(session, uuid);
- if (dto != null && dto.isEnabled()) {
- return ToMetric.INSTANCE.apply(dto);
- }
- return null;
- }
- }
-
- public Metric findByKey(String key) {
- try (DbSession session = dbClient.openSession(false)) {
- MetricDto dto = dbClient.metricDao().selectByKey(session, key);
- if (dto != null && dto.isEnabled()) {
- return ToMetric.INSTANCE.apply(dto);
- }
- return null;
- }
- }
-
- public Collection<Metric> findAll(List<String> metricKeys) {
- try (DbSession session = dbClient.openSession(false)) {
- List<MetricDto> dtos = dbClient.metricDao().selectByKeys(session, metricKeys);
- return dtos.stream().filter(IsEnabled.INSTANCE).map(ToMetric.INSTANCE).toList();
- }
- }
-
- public Collection<Metric> findAll() {
- try (DbSession session = dbClient.openSession(false)) {
- List<MetricDto> dtos = dbClient.metricDao().selectEnabled(session);
- return dtos.stream().map(ToMetric.INSTANCE).toList();
- }
- }
-
- private enum IsEnabled implements Predicate<MetricDto> {
- INSTANCE;
- @Override
- public boolean test(@Nonnull MetricDto dto) {
- return dto.isEnabled();
- }
- }
-
- private enum ToMetric implements Function<MetricDto, Metric> {
- INSTANCE;
-
- @Override
- public Metric apply(@Nonnull MetricDto dto) {
- Metric<Serializable> metric = new Metric<>();
- metric.setUuid(dto.getUuid());
- metric.setKey(dto.getKey());
- metric.setDescription(dto.getDescription());
- metric.setName(dto.getShortName());
- metric.setBestValue(dto.getBestValue());
- metric.setDomain(dto.getDomain());
- metric.setEnabled(dto.isEnabled());
- metric.setDirection(dto.getDirection());
- metric.setHidden(dto.isHidden());
- metric.setQualitative(dto.isQualitative());
- metric.setType(Metric.ValueType.valueOf(dto.getValueType()));
- metric.setOptimizedBestValue(dto.isOptimizedBestValue());
- metric.setWorstValue(dto.getWorstValue());
- return metric;
- }
- }
-}
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
-import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
-import org.sonar.api.utils.SonarException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.sonar.api.notifications.Notification;
+import org.sonar.api.utils.SonarException;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.EmailSubscriberDto;
}
@Override
- public Set<EmailRecipient> findSubscribedEmailRecipients(String dispatcherKey, String projectKey, SubscriberPermissionsOnProject subscriberPermissionsOnProject) {
+ public Set<EmailRecipient> findSubscribedEmailRecipients(String dispatcherKey, String projectKey,
+ SubscriberPermissionsOnProject subscriberPermissionsOnProject) {
verifyProjectKey(projectKey);
try (DbSession dbSession = dbClient.openSession(false)) {
.collect(Collectors.toSet());
}
- private Stream<EmailSubscriberDto> keepAuthorizedEmailSubscribers(DbSession dbSession, String projectKey, Set<EmailSubscriberDto> emailSubscribers,
+ private Stream<EmailSubscriberDto> keepAuthorizedEmailSubscribers(DbSession dbSession, String projectKey,
+ Set<EmailSubscriberDto> emailSubscribers,
SubscriberPermissionsOnProject requiredPermissions) {
if (requiredPermissions.getGlobalSubscribers().equals(requiredPermissions.getProjectSubscribers())) {
return keepAuthorizedEmailSubscribers(dbSession, projectKey, emailSubscribers, null, requiredPermissions.getGlobalSubscribers());
}
}
- private Stream<EmailSubscriberDto> keepAuthorizedEmailSubscribers(DbSession dbSession, String projectKey, Set<EmailSubscriberDto> emailSubscribers,
+ private Stream<EmailSubscriberDto> keepAuthorizedEmailSubscribers(DbSession dbSession, String projectKey,
+ Set<EmailSubscriberDto> emailSubscribers,
@Nullable Boolean global, String permission) {
Set<EmailSubscriberDto> subscribers = emailSubscribers.stream()
.filter(s -> global == null || s.isGlobal() == global)
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.notification;
+
+import org.sonar.api.notifications.Notification;
+
+/**
+ * <p>
+ * This class can be extended to provide implementation on a specific way to deliver notifications.
+ *
+ * For example:
+ * <ul>
+ * <li>email - sends email as soon as possible</li>
+ * <li>email (digest) - collects notifications and sends them together once a day</li>
+ * <li>gtalk - sends a chat message as soon as possible</li>
+ * </ul>
+ *
+ */
+public abstract class NotificationChannel {
+
+ /**
+ * Returns the unique key of this channel.
+ *
+ * @return the key
+ */
+ public String getKey() {
+ return getClass().getSimpleName();
+ }
+
+ /**
+ * Implements the delivery of the given notification to the given user.
+ *
+ * @param notification the notification to deliver
+ * @param userlogin the login of the user who should receive the notification
+ * @return whether the notification was sent or not
+ */
+ public abstract boolean deliver(Notification notification, String userlogin);
+
+ @Override
+ public String toString() {
+ return getKey();
+ }
+
+}
\ No newline at end of file
import org.sonar.api.ExtensionPoint;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.server.ServerSide;
/**
import javax.annotation.Nullable;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.server.ServerSide;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.LoggerFactory;
import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.user.User;
import org.sonar.api.utils.SonarException;
import org.sonar.db.DbClient;
import org.sonar.db.user.UserDto;
import org.sonar.server.issue.notification.EmailMessage;
import org.sonar.server.issue.notification.EmailTemplate;
+import org.sonar.server.notification.NotificationChannel;
import static java.util.Objects.requireNonNull;
return config.get(CoreProperties.SERVER_ID).orElse(null);
}
- @Override
- public String getPermanentServerId() {
- return getId();
- }
-
@Override
public String getVersion() {
return version.get().toString();
public String getPublicRootUrl() {
return urlSettings.getBaseUrl();
}
-
- @Override
- public boolean isSecured() {
- return urlSettings.isSecured();
- }
}
private org.sonar.api.rules.Rule toRule(RuleDto rule, List<RuleParamDto> params) {
String severity = rule.getSeverityString();
- org.sonar.api.rules.Rule apiRule = new org.sonar.api.rules.Rule();
+ org.sonar.api.rules.Rule apiRule = org.sonar.api.rules.Rule.create();
apiRule
.setName(rule.getName())
.setLanguage(rule.getLanguage())
Optional.ofNullable(ruleDescriptionFormatter.getDescriptionAsHtml(rule)).ifPresent(apiRule::setDescription);
- List<org.sonar.api.rules.RuleParam> apiParams = new ArrayList<>();
for (RuleParamDto param : params) {
- apiParams.add(new org.sonar.api.rules.RuleParam(apiRule, param.getName(), param.getDescription(), param.getType())
- .setDefaultValue(param.getDefaultValue()));
+ apiRule.createParameter()
+ .setType(param.getType())
+ .setDescription(param.getDescription())
+ .setKey(param.getName())
+ .setDefaultValue(param.getDefaultValue());
}
- apiRule.setParams(apiParams);
return apiRule;
}
Rule rule2 = newRandomNotAHotspotRule("a");
String host = randomAlphabetic(15);
List<ChangedIssue> changedIssues = Stream.of(
- IntStream.range(0, 39).mapToObj(i -> newChangedIssue("39_" + i, project1, rule1)),
- IntStream.range(0, 40).mapToObj(i -> newChangedIssue("40_" + i, project1, rule2)),
- IntStream.range(0, 81).mapToObj(i -> newChangedIssue("1-40_41-80_1_" + i, project2, rule2)),
- IntStream.range(0, 6).mapToObj(i -> newChangedIssue("6_" + i, project2Branch, rule1)))
+ IntStream.range(0, 39).mapToObj(i -> newChangedIssue("39_" + i, project1, rule1)),
+ IntStream.range(0, 40).mapToObj(i -> newChangedIssue("40_" + i, project1, rule2)),
+ IntStream.range(0, 81).mapToObj(i -> newChangedIssue("1-40_41-80_1_" + i, project2, rule2)),
+ IntStream.range(0, 6).mapToObj(i -> newChangedIssue("6_" + i, project2Branch, rule1)))
.flatMap(t -> t)
.collect(toList());
Collections.shuffle(changedIssues);
import org.junit.Test;
import org.mockito.InOrder;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
public class DefaultNotificationManagerTest {
-
private DefaultNotificationManager underTest;
private PropertiesDao propertiesDao = mock(PropertiesDao.class);
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
assertThat(underTest.getContextPath()).isEqualTo("/foo");
assertThat(underTest.getPublicRootUrl()).isEqualTo("http://localhost:9000/foo");
- assertThat(underTest.isSecured()).isFalse();
}
@Test
settings.setProperty(CoreProperties.SERVER_ID, "foo");
assertThat(underTest.getId()).isEqualTo("foo");
- assertThat(underTest.getPermanentServerId()).isEqualTo("foo");
}
@Test
public String getPublicRootUrl() {
return null;
}
-
- @Override
- public boolean isSecured() {
- return false;
- }
-
- @Override
- public String getPermanentServerId() {
- return null;
- }
}
@Test
public void shouldFormatAlertWithSeveralMessagesOnBranch() {
Notification notification = createNotification("Failed", "violations > 4, coverage < 75%", "ERROR", "false")
- .setFieldValue("branch", "feature");
+ .setFieldValue("branch", "feature");
EmailMessage message = template.format(notification);
assertThat(message.getMessageId(), is("alerts/45"));
@Test
public void shouldFormatNewAlertWithoutVersion() {
Notification notification = createNotification("Failed", "violations > 4", "ERROR", "true")
- .setFieldValue("projectVersion", null);
+ .setFieldValue("projectVersion", null);
EmailMessage message = template.format(notification);
assertThat(message.getMessageId(), is("alerts/45"));
@Test
public void shouldFormatBackToGreenMessageOnBranch() {
Notification notification = createNotification("Passed", "", "OK", "false")
- .setFieldValue("branch", "feature");
+ .setFieldValue("branch", "feature");
EmailMessage message = template.format(notification);
assertThat(message.getMessageId(), is("alerts/45"));
private Notification createNotification(String alertName, String alertText, String alertLevel, String isNewAlert) {
return new Notification("alerts")
- .setFieldValue("projectName", "Foo")
- .setFieldValue("projectKey", "org.sonar.foo:foo")
- .setFieldValue("projectId", "45")
- .setFieldValue("projectVersion", "V1-SNAP")
- .setFieldValue("alertName", alertName)
- .setFieldValue("alertText", alertText)
- .setFieldValue("alertLevel", alertLevel)
- .setFieldValue("isNewAlert", isNewAlert)
- .setFieldValue("ratingMetrics", "Maintainability Rating,Reliability Rating on New Code," +
- "Maintainability Rating on New Code,Reliability Rating," +
- "Security Rating on New Code,Security Review Rating," +
- "Security Review Rating on New Code,Security Rating");
+ .setFieldValue("projectName", "Foo")
+ .setFieldValue("projectKey", "org.sonar.foo:foo")
+ .setFieldValue("projectId", "45")
+ .setFieldValue("projectVersion", "V1-SNAP")
+ .setFieldValue("alertName", alertName)
+ .setFieldValue("alertText", alertText)
+ .setFieldValue("alertLevel", alertLevel)
+ .setFieldValue("isNewAlert", isNewAlert)
+ .setFieldValue("ratingMetrics", "Maintainability Rating,Reliability Rating on New Code," +
+ "Maintainability Rating on New Code,Reliability Rating," +
+ "Security Rating on New Code,Security Review Rating," +
+ "Security Review Rating on New Code,Security Rating");
}
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.qualitygate;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-/**
- * Store number of projects in warning in order for the web service api/components/search to know if warning value should be return in the quality gate facet.
- * The value is updated each time the daemon {@link ProjectsInWarningDaemon} is executed
- */
-public class ProjectsInWarning {
-
- private Long projectsInWarning;
-
- public void update(long projectsInWarning) {
- this.projectsInWarning = projectsInWarning;
- }
-
- public long count() {
- checkArgument(isInitialized(), "Initialization has not be done");
- return projectsInWarning;
- }
-
- boolean isInitialized() {
- return projectsInWarning != null;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.qualitygate;
-
-import javax.annotation.ParametersAreNonnullByDefault;
Optional.ofNullable(ruleDescriptionFormatter.getDescriptionAsHtml(ruleDto)).ifPresent(apiRule::setDescription);
Optional.ofNullable(ruleDto.getLanguage()).ifPresent(apiRule::setLanguage);
- List<org.sonar.api.rules.RuleParam> apiParams = new ArrayList<>();
for (RuleParamDto param : params) {
- apiParams.add(new org.sonar.api.rules.RuleParam(apiRule, param.getName(), param.getDescription(), param.getType())
- .setDefaultValue(param.getDefaultValue()));
+ apiRule.createParameter()
+ .setDescription(param.getDescription())
+ .setKey(param.getName())
+ .setType(param.getType())
+ .setDefaultValue(param.getDefaultValue());
}
- apiRule.setParams(apiParams);
return apiRule;
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.util;
-
-import java.util.List;
-import javax.annotation.Nullable;
-import org.sonar.api.PropertyType;
-import org.sonar.server.exceptions.BadRequestException;
-
-import static java.lang.String.format;
-
-public class LongTypeValidation implements TypeValidation {
- @Override
- public String key() {
- return PropertyType.LONG.name();
- }
-
- @Override
- public void validate(String value, @Nullable List<String> options) {
- try {
- Long.parseLong(value);
- } catch (NumberFormatException e) {
- throw BadRequestException.create(format("Value '%s' must be a long.", value));
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.util;
-
-import java.util.List;
-import javax.annotation.Nullable;
-import org.sonar.api.PropertyType;
-import org.sonar.api.measures.Metric;
-import org.sonar.server.exceptions.BadRequestException;
-
-import static java.lang.String.format;
-
-public class MetricLevelTypeValidation implements TypeValidation {
- @Override
- public String key() {
- return PropertyType.METRIC_LEVEL.name();
- }
-
- @Override
- public void validate(String value, @Nullable List<String> options) {
- try {
- Metric.Level.valueOf(value);
- } catch (IllegalArgumentException e) {
- throw BadRequestException.create(format("Value '%s' must be one of \"OK\", \"ERROR\".", value));
- }
- }
-}
BooleanTypeValidation.class,
TextTypeValidation.class,
StringTypeValidation.class,
- StringListTypeValidation.class,
- LongTypeValidation.class,
- MetricLevelTypeValidation.class
+ StringListTypeValidation.class
);
}
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.util;
-
-import org.junit.Test;
-import org.sonar.api.PropertyType;
-import org.sonar.server.exceptions.BadRequestException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-public class LongTypeValidationTest {
-
- LongTypeValidation underTest = new LongTypeValidation();
-
- @Test
- public void key_is_long_type_name() {
- assertThat(underTest.key()).isEqualTo(PropertyType.LONG.name());
- }
-
- @Test
- public void do_not_fail_with_long_values() {
- underTest.validate("1984", null);
- underTest.validate("-1984", null);
- }
-
- @Test
- public void fail_when_float() {
- assertThatThrownBy(() -> underTest.validate("3.14", null))
- .isInstanceOf(BadRequestException.class)
- .hasMessage("Value '3.14' must be a long.");
- }
-
- @Test
- public void fail_when_string() {
- assertThatThrownBy(() -> underTest.validate("original string", null))
- .isInstanceOf(BadRequestException.class)
- .hasMessage("Value 'original string' must be a long.");
- }
-}
public void verify_count_of_added_components() {
ListContainer container = new ListContainer();
new TypeValidationModule().configure(container);
- assertThat(container.getAddedObjects()).hasSize(9);
+ assertThat(container.getAddedObjects()).hasSize(7);
}
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.user;
-
-import org.sonar.api.security.LoginPasswordAuthenticator;
-import org.sonar.api.security.SecurityRealm;
-
-/**
- * Provides backward compatibility for {@link org.sonar.api.CoreProperties#CORE_AUTHENTICATOR_CLASS}.
- *
- * @since 2.14
- */
-class CompatibilityRealm extends SecurityRealm {
- private final LoginPasswordAuthenticator authenticator;
-
- public CompatibilityRealm(LoginPasswordAuthenticator authenticator) {
- this.authenticator = authenticator;
- }
-
- @Override
- public void init() {
- authenticator.init();
- }
-
- @Override
- public String getName() {
- return "CompatibilityRealm[" + authenticator.getClass().getName() + "]";
- }
-
- @Override
- public LoginPasswordAuthenticator getLoginPasswordAuthenticator() {
- return authenticator;
- }
-}
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
import org.sonar.api.Startable;
import org.sonar.api.config.Configuration;
-import org.sonar.api.security.LoginPasswordAuthenticator;
import org.sonar.api.security.SecurityRealm;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.SonarException;
private final SecurityRealm realm;
@Autowired(required = false)
- public SecurityRealmFactory(Configuration config, SecurityRealm[] realms, LoginPasswordAuthenticator[] authenticators) {
+ public SecurityRealmFactory(Configuration config, SecurityRealm[] realms) {
ignoreStartupFailure = config.getBoolean(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey()).orElse(false);
String realmName = config.get(SONAR_SECURITY_REALM.getKey()).orElse(null);
- String className = config.get(CoreProperties.CORE_AUTHENTICATOR_CLASS).orElse(null);
if (LDAP_SECURITY_REALM.equals(realmName)) {
realm = null;
"Realm '%s' not found. Please check the property '%s' in conf/sonar.properties", realmName, SONAR_SECURITY_REALM.getKey()));
}
}
- if (selectedRealm == null && !StringUtils.isEmpty(className)) {
- LoginPasswordAuthenticator authenticator = selectAuthenticator(authenticators, className);
- if (authenticator == null) {
- throw new SonarException(String.format(
- "Authenticator '%s' not found. Please check the property '%s' in conf/sonar.properties", className, CoreProperties.CORE_AUTHENTICATOR_CLASS));
- }
- selectedRealm = new CompatibilityRealm(authenticator);
- }
- realm = selectedRealm;
- }
-
- @Autowired(required = false)
- public SecurityRealmFactory(Configuration config, LoginPasswordAuthenticator[] authenticators) {
- this(config, new SecurityRealm[0], authenticators);
- }
+ realm = selectedRealm;
- @Autowired(required = false)
- public SecurityRealmFactory(Configuration config, SecurityRealm[] realms) {
- this(config, realms, new LoginPasswordAuthenticator[0]);
}
@Autowired(required = false)
public SecurityRealmFactory(Configuration config) {
- this(config, new SecurityRealm[0], new LoginPasswordAuthenticator[0]);
+ this(config, new SecurityRealm[0]);
}
@Override
}
return null;
}
-
- private static LoginPasswordAuthenticator selectAuthenticator(LoginPasswordAuthenticator[] authenticators, String className) {
- for (LoginPasswordAuthenticator lpa : authenticators) {
- if (lpa.getClass().getName().equals(className)) {
- return lpa;
- }
- }
- return null;
- }
-
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.user;
-
-import org.junit.Test;
-import org.sonar.api.security.LoginPasswordAuthenticator;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class CompatibilityRealmTest {
-
- @Test
- public void shouldDelegate() {
- LoginPasswordAuthenticator authenticator = mock(LoginPasswordAuthenticator.class);
- CompatibilityRealm realm = new CompatibilityRealm(authenticator);
- realm.init();
- verify(authenticator).init();
- assertThat(realm.getLoginPasswordAuthenticator()).isSameAs(authenticator);
- assertThat(realm.getName()).isEqualTo("CompatibilityRealm[" + authenticator.getClass().getName() + "]");
- }
-
-}
import org.junit.Test;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.internal.MapSettings;
-import org.sonar.api.security.LoginPasswordAuthenticator;
+import org.sonar.api.security.Authenticator;
import org.sonar.api.security.SecurityRealm;
import org.sonar.api.utils.SonarException;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.sonar.process.ProcessProperties.Property.SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE;
public class SecurityRealmFactoryTest {
}
}
- @Test
- public void should_provide_compatibility_for_authenticator() {
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName());
- LoginPasswordAuthenticator authenticator = new FakeAuthenticator();
-
- SecurityRealmFactory factory = new SecurityRealmFactory(settings.asConfig(), new LoginPasswordAuthenticator[] {authenticator});
- SecurityRealm realm = factory.getRealm();
- assertThat(realm).isInstanceOf(CompatibilityRealm.class);
- }
-
- @Test
- public void should_take_precedence_over_authenticator() {
- SecurityRealm realm = new FakeRealm();
- settings.setProperty("sonar.security.realm", realm.getName());
- LoginPasswordAuthenticator authenticator = new FakeAuthenticator();
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName());
-
- SecurityRealmFactory factory = new SecurityRealmFactory(settings.asConfig(), new SecurityRealm[] {realm},
- new LoginPasswordAuthenticator[] {authenticator});
- assertThat(factory.getRealm()).isSameAs(realm);
- }
-
- @Test
- public void authenticator_not_found() {
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, "Fake");
-
- try {
- new SecurityRealmFactory(settings.asConfig());
- fail();
- } catch (SonarException e) {
- assertThat(e.getMessage()).contains("Authenticator 'Fake' not found.");
- }
- }
-
@Test
public void ignore_startup_failure() {
SecurityRealm realm = spy(new AlwaysFailsRealm());
settings.setProperty("sonar.security.realm", realm.getName());
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE, true);
+ settings.setProperty(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey(), true);
new SecurityRealmFactory(settings.asConfig(), new SecurityRealm[] {realm}).start();
verify(realm).init();
private static class FakeRealm extends SecurityRealm {
@Override
- public LoginPasswordAuthenticator getLoginPasswordAuthenticator() {
+ public Authenticator doGetAuthenticator() {
return null;
}
}
-
- private static class FakeAuthenticator implements LoginPasswordAuthenticator {
- public void init() {
- }
-
- public boolean authenticate(String login, String password) {
- return false;
- }
- }
-
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.qualitygate;
-
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import java.util.Optional;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import org.sonar.api.Startable;
-import org.sonar.api.config.Configuration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.measure.index.ProjectMeasuresIndex;
-import org.sonar.server.measure.index.ProjectMeasuresQuery;
-import org.sonar.server.util.GlobalLockManager;
-
-import static org.sonar.api.measures.Metric.Level.WARN;
-
-/**
- * This class is regularly checking the number of projects in warning state, in order to not return the "Warning" value
- * in the quality gate facet of the Projects page when there are no more projects in warning.
- *
- * @see <a href="https://jira.sonarsource.com/browse/SONAR-12140">SONAR-12140</a> for more information
- */
-public class ProjectsInWarningDaemon implements Startable {
-
- static final String PROJECTS_IN_WARNING_INTERNAL_PROPERTY = "projectsInWarning";
-
- private static final Logger LOG = LoggerFactory.getLogger(ProjectsInWarningDaemon.class);
-
- private static final String FREQUENCY_IN_MILLISECONDS_PROPERTY = "sonar.projectsInWarning.frequencyInMilliseconds";
- private static final int DEFAULT_FREQUENCY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
- private static final String THREAD_NAME_PREFIX = "sq-projects-in-warning-service-";
-
- private static final String LOCK_NAME = "ProjectsInWarn";
- private static final int LOCK_DURATION_IN_SECOND = 60 * 60;
-
- private final DbClient dbClient;
- private final ProjectMeasuresIndex projectMeasuresIndex;
- private final Configuration config;
- private final GlobalLockManager lockManager;
- private final ProjectsInWarning projectsInWarning;
-
- private ScheduledExecutorService executorService;
-
- public ProjectsInWarningDaemon(DbClient dbClient, ProjectMeasuresIndex projectMeasuresIndex, Configuration config, GlobalLockManager lockManager,
- ProjectsInWarning projectsInWarning) {
- this.dbClient = dbClient;
- this.projectMeasuresIndex = projectMeasuresIndex;
- this.config = config;
- this.lockManager = lockManager;
- this.projectsInWarning = projectsInWarning;
- }
-
- public void notifyStart() {
- try (DbSession dbSession = dbClient.openSession(false)) {
- Optional<String> internalProperty = dbClient.internalPropertiesDao().selectByKey(dbSession, PROJECTS_IN_WARNING_INTERNAL_PROPERTY);
- if (internalProperty.isPresent() && internalProperty.get().equals("0")) {
- projectsInWarning.update(0L);
- LOG.info("Counting number of projects in warning is not started as there are no projects in this situation.");
- return;
- }
- }
- LOG.info("Counting number of projects in warning is enabled.");
- executorService = Executors.newSingleThreadScheduledExecutor(newThreadFactory());
- executorService.scheduleWithFixedDelay(countProjectsInWarning(), 0, frequency(), TimeUnit.MILLISECONDS);
- }
-
- private int frequency() {
- return config.getInt(FREQUENCY_IN_MILLISECONDS_PROPERTY).orElse(DEFAULT_FREQUENCY_IN_MILLISECONDS);
- }
-
- private Runnable countProjectsInWarning() {
- return () -> {
- long nbProjectsInWarning = projectMeasuresIndex.search(
- new ProjectMeasuresQuery()
- .setQualityGateStatus(WARN)
- .setIgnoreAuthorization(true),
- // We only need the number of projects in warning
- new SearchOptions().setLimit(1)).getTotal();
-
- try (DbSession dbSession = dbClient.openSession(false)) {
- updateProjectsInWarningInDb(dbSession, nbProjectsInWarning);
- } catch (Exception e) {
- LOG.error("Error updating number of projects in warning: {}", e.getMessage(), e);
- }
- projectsInWarning.update(nbProjectsInWarning);
- if (nbProjectsInWarning == 0L) {
- LOG.info("Counting number of projects in warning will be disabled as there are no more projects in warning.");
- executorService.shutdown();
- }
- };
- }
-
- private void updateProjectsInWarningInDb(DbSession dbSession, long nbProjectsInWarning) {
- // Only one web node should do the update in db to avoid any collision
- if (!lockManager.tryLock(LOCK_NAME, LOCK_DURATION_IN_SECOND)) {
- return;
- }
- dbClient.internalPropertiesDao().save(dbSession, PROJECTS_IN_WARNING_INTERNAL_PROPERTY, Long.toString(nbProjectsInWarning));
- dbSession.commit();
- }
-
- @Override
- public void start() {
- // Nothing is done here, as this component needs to be started after ES indexing. See PlatformLevelStartup for more info.
- }
-
- @Override
- public void stop() {
- if (executorService == null) {
- return;
- }
- try {
- executorService.shutdown();
- executorService.awaitTermination(5, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
-
- private static ThreadFactory newThreadFactory() {
- return new ThreadFactoryBuilder()
- .setNameFormat(THREAD_NAME_PREFIX + "%d")
- .setPriority(Thread.MIN_PRIORITY)
- .build();
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.qualitygate;
-
-import org.sonar.core.platform.Module;
-
-public class ProjectsInWarningModule extends Module {
- @Override
- protected void configureModule() {
- add(
- ProjectsInWarningDaemon.class,
- ProjectsInWarning.class
-
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.qualitygate;
-
-import javax.annotation.ParametersAreNonnullByDefault;
import org.junit.Test;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import static org.assertj.core.api.Assertions.assertThat;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.config.internal.Settings;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.qualitygate;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.slf4j.event.Level;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.testfixtures.log.LogTester;
-import org.sonar.api.utils.System2;
-import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ProjectData;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.measure.index.ProjectMeasuresIndex;
-import org.sonar.server.measure.index.ProjectMeasuresIndexer;
-import org.sonar.server.permission.index.PermissionIndexerTester;
-import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
-import org.sonar.server.util.GlobalLockManager;
-import org.sonar.server.util.GlobalLockManagerImpl;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.sonar.api.measures.Metric.Level.WARN;
-import static org.sonar.db.measure.MeasureTesting.newLiveMeasure;
-import static org.sonar.server.qualitygate.ProjectsInWarningDaemon.PROJECTS_IN_WARNING_INTERNAL_PROPERTY;
-
-public class ProjectsInWarningDaemonTest {
-
- @Rule
- public DbTester db = DbTester.create();
- @Rule
- public EsTester es = EsTester.create();
- @Rule
- public LogTester logger = new LogTester().setLevel(LoggerLevel.DEBUG);
-
- private final PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es, new ProjectMeasuresIndexer(db.getDbClient(), es.client()));
- private final ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(db.getDbClient(), es.client());
- private final ProjectMeasuresIndex projectMeasuresIndex = new ProjectMeasuresIndex(es.client(), new WebAuthorizationTypeSupport(null), System2.INSTANCE);
-
- private final MapSettings settings = new MapSettings();
- private final GlobalLockManager lockManager = mock(GlobalLockManagerImpl.class);
- private final ProjectsInWarning projectsInWarning = new ProjectsInWarning();
-
- private final ProjectsInWarningDaemon underTest = new ProjectsInWarningDaemon(db.getDbClient(), projectMeasuresIndex, settings.asConfig(), lockManager, projectsInWarning);
-
- @Before
- public void setUp() {
- settings.setProperty("sonar.projectsInWarning.frequencyInMilliseconds", "100");
- }
-
- @After
- public void tearDown() {
- underTest.stop();
- }
-
- @Test
- public void store_projects_in_warning() throws InterruptedException {
- allowLockToBeAcquired();
- MetricDto qualityGateStatus = insertQualityGateStatusMetric();
- insertProjectInWarning(qualityGateStatus);
- insertProjectInWarning(qualityGateStatus);
- // Setting does not exist
- assertThat(db.getDbClient().internalPropertiesDao().selectByKey(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY)).isEmpty();
-
- underTest.notifyStart();
-
- assertProjectsInWarningValue(2L);
- assertThat(logger.logs(Level.INFO)).contains("Counting number of projects in warning is enabled.");
- }
-
- @Test
- public void update_projects_in_warning_when_new_project_in_warning() throws InterruptedException {
- allowLockToBeAcquired();
- MetricDto qualityGateStatus = insertQualityGateStatusMetric();
- insertProjectInWarning(qualityGateStatus);
- insertProjectInWarning(qualityGateStatus);
- // Setting does not exist
- assertThat(db.getDbClient().internalPropertiesDao().selectByKey(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY)).isEmpty();
-
- underTest.notifyStart();
- // Add a project in warning after the start in order to let the thread do his job
- insertProjectInWarning(qualityGateStatus);
-
- assertProjectsInWarningValue(3L);
- assertThat(logger.logs(Level.INFO)).contains("Counting number of projects in warning is enabled.");
- }
-
- @Test
- public void stop_thread_when_number_of_projects_in_warning_reach_zero() throws InterruptedException {
- allowLockToBeAcquired();
- MetricDto qualityGateStatus = insertQualityGateStatusMetric();
- ProjectData project = insertProjectInWarning(qualityGateStatus);
-
- underTest.notifyStart();
- assertProjectsInWarningValue(1L);
- // Set quality gate status of the project to OK => No more projects in warning
- db.getDbClient().liveMeasureDao().insertOrUpdate(db.getSession(),
- newLiveMeasure(project.getMainBranchComponent(), qualityGateStatus).setData(Metric.Level.OK.name()).setValue(null));
- db.commit();
- projectMeasuresIndexer.indexOnAnalysis(project.mainBranchUuid());
-
- assertProjectsInWarningValue(0L);
- assertThat(logger.logs(Level.INFO))
- .contains(
- "Counting number of projects in warning is enabled.",
- "Counting number of projects in warning will be disabled as there are no more projects in warning.");
- }
-
- @Test
- public void update_internal_properties_when_already_exits_and_projects_in_warnings_more_than_zero() throws InterruptedException {
- allowLockToBeAcquired();
- MetricDto qualityGateStatus = insertQualityGateStatusMetric();
- insertProjectInWarning(qualityGateStatus);
- insertProjectInWarning(qualityGateStatus);
- // Setting contains 10, it should be updated with new value
- db.getDbClient().internalPropertiesDao().save(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY, "10");
- db.commit();
-
- underTest.notifyStart();
-
- assertProjectsInWarningValue(2L);
- assertThat(logger.logs(Level.INFO)).contains("Counting number of projects in warning is enabled.");
- }
-
- @Test
- public void store_zero_projects_in_warning_when_no_projects() throws InterruptedException {
- allowLockToBeAcquired();
- assertThat(db.getDbClient().internalPropertiesDao().selectByKey(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY)).isEmpty();
-
- underTest.notifyStart();
-
- assertProjectsInWarningValue(0L);
- assertThat(logger.logs(Level.INFO)).contains("Counting number of projects in warning is enabled.");
- }
-
- @Test
- public void do_not_compute_projects_in_warning_when_internal_property_is_zero() throws InterruptedException {
- allowLockToBeAcquired();
- MetricDto qualityGateStatus = insertQualityGateStatusMetric();
- insertProjectInWarning(qualityGateStatus);
- // Setting contains 0, even if there are projects in warning it will stay 0 (as it's not possible to have new projects in warning)
- db.getDbClient().internalPropertiesDao().save(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY, "0");
- db.commit();
-
- underTest.notifyStart();
-
- assertProjectsInWarningValue(0L);
- assertThat(logger.logs(Level.INFO)).contains("Counting number of projects in warning is not started as there are no projects in this situation.");
- }
-
- @Test
- public void do_not_store_projects_in_warning_in_db_when_cannot_acquire_lock() throws InterruptedException {
- when(lockManager.tryLock(any(), anyInt())).thenReturn(false);
- MetricDto qualityGateStatus = insertQualityGateStatusMetric();
- insertProjectInWarning(qualityGateStatus);
-
- underTest.notifyStart();
-
- waitForValueToBeComputed(1L);
- assertThat(projectsInWarning.count()).isOne();
- assertThat(countNumberOfProjectsInWarning()).isZero();
- }
-
- private void waitForValueToBeComputed(long expectedValue) throws InterruptedException {
- for (int i = 0; i < 1000; i++) {
- if (projectsInWarning.isInitialized() && projectsInWarning.count() == expectedValue) {
- break;
- }
- Thread.sleep(100);
- }
- }
-
- private void assertProjectsInWarningValue(long expectedValue) throws InterruptedException {
- waitForValueToBeComputed(expectedValue);
- assertThat(projectsInWarning.count()).isEqualTo(expectedValue);
- assertThat(countNumberOfProjectsInWarning()).isEqualTo(expectedValue);
- }
-
- private long countNumberOfProjectsInWarning() {
- return db.getDbClient().internalPropertiesDao().selectByKey(db.getSession(), PROJECTS_IN_WARNING_INTERNAL_PROPERTY)
- .map(Long::valueOf)
- .orElse(0L);
- }
-
- private ProjectData insertProjectInWarning(MetricDto qualityGateStatus) {
- ProjectData project = db.components().insertPrivateProject();
- db.measures().insertLiveMeasure(project, qualityGateStatus, lm -> lm.setData(WARN.name()).setValue(null));
- authorizationIndexerTester.allowOnlyAnyone(project.getProjectDto());
- projectMeasuresIndexer.indexOnAnalysis(project.mainBranchUuid());
- return project;
- }
-
- private MetricDto insertQualityGateStatusMetric() {
- return db.measures().insertMetric(m -> m.setKey(CoreMetrics.ALERT_STATUS_KEY).setValueType(Metric.ValueType.LEVEL.name()));
- }
-
- private void allowLockToBeAcquired() {
- when(lockManager.tryLock(any(), anyInt())).thenReturn(true);
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.qualitygate;
-
-import org.junit.Test;
-import org.sonar.core.platform.ListContainer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ProjectsInWarningModuleTest {
- @Test
- public void verify_count_of_added_components() {
- ListContainer container = new ListContainer();
- new ProjectsInWarningModule().configure(container);
- assertThat(container.getAddedObjects()).hasSize(2);
- }
-}
return this;
}
- @CheckForNull
- @Override
- public String getPermanentServerId() {
- return null;
- }
-
@Override
public String getVersion() {
return this.version;
public String getPublicRootUrl() {
return null;
}
-
- @Override
- public boolean isSecured() {
- return false;
- }
-
}
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.NestedSortBuilder;
-import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.System2;
.subAggregation(rangeAgg));
}
- private static AbstractAggregationBuilder<?> createQualityGateFacet(ProjectMeasuresQuery projectMeasuresQuery) {
+ private static AbstractAggregationBuilder<?> createQualityGateFacet() {
return filters(
ALERT_STATUS_KEY,
QUALITY_GATE_STATUS
.entrySet()
.stream()
- .filter(qgs -> !(projectMeasuresQuery.isIgnoreWarning() && qgs.getKey().equals(Metric.Level.WARN.name())))
.map(entry -> new KeyedFilter(entry.getKey(), termQuery(FIELD_QUALITY_GATE_STATUS, entry.getValue())))
.toArray(KeyedFilter[]::new));
}
TermsAggregationBuilder tagFacet = AggregationBuilders.terms(FIELD_TAGS)
.field(FIELD_TAGS)
- .size(size*page)
+ .size(size * page)
.minDocCount(1)
.order(BucketOrder.key(true));
if (textQuery != null) {
Terms aggregation = response.getAggregations().get(FIELD_TAGS);
return aggregation.getBuckets().stream()
- .skip((page-1) * size)
+ .skip((page - 1) * size)
.map(Bucket::getKeyAsString)
.toList();
}
return topAggregationHelper.buildTopAggregation(
facet.getName(), facet.getTopAggregationDef(),
NO_EXTRA_FILTER,
- t -> t.subAggregation(createQualityGateFacet(query)));
+ t -> t.subAggregation(createQualityGateFacet()));
}
private static FilterAggregationBuilder buildTagsFacet(Facet facet, ProjectMeasuresQuery query, TopAggregationHelper topAggregationHelper) {
import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
assertThat(result).containsOnly(
entry(ERROR.name(), 4L),
- entry(OK.name(), 2L),
- entry(WARN.name(), 0L));
+ entry(OK.name(), 2L));
}
@Test
// Sticky facet on quality gate does not take into account quality gate filter
assertThat(facets.get(ALERT_STATUS_KEY)).containsOnly(
entry(OK.name(), 2L),
- entry(ERROR.name(), 3L),
- entry(WARN.name(), 0L));
+ entry(ERROR.name(), 3L));
// But facet on ncloc does well take into into filters
assertThat(facets.get(NCLOC)).containsExactly(
entry("*-1000.0", 1L),
assertThat(result).containsOnly(
entry(ERROR.name(), 0L),
- entry(OK.name(), 2L),
- entry(WARN.name(), 0L));
- }
-
- @Test
- public void facet_quality_gate_using_deprecated_warning() {
- index(
- // 2 docs with QG OK
- newDoc().setQualityGateStatus(OK.name()),
- newDoc().setQualityGateStatus(OK.name()),
- // 3 docs with QG WARN
- newDoc().setQualityGateStatus(WARN.name()),
- newDoc().setQualityGateStatus(WARN.name()),
- newDoc().setQualityGateStatus(WARN.name()),
- // 4 docs with QG ERROR
- newDoc().setQualityGateStatus(ERROR.name()),
- newDoc().setQualityGateStatus(ERROR.name()),
- newDoc().setQualityGateStatus(ERROR.name()),
- newDoc().setQualityGateStatus(ERROR.name()));
-
- LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY);
-
- assertThat(result).containsOnly(
- entry(ERROR.name(), 4L),
- entry(WARN.name(), 3L),
- entry(OK.name(), 2L));
- }
-
- @Test
- public void facet_quality_gate_does_not_return_deprecated_warning_when_set_ignore_warning_is_true() {
- index(
- // 2 docs with QG OK
- newDoc().setQualityGateStatus(OK.name()),
- newDoc().setQualityGateStatus(OK.name()),
- // 4 docs with QG ERROR
- newDoc().setQualityGateStatus(ERROR.name()),
- newDoc().setQualityGateStatus(ERROR.name()),
- newDoc().setQualityGateStatus(ERROR.name()),
- newDoc().setQualityGateStatus(ERROR.name()));
-
- assertThat(underTest.search(new ProjectMeasuresQuery().setIgnoreWarning(true), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY)).containsOnly(
- entry(ERROR.name(), 4L),
entry(OK.name(), 2L));
- assertThat(underTest.search(new ProjectMeasuresQuery().setIgnoreWarning(false), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY))
- .containsOnly(
- entry(ERROR.name(), 4L),
- entry(WARN.name(), 0L),
- entry(OK.name(), 2L));
}
@Test
entry("cpp", 1L));
assertThat(facets.get(ALERT_STATUS_KEY)).containsOnly(
entry(OK.name(), 0L),
- entry(ERROR.name(), 1L),
- entry(WARN.name(), 0L));
+ entry(ERROR.name(), 1L));
}
@Test
import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
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.PERCENT;
import static org.sonar.server.badge.ws.SvgGenerator.Color.DEFAULT;
import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_ERROR;
import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_OK;
-import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_WARN;
@RunWith(DataProviderRunner.class)
public class MeasureActionIT {
}
- @Test
- public void display_deprecated_warning_quality_gate() {
- ProjectData projectData = db.components().insertPublicProject();
- ComponentDto project = projectData.getMainBranchComponent();
-
- userSession.registerProjects(projectData.getProjectDto());
- MetricDto metric = createQualityGateMetric();
- db.measures().insertLiveMeasure(project, metric, m -> m.setData(WARN.name()));
-
- TestResponse response = ws.newRequest()
- .setParam("project", project.getKey())
- .setParam("metric", metric.getKey())
- .execute();
-
- checkSvg(response, "quality gate", "warning", QUALITY_GATE_WARN);
- }
-
@Test
public void measure_on_non_main_branch() {
ProjectData projectData = db.components().insertPublicProject(p -> p.setPrivate(false));
import org.sonar.server.measure.index.ProjectMeasuresIndexer;
import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
-import org.sonar.server.qualitygate.ProjectsInWarning;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es, new ProjectMeasuresIndexer(dbClient, es.client()));
private ProjectMeasuresIndex index = new ProjectMeasuresIndex(es.client(), new WebAuthorizationTypeSupport(userSession), System2.INSTANCE);
private ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(db.getDbClient(), es.client());
- private ProjectsInWarning projectsInWarning = new ProjectsInWarning();
- private WsActionTester ws = new WsActionTester(new SearchProjectsAction(dbClient, index, userSession, projectsInWarning, editionProviderMock,
+ private WsActionTester ws = new WsActionTester(new SearchProjectsAction(dbClient, index, userSession, editionProviderMock,
new IssueIndexSyncProgressChecker(db.getDbClient())));
private RequestBuilder request = SearchProjectsRequest.builder();
- @Before
- public void setUp() {
- projectsInWarning.update(0L);
- }
-
@Test
public void verify_definition() {
WebService.Action def = ws.getDef();
MetricDto qualityGateStatus = db.measures().insertMetric(c -> c.setKey(ALERT_STATUS_KEY).setValueType(LEVEL.name()));
insertProject(new Measure(qualityGateStatus, c -> c.setData(Metric.Level.ERROR.name()).setValue(null)));
insertProject(new Measure(qualityGateStatus, c -> c.setData(Metric.Level.ERROR.name()).setValue(null)));
- insertProject(new Measure(qualityGateStatus, c -> c.setData(Metric.Level.WARN.name()).setValue(null)));
insertProject(new Measure(qualityGateStatus, c -> c.setData(Metric.Level.OK.name()).setValue(null)));
- projectsInWarning.update(1L);
index();
SearchProjectsWsResponse result = call(request.setFacets(singletonList(ALERT_STATUS_KEY)));
.extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
.containsOnly(
tuple("OK", 1L),
- tuple("ERROR", 2L),
- tuple("WARN", 1L));
+ tuple("ERROR", 2L));
}
@Test
insertProject(new Measure(qualityGateStatus, c -> c.setData(Metric.Level.ERROR.name()).setValue(null)));
insertProject(new Measure(qualityGateStatus, c -> c.setData(Metric.Level.ERROR.name()).setValue(null)));
insertProject(new Measure(qualityGateStatus, c -> c.setData(Metric.Level.OK.name()).setValue(null)));
- projectsInWarning.update(0L);
index();
SearchProjectsWsResponse result = call(request.setFacets(singletonList(ALERT_STATUS_KEY)));
.containsExactlyInAnyOrder(project.getKey());
}
- @Test
- public void use_deprecated_warning_quality_gate_in_filter() {
- userSession.logIn();
- MetricDto qualityGateStatus = db.measures().insertMetric(c -> c.setKey(QUALITY_GATE_STATUS).setValueType(LEVEL.name()));
- ComponentDto project1 = insertProject(c -> c.setName("Sonar Java"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("ERROR")));
- ComponentDto project2 = insertProject(c -> c.setName("Sonar Groovy"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("WARN")));
- ComponentDto project3 = insertProject(c -> c.setName("Sonar Markdown"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("WARN")));
- ComponentDto project4 = insertProject(c -> c.setName("Sonar Qube"), new Measure(qualityGateStatus, c -> c.setValue(null).setData("OK")));
- index();
-
- List<Component> projects = call(request
- .setFilter("alert_status = WARN"))
- .getComponentsList();
-
- assertThat(projects)
- .extracting(Component::getKey)
- .containsExactly(project2.getKey(), project3.getKey());
- }
-
@Test
public void fail_when_filter_metrics_are_unknown() {
userSession.logIn();
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.junit.Rule;
import org.junit.Test;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.notifications.Notification;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.ws.RemoveAction.RemoveRequest;
import org.sonar.server.tester.UserSessionRule;
assertThat(definition.getFields(1).getOptionsList()).containsExactly("one", "two");
}
- @Test
- public void return_license_type_in_property_set() {
- logIn();
- propertyDefinitions.addComponent(PropertyDefinition
- .builder("foo")
- .type(PropertyType.PROPERTY_SET)
- .fields(PropertyFieldDefinition.build("license").name("License").type(PropertyType.LICENSE).build())
- .build());
-
- ListDefinitionsWsResponse result = executeRequest();
-
- assertThat(result.getDefinitionsList()).hasSize(1);
- assertThat(result.getDefinitions(0).getFieldsList()).extracting(Settings.Field::getKey, Settings.Field::getType).containsOnly(tuple("license", LICENSE));
- }
-
@Test
public void return_global_settings_definitions() {
logIn();
assertThat(result.getDefinitionsList()).isEmpty();
}
- @Test
- public void return_license_type() {
- logInAsAdmin();
- propertyDefinitions.addComponents(asList(
- PropertyDefinition.builder("plugin.license.secured").type(PropertyType.LICENSE).build(),
- PropertyDefinition.builder("commercial.plugin").type(PropertyType.LICENSE).build()));
-
- ListDefinitionsWsResponse result = executeRequest();
-
- assertThat(result.getDefinitionsList()).extracting(Definition::getKey, Definition::getType)
- .containsOnly(tuple("plugin.license.secured", LICENSE), tuple("commercial.plugin", LICENSE));
- }
-
@Test
public void does_not_returned_secured_and_license_settings_when_not_authenticated() {
propertyDefinitions.addComponents(asList(
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", List.of("metric_key_1", "metric_key_2"));
-
- assertGlobalSetting("my_key", "metric_key_1,metric_key_2");
- }
-
@Test
public void persist_multi_value_with_type_logIn() {
definitions.addComponent(PropertyDefinition
.hasMessage("Not an integer error message");
}
- @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"));
- dbClient.metricDao().insert(dbSession, newMetricDto().setKey("metric_disabled_key").setEnabled(false));
- dbSession.commit();
-
- List<String> values = List.of("metric_key", "metric_disabled_key");
- assertThatThrownBy(() -> callForMultiValueGlobalSetting("my_key", values))
- .isInstanceOf(BadRequestException.class)
- .hasMessage("Error when validating metric setting with key 'my_key' and values [metric_key, metric_disabled_key]. A value is not a valid metric key.");
- }
-
@Test
public void fail_when_data_and_login_type_with_invalid_logIn() {
definitions.addComponent(PropertyDefinition
import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY;
import static org.sonar.api.measures.CoreMetrics.VULNERABILITIES_KEY;
import static org.sonar.api.measures.Metric.Level;
-import static org.sonar.api.measures.Metric.ValueType;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
+import static org.sonar.api.measures.Metric.ValueType;
import static org.sonar.server.badge.ws.ETagUtils.RFC1123_DATE;
import static org.sonar.server.badge.ws.ETagUtils.getETag;
import static org.sonar.server.badge.ws.SvgFormatter.formatDuration;
private static final Map<Level, String> QUALITY_GATE_MESSAGE_BY_STATUS = new EnumMap<>(Map.of(
OK, "passed",
- WARN, "warning",
ERROR, "failed"));
private static final Map<Level, Color> COLOR_BY_QUALITY_GATE_STATUS = new EnumMap<>(Map.of(
OK, Color.QUALITY_GATE_OK,
- WARN, Color.QUALITY_GATE_WARN,
ERROR, Color.QUALITY_GATE_ERROR));
private static final Map<Rating, Color> COLOR_BY_RATING = new EnumMap<>(Map.of(
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
-import static org.sonar.api.measures.Metric.Level.WARN;
@ServerSide
public class SvgGenerator {
this.badgeTemplate = readTemplate(TEMPLATES_PATH + "/badge.svg");
this.qualityGateTemplates = Map.of(
OK, readTemplate(TEMPLATES_PATH + "/quality_gate_passed.svg"),
- WARN, readTemplate(TEMPLATES_PATH + "/quality_gate_warn.svg"),
ERROR, readTemplate(TEMPLATES_PATH + "/quality_gate_failed.svg"));
}
static class Color {
static final Color DEFAULT = new Color("#999999");
static final Color QUALITY_GATE_OK = new Color("#00aa00");
- static final Color QUALITY_GATE_WARN = new Color("#ed7d20");
static final Color QUALITY_GATE_ERROR = new Color("#d4333f");
static final Color RATING_A = new Color("#00aa00");
static final Color RATING_B = new Color("#b0d513");
import org.sonar.server.measure.index.ProjectMeasuresIndex;
import org.sonar.server.measure.index.ProjectMeasuresQuery;
import org.sonar.server.project.Visibility;
-import org.sonar.server.qualitygate.ProjectsInWarning;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.Components.Component;
private final DbClient dbClient;
private final ProjectMeasuresIndex index;
private final UserSession userSession;
- private final ProjectsInWarning projectsInWarning;
private final PlatformEditionProvider editionProvider;
private final IssueIndexSyncProgressChecker issueIndexSyncProgressChecker;
- public SearchProjectsAction(DbClient dbClient, ProjectMeasuresIndex index, UserSession userSession, ProjectsInWarning projectsInWarning,
+ public SearchProjectsAction(DbClient dbClient, ProjectMeasuresIndex index, UserSession userSession,
PlatformEditionProvider editionProvider, IssueIndexSyncProgressChecker issueIndexSyncProgressChecker) {
this.dbClient = dbClient;
this.index = index;
this.userSession = userSession;
- this.projectsInWarning = projectsInWarning;
this.editionProvider = editionProvider;
this.issueIndexSyncProgressChecker = issueIndexSyncProgressChecker;
}
Set<String> favoriteProjectUuids = loadFavoriteProjectUuids(dbSession);
List<Criterion> criteria = FilterParser.parse(firstNonNull(request.getFilter(), ""));
ProjectMeasuresQuery query = newProjectMeasuresQuery(criteria, hasFavoriteFilter(criteria) ? favoriteProjectUuids : null)
- .setIgnoreWarning(projectsInWarning.count() == 0L)
.setSort(request.getSort())
.setAsc(request.getAsc());
import java.util.List;
import java.util.Optional;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.issue.notification.MyNewIssuesNotificationHandler;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.notification.email.EmailNotificationChannel;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.KeyExamples;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.property.PropertyQuery;
import org.sonar.db.user.UserDto;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Notifications.ListResponse;
import org.sonarqube.ws.Notifications.Notification;
private UnaryOperator<ListResponse.Builder> addNotifications(DbSession dbSession, UserDto user) {
return response -> {
- List<PropertyDto> properties = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setUserUuid(user.getUuid()).build(), dbSession);
+ List<PropertyDto> properties = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setUserUuid(user.getUuid()).build(),
+ dbSession);
Map<String, EntityDto> entitiesByUuid = searchProjects(dbSession, properties);
Predicate<PropertyDto> isNotification = prop -> prop.getKey().startsWith("notification.");
.map(PropertyDto::getEntityUuid)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
- Set<String> authorizedProjectUuids = dbClient.authorizationDao().keepAuthorizedEntityUuids(dbSession, entityUuids, userSession.getUuid(), UserRole.USER);
+ Set<String> authorizedProjectUuids = dbClient.authorizationDao().keepAuthorizedEntityUuids(dbSession, entityUuids,
+ userSession.getUuid(), UserRole.USER);
return dbClient.entityDao().selectByUuids(dbSession, entityUuids)
.stream()
.filter(c -> authorizedProjectUuids.contains(c.getUuid()))
.collect(Collectors.toMap(EntityDto::getUuid, Function.identity()));
}
- private static Function<PropertyDto, Notification> toWsNotification(Notification.Builder notification, Map<String, EntityDto> projectsByUuid) {
+ private static Function<PropertyDto, Notification> toWsNotification(Notification.Builder notification,
+ Map<String, EntityDto> projectsByUuid) {
return property -> {
notification.clear();
List<String> propertyKey = Splitter.on(".").splitToList(property.getKey());
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
-import org.sonar.api.notifications.NotificationChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.issue.notification.MyNewIssuesNotificationHandler;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.notification.email.EmailNotificationChannel;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.KeyExamples;
return;
}
- if (definition.type() == PropertyType.METRIC) {
- validateMetric(data);
- } else if (definition.type() == PropertyType.USER_LOGIN) {
+ if (definition.type() == PropertyType.USER_LOGIN) {
validateLogin(data);
} else if (definition.type() == PropertyType.JSON) {
validateJson(data, definition);
+++ /dev/null
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 262.5" width="128" height="96">
- <!-- SONARQUBE QUALITY GATE WARN -->
- <path fill="#fff" d="M328.4 259.5H21.3c-10.6 0-19.5-8.7-19.5-19.5V22c0-10.6 8.7-19.5 19.5-19.5h307.1c10.6 0 19.5 8.7 19.5 19.5v218c0 10.8-8.9 19.5-19.5 19.5z"/>
- <path fill="#cfd3d7" d="M328.4 260.4H21.3C10.1 260.4.9 251.2.9 240V22c0-11.2 9.2-20.4 20.4-20.4h307.1c11.2 0 20.4 9.2 20.4 20.4v218c0 11.2-9.3 20.4-20.4 20.4zM21.3 3.4C11 3.4 2.7 11.7 2.7 22v218c0 10.3 8.3 18.6 18.6 18.6h307.1c10.3 0 18.6-8.3 18.6-18.6V22c0-10.3-8.3-18.6-18.6-18.6H21.3z"/>
- <path fill="#434447" d="M94.9 54.3c0 2.7-.4 5-1.3 7-.9 1.9-2.1 3.5-3.6 4.6l5 3.9-2.5 2.2-5.9-4.7c-.9.2-1.9.3-2.9.3-2.2 0-4.1-.5-5.8-1.6-1.7-1.1-3-2.6-3.9-4.6s-1.4-4.3-1.4-6.9v-2c0-2.7.5-5 1.4-7.1s2.2-3.6 3.9-4.7 3.6-1.6 5.8-1.6c2.2 0 4.2.5 5.9 1.6 1.7 1.1 3 2.6 3.9 4.7.9 2 1.4 4.4 1.4 7.1v1.8zm-3.6-1.8c0-3.3-.7-5.8-2-7.6s-3.2-2.7-5.6-2.7c-2.3 0-4.1.9-5.5 2.6-1.3 1.8-2 4.2-2.1 7.4v2c0 3.2.7 5.7 2 7.5s3.2 2.8 5.6 2.8 4.2-.9 5.5-2.6c1.3-1.7 2-4.2 2-7.4l.1-2zm21.5 12.8c-1.4 1.6-3.4 2.4-6.1 2.4-2.2 0-3.9-.6-5-1.9-1.2-1.3-1.7-3.2-1.7-5.7V46.6h3.5V60c0 3.1 1.3 4.7 3.8 4.7 2.7 0 4.5-1 5.4-3v-15h3.5v20.7h-3.4v-2.1zm21.6 2c-.2-.4-.4-1.1-.5-2.2-1.6 1.7-3.6 2.6-5.9 2.6-2 0-3.7-.6-5-1.7-1.3-1.2-2-2.6-2-4.4 0-2.2.8-3.8 2.5-5 1.6-1.2 3.9-1.8 6.9-1.8h3.4v-1.6c0-1.2-.4-2.2-1.1-3-.7-.7-1.8-1.1-3.3-1.1-1.3 0-2.3.3-3.2 1-.9.6-1.3 1.4-1.3 2.3h-3.6c0-1 .4-2 1.1-3s1.7-1.7 3-2.3 2.6-.8 4.1-.8c2.4 0 4.3.6 5.6 1.8 1.4 1.2 2.1 2.8 2.1 4.9v9.5c0 1.9.2 3.4.7 4.5v.3h-3.5zm-5.9-2.7c1.1 0 2.2-.3 3.2-.9s1.7-1.3 2.2-2.2v-4.2h-2.8c-4.3 0-6.5 1.3-6.5 3.8 0 1.1.4 2 1.1 2.6.7.6 1.7.9 2.8.9zm18.3 2.7h-3.5V37.9h3.5v29.4zm5.7-26.2c0-.6.2-1.1.5-1.5s.9-.6 1.6-.6c.7 0 1.2.2 1.6.6s.5.9.5 1.5-.2 1.1-.5 1.4-.9.6-1.6.6c-.7 0-1.2-.2-1.6-.6s-.5-.8-.5-1.4zm3.8 26.2h-3.5V46.6h3.5v20.7zm10.4-25.7v5h3.9v2.7h-3.9v12.8c0 .8.2 1.5.5 1.9s.9.6 1.8.6c.4 0 1-.1 1.7-.2v2.9c-.9.3-1.8.4-2.7.4-1.6 0-2.8-.5-3.6-1.4-.8-1-1.2-2.3-1.2-4.1V49.4h-3.8v-2.7h3.8v-5h3.5v-.1zm14.8 20.5l4.8-15.5h3.8l-8.3 23.9c-1.3 3.4-3.3 5.2-6.1 5.2l-.7-.1-1.3-.2v-2.9l1 .1c1.2 0 2.1-.2 2.8-.7s1.2-1.4 1.7-2.7l.8-2.1-7.4-20.5h3.9l5 15.5zm42.6 1.6c-.9 1.4-2.3 2.4-3.9 3-1.7.7-3.7 1-5.9 1-2.3 0-4.3-.5-6-1.6-1.8-1.1-3.1-2.6-4.1-4.5-1-2-1.5-4.2-1.5-6.8v-2.4c0-4.2 1-7.4 2.9-9.8 2-2.3 4.7-3.5 8.3-3.5 2.9 0 5.2.7 7 2.2s2.9 3.6 3.2 6.3h-3.7c-.7-3.7-2.9-5.5-6.6-5.5-2.5 0-4.3.9-5.6 2.6-1.3 1.7-1.9 4.2-1.9 7.5v2.3c0 3.1.7 5.6 2.1 7.5 1.4 1.8 3.4 2.8 5.8 2.8 1.4 0 2.6-.2 3.6-.5s1.9-.8 2.6-1.5v-6.2H214v-3h10.1v10.1zm18.3 3.6c-.2-.4-.4-1.1-.5-2.2-1.6 1.7-3.6 2.6-5.9 2.6-2 0-3.7-.6-5-1.7-1.3-1.2-2-2.6-2-4.4 0-2.2.8-3.8 2.5-5 1.6-1.2 3.9-1.8 6.9-1.8h3.4v-1.6c0-1.2-.4-2.2-1.1-3-.7-.7-1.8-1.1-3.3-1.1-1.3 0-2.3.3-3.2 1-.9.6-1.3 1.4-1.3 2.3h-3.6c0-1 .4-2 1.1-3 .7-1 1.7-1.7 3-2.3s2.6-.8 4.1-.8c2.4 0 4.3.6 5.6 1.8 1.4 1.2 2.1 2.8 2.1 4.9v9.5c0 1.9.2 3.4.7 4.5v.3h-3.5zm-5.9-2.7c1.1 0 2.2-.3 3.2-.9s1.7-1.3 2.2-2.2v-4.2h-2.8c-4.3 0-6.5 1.3-6.5 3.8 0 1.1.4 2 1.1 2.6.7.6 1.7.9 2.8.9zm19.2-23v5h3.9v2.7h-3.9v12.8c0 .8.2 1.5.5 1.9.3.4.9.6 1.8.6.4 0 1-.1 1.7-.2v2.9c-.9.3-1.8.4-2.7.4-1.6 0-2.8-.5-3.6-1.4-.8-1-1.2-2.3-1.2-4.1V49.4h-3.8v-2.7h3.8v-5h3.5v-.1zm16.6 26.1c-2.8 0-5.1-.9-6.8-2.8-1.8-1.8-2.6-4.3-2.6-7.4v-.6c0-2.1.4-3.9 1.2-5.5.8-1.6 1.9-2.9 3.3-3.8 1.4-.9 2.9-1.4 4.6-1.4 2.7 0 4.8.9 6.3 2.7s2.2 4.3 2.2 7.6V58h-14c.1 2 .6 3.7 1.8 4.9 1.1 1.3 2.6 1.9 4.3 1.9 1.2 0 2.3-.3 3.2-.8.9-.5 1.6-1.2 2.3-2l2.2 1.7c-1.9 2.7-4.5 4-8 4zm-.4-18.6c-1.4 0-2.6.5-3.6 1.6-1 1-1.6 2.5-1.8 4.4h10.4v-.3c-.1-1.8-.6-3.2-1.5-4.2s-2.1-1.5-3.5-1.5z"/>
- <path fill="#ed7d20" d="M227.6 162.9H120.4c-17.6 0-31.9-14.4-31.9-31.9 0-17.6 14.4-31.9 31.9-31.9h107.2c17.6 0 31.9 14.4 31.9 31.9 0 17.6-14.3 31.9-31.9 31.9z"/>
- <path fill="#fff" d="M139.1 136.9l4.1-21.6h6.2l-6.7 30.3h-6.3l-4.9-20.3-4.9 20.3h-6.3l-6.7-30.3h6.2l4.1 21.5 5-21.5h5.3l4.9 21.6zm29.9 2.5h-11l-2.1 6.2h-6.6l11.3-30.3h5.8l11.4 30.3h-6.6l-2.2-6.2zm-9.3-5h7.6l-3.8-11.4-3.8 11.4zm32.1.2h-5v11.1h-6.2v-30.3h11.3c3.6 0 6.3.8 8.3 2.4 1.9 1.6 2.9 3.9 2.9 6.8 0 2.1-.4 3.8-1.3 5.2-.9 1.4-2.3 2.5-4.1 3.3l6.6 12.4v.3h-6.7l-5.8-11.2zm-5-5.1h5c1.6 0 2.8-.4 3.6-1.2.9-.8 1.3-1.9 1.3-3.3s-.4-2.6-1.2-3.4c-.8-.8-2.1-1.2-3.7-1.2h-5v9.1zm45.7 16.2h-6.2l-12.2-20v20h-6.2v-30.3h6.2l12.2 20v-20h6.2v30.3z"/>
- <path fill="#1b171b" d="M55.35 215.864a13.464 13.464 0 0 0 5.954 1.683c2.092 0 2.956-.729 2.956-1.863s-.679-1.683-3.271-2.547c-4.595-1.548-6.368-4.05-6.3-6.683 0-4.14 3.55-7.276 9.05-7.276a14.882 14.882 0 0 1 6.277 1.274l-1.251 4.77a10.908 10.908 0 0 0-4.815-1.274c-1.683 0-2.642.68-2.642 1.8 0 1.049.869 1.593 3.6 2.547 4.23 1.454 6.003 3.6 6.048 6.867 0 4.135-3.271 7.2-9.639 7.2-2.911 0-5.499-.639-7.2-1.548zM95.284 210.54c0 8.141-5.774 11.872-11.737 11.872-6.497.004-11.497-4.262-11.497-11.462s4.725-11.776 11.867-11.776c6.821 0 11.366 4.684 11.366 11.367zm-16.102.23c0 3.82 1.594 6.683 4.55 6.683 2.7 0 4.41-2.7 4.41-6.683 0-3.321-1.274-6.691-4.41-6.691-3.316.004-4.55 3.415-4.55 6.691zM97.75 206.77c0-2.773-.09-5.14-.185-7.093h5.985l.315 3.042h.14a8.136 8.136 0 0 1 6.862-3.546c4.55 0 7.96 2.997 7.96 9.55v13.189h-6.889V209.6c0-2.867-.999-4.82-3.501-4.82a3.681 3.681 0 0 0-3.501 2.57 4.684 4.684 0 0 0-.275 1.728v12.83H97.75zM135.226 221.912l-.41-2.25h-.135c-1.454 1.778-3.735 2.732-6.368 2.732-4.5 0-7.2-3.281-7.2-6.822 0-5.774 5.185-8.55 13.05-8.51v-.315c0-1.183-.639-2.867-4.05-2.867a12.51 12.51 0 0 0-6.138 1.679l-1.278-4.455c1.548-.868 4.595-1.957 8.64-1.957 7.416 0 9.779 4.365 9.779 9.594v7.73a34.164 34.164 0 0 0 .32 5.4zm-.815-10.512c-3.636-.045-6.457.824-6.457 3.501 0 1.778 1.183 2.642 2.731 2.642a3.776 3.776 0 0 0 3.6-2.547 4.891 4.891 0 0 0 .14-1.184zM144.784 206.994c0-3.271-.09-5.4-.185-7.317h5.958l.243 4.073h.18c1.138-3.227 3.865-4.59 6.003-4.59a7.452 7.452 0 0 1 1.467.09v6.516a9.819 9.819 0 0 0-1.863-.184c-2.547 0-4.275 1.35-4.734 3.5a8.523 8.523 0 0 0-.135 1.548v11.282h-6.934zM204.058 215.9c0 2.25.045 4.275.184 6.003h-3.55l-.23-3.6h-.085a8.293 8.293 0 0 1-7.277 4.095c-3.456 0-7.6-1.908-7.6-9.639v-12.861h4v12.19c0 4.181 1.273 7.007 4.914 7.007a5.796 5.796 0 0 0 5.274-3.645 5.918 5.918 0 0 0 .364-2.047v-13.5h4.005zM208.702 221.912c.09-1.503.18-3.735.18-5.688V189.62h3.955v13.828h.09c1.409-2.457 3.956-4.05 7.506-4.05 5.454 0 9.32 4.55 9.275 11.25 0 7.871-4.95 11.781-9.864 11.781-3.186 0-5.729-1.228-7.367-4.14h-.14l-.18 3.641zm4.135-8.825a7.416 7.416 0 0 0 .185 1.454 6.17 6.17 0 0 0 5.998 4.684c4.19 0 6.683-3.41 6.683-8.455 0-4.41-2.25-8.186-6.548-8.186a6.377 6.377 0 0 0-6.093 4.91 7.861 7.861 0 0 0-.23 1.638zM235.175 211.634c.086 5.4 3.546 7.65 7.546 7.65a14.508 14.508 0 0 0 6.094-1.134l.684 2.867c-1.409.634-3.821 1.35-7.322 1.35-6.777 0-10.827-4.455-10.827-11.093s3.91-11.871 10.323-11.871c7.2 0 9.095 6.3 9.095 10.35a15.152 15.152 0 0 1-.135 1.863zm11.732-2.866c.045-2.547-1.04-6.507-5.544-6.507-4.05 0-5.823 3.735-6.143 6.507zM180.748 203.863a11.885 11.885 0 1 0-5.09 17.581l4.599 7.47 3.65-2.48-4.6-7.47a11.889 11.889 0 0 0 1.44-15.101m-5.152 13.567a8.325 8.325 0 1 1 2.205-11.565 8.334 8.334 0 0 1-2.205 11.565"/>
- <g fill="#4e9bcd">
- <path d="M278.123 222.006h-2.821c0-22.698-18.73-41.166-41.752-41.166v-2.817c24.58 0 44.573 19.728 44.573 43.983z"/>
- <path d="M280.072 206.869c-3.384-14.243-14.922-26.127-29.372-30.281l.648-2.25c15.268 4.383 27.45 16.943 31.028 31.995zM282.24 193.504a43.2 43.2 0 0 0-16.726-18.671l.977-1.607a45.108 45.108 0 0 1 17.46 19.49z"/>
- </g>
-</svg>
\ No newline at end of file
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.sonar.api.measures.Metric.Level.ERROR;
-import static org.sonar.api.measures.Metric.Level.WARN;
import static org.sonar.server.badge.ws.SvgGenerator.Color.DEFAULT;
public class SvgGeneratorTest {
checkQualityGate(result, ERROR);
}
- @Test
- public void generate_deprecated_warning_quality_gate() {
- initSvgGenerator();
-
- String result = underTest.generateQualityGate(WARN);
-
- assertThat(result).isEqualTo(readTemplate("quality_gate_warn.svg"));
- }
-
@Test
public void generate_error() {
initSvgGenerator();
package org.sonar.server.notification.ws;
import org.junit.Test;
-import org.sonar.api.notifications.NotificationChannel;
import org.sonar.server.issue.notification.FPOrWontFixNotificationHandler;
import org.sonar.server.issue.notification.MyNewIssuesNotificationHandler;
import org.sonar.server.issue.notification.NewIssuesNotificationHandler;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.qualitygate.notification.QGChangeNotificationHandler;
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.server.notification.NotificationChannel;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import static org.assertj.core.api.Assertions.assertThat;
NotificationDispatcherMetadata metadata3 = NotificationDispatcherMetadata.create("Dispatcher3").setProperty("global", "FOO").setProperty("on-project", "BAR");
underTest = new NotificationCenter(
- new NotificationDispatcherMetadata[] {metadata1, metadata2, metadata3},
- new NotificationChannel[] {emailChannel, gtalkChannel}
- );
+ new NotificationDispatcherMetadata[] {metadata1, metadata2, metadata3},
+ new NotificationChannel[] {emailChannel, gtalkChannel}
+ );
}
@Test
public String getPublicRootUrl() {
throw new UnsupportedOperationException();
}
-
- @Override
- public boolean isSecured() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getPermanentServerId() {
- throw new UnsupportedOperationException();
- }
}
}
return new TypeValidations(Arrays.asList(
new BooleanTypeValidation(),
new IntegerTypeValidation(),
- new LongTypeValidation(),
new FloatTypeValidation(),
new StringTypeValidation(),
- new StringListTypeValidation(),
- new MetricLevelTypeValidation()
+ new StringListTypeValidation()
));
}
}
import org.sonar.alm.client.github.security.GithubAppSecurityImpl;
import org.sonar.alm.client.gitlab.GitlabGlobalSettingsValidator;
import org.sonar.alm.client.gitlab.GitlabHttpClient;
-import org.sonar.api.profiles.XMLProfileParser;
-import org.sonar.api.profiles.XMLProfileSerializer;
import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.rules.AnnotationRuleParser;
import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
import org.sonar.auth.bitbucket.BitbucketModule;
import org.sonar.auth.github.GitHubModule;
import org.sonar.server.measure.index.ProjectsEsModule;
import org.sonar.server.measure.live.LiveMeasureModule;
import org.sonar.server.measure.ws.MeasuresWsModule;
-import org.sonar.server.metric.MetricFinder;
import org.sonar.server.metric.UnanalyzedLanguageMetrics;
import org.sonar.server.metric.ws.MetricsWsModule;
import org.sonar.server.monitoring.ComputeEngineMetricStatusTask;
import org.sonar.server.pushapi.hotspots.HotspotChangeEventServiceImpl;
import org.sonar.server.pushapi.issues.IssueChangeEventServiceImpl;
import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventServiceImpl;
-import org.sonar.server.qualitygate.ProjectsInWarningModule;
import org.sonar.server.qualitygate.QualityGateModule;
import org.sonar.server.qualitygate.notification.QGChangeNotificationHandler;
import org.sonar.server.qualitygate.ws.QualityGateWsModule;
// quality profile
BuiltInQProfileRepositoryImpl.class,
ActiveRuleIndexer.class,
- XMLProfileParser.class,
- XMLProfileSerializer.class,
QProfileComparison.class,
QProfileTreeImpl.class,
QProfileRulesImpl.class,
// rule
RuleIndexDefinition.class,
RuleIndexer.class,
- AnnotationRuleParser.class,
WebServerRuleFinderImpl.class,
RuleDefinitionsLoader.class,
RulesDefinitionXmlLoader.class,
// measure
new MetricsWsModule(),
new MeasuresWsModule(),
- MetricFinder.class,
UnanalyzedLanguageMetrics.class,
new QualityGateModule(),
- new ProjectsInWarningModule(),
new QualityGateWsModule(),
// web services
import org.sonar.server.platform.web.RegisterServletFilters;
import org.sonar.server.plugins.DetectPluginChange;
import org.sonar.server.plugins.PluginConsentVerifier;
-import org.sonar.server.qualitygate.ProjectsInWarningDaemon;
import org.sonar.server.qualitygate.RegisterQualityGates;
+import org.sonar.server.qualityprofile.RegisterQualityProfiles;
import org.sonar.server.qualityprofile.builtin.BuiltInQProfileInsertImpl;
import org.sonar.server.qualityprofile.builtin.BuiltInQProfileLoader;
import org.sonar.server.qualityprofile.builtin.BuiltInQProfileUpdateImpl;
import org.sonar.server.qualityprofile.builtin.BuiltInQualityProfilesUpdateListener;
-import org.sonar.server.qualityprofile.RegisterQualityProfiles;
import org.sonar.server.rule.AdvancedRuleDescriptionSectionsGenerator;
import org.sonar.server.rule.LegacyHotspotRuleDescriptionSectionsGenerator;
import org.sonar.server.rule.LegacyIssueRuleDescriptionSectionsGenerator;
// RegisterServletFilters makes the WebService engine of Level4 served by the MasterServletFilter, therefore it
// must be started after all the other startup tasks
RegisterServletFilters.class
- );
+ );
}
/**
protected void doPrivileged() {
PlatformLevelStartup.super.start();
getOptional(IndexerStartupTask.class).ifPresent(IndexerStartupTask::execute);
- // Need to be executed after indexing as it executes an ES query
- get(ProjectsInWarningDaemon.class).notifyStart();
get(ServerLifecycleNotifier.class).notifyStart();
get(ProcessCommandWrapper.class).notifyOperational();
get(WebServerRuleFinder.class).stopCaching();
import org.apache.commons.lang.builder.ToStringStyle;
import org.sonar.api.code.CodeCharacteristic;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueComment;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
return this;
}
- /**
- * @deprecated since 7.2, comments are not more available
- */
- @Override
- @Deprecated
- public List<IssueComment> comments() {
- return Collections.emptyList();
- }
-
public List<DefaultIssueComment> defaultIssueComments() {
if (comments == null) {
return Collections.emptyList();
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.api.batch.rule.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import javax.annotation.concurrent.Immutable;
-import org.sonar.api.batch.rule.Rule;
-import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.rule.RuleKey;
-
-@Immutable
-class DefaultRules implements Rules {
- private final Map<String, List<Rule>> rulesByRepository;
- private final Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKey;
- private final Map<RuleKey, Rule> rulesByRuleKey;
-
- DefaultRules(Collection<NewRule> newRules) {
- Map<String, List<Rule>> rulesByRepositoryBuilder = new HashMap<>();
- Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKeyBuilder = new HashMap<>();
- Map<RuleKey, Rule> rulesByRuleKeyBuilder = new HashMap<>();
-
- for (NewRule newRule : newRules) {
- DefaultRule r = new DefaultRule(newRule);
- rulesByRuleKeyBuilder.put(r.key(), r);
- rulesByRepositoryBuilder.computeIfAbsent(r.key().repository(), x -> new ArrayList<>()).add(r);
- addToTable(rulesByRepositoryAndInternalKeyBuilder, r);
- }
-
- rulesByRuleKey = Collections.unmodifiableMap(rulesByRuleKeyBuilder);
- rulesByRepository = Collections.unmodifiableMap(rulesByRepositoryBuilder);
- rulesByRepositoryAndInternalKey = Collections.unmodifiableMap(rulesByRepositoryAndInternalKeyBuilder);
- }
-
- private static void addToTable(Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKeyBuilder, DefaultRule r) {
- if (r.internalKey() == null) {
- return;
- }
-
- rulesByRepositoryAndInternalKeyBuilder
- .computeIfAbsent(r.key().repository(), x -> new HashMap<>())
- .computeIfAbsent(r.internalKey(), x -> new ArrayList<>())
- .add(r);
- }
-
- @Override
- public Rule find(RuleKey ruleKey) {
- return rulesByRuleKey.get(ruleKey);
- }
-
- @Override
- public Collection<Rule> findAll() {
- return rulesByRepository.values().stream().flatMap(List::stream).collect(Collectors.toList());
- }
-
- @Override
- public Collection<Rule> findByRepository(String repository) {
- return rulesByRepository.getOrDefault(repository, Collections.emptyList());
- }
-
- @Override
- public Collection<Rule> findByInternalKey(String repository, String internalKey) {
- return rulesByRepositoryAndInternalKey
- .getOrDefault(repository, Collections.emptyMap())
- .getOrDefault(internalKey, Collections.emptyList());
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.api.batch.rule.internal;
-
-import java.util.HashMap;
-import java.util.Map;
-import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.rule.RuleKey;
-
-/**
- * For unit testing and internal use only.
- *
- * @since 4.2
- */
-
-public class RulesBuilder {
-
- private final Map<RuleKey, NewRule> map = new HashMap<>();
-
- public NewRule add(RuleKey key) {
- if (map.containsKey(key)) {
- throw new IllegalStateException(String.format("Rule '%s' already exists", key));
- }
- NewRule newRule = new NewRule(key);
- map.put(key, newRule);
- return newRule;
- }
-
- public Rules build() {
- return new DefaultRules(map.values());
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.api.batch.rule.internal;
-
-import java.util.LinkedList;
-import java.util.List;
-import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class DefaultRulesTest {
- @Test
- public void testRepeatedInternalKey() {
- List<NewRule> newRules = new LinkedList<>();
- newRules.add(createRule("key1", "repo", "internal"));
- newRules.add(createRule("key2", "repo", "internal"));
-
- DefaultRules rules = new DefaultRules(newRules);
- assertThat(rules.findByInternalKey("repo", "internal")).hasSize(2);
- assertThat(rules.find(RuleKey.of("repo", "key1"))).isNotNull();
- assertThat(rules.find(RuleKey.of("repo", "key2"))).isNotNull();
- assertThat(rules.findByRepository("repo")).hasSize(2);
- }
-
- @Test
- public void testNonExistingKey() {
- List<NewRule> newRules = new LinkedList<>();
- newRules.add(createRule("key1", "repo", "internal"));
- newRules.add(createRule("key2", "repo", "internal"));
-
- DefaultRules rules = new DefaultRules(newRules);
- assertThat(rules.findByInternalKey("xx", "xx")).isEmpty();
- assertThat(rules.find(RuleKey.of("xxx", "xx"))).isNull();
- assertThat(rules.findByRepository("xxxx")).isEmpty();
- }
-
- @Test
- public void testRepeatedRule() {
- List<NewRule> newRules = new LinkedList<>();
- newRules.add(createRule("key", "repo", "internal"));
- newRules.add(createRule("key", "repo", "internal"));
-
- DefaultRules rules = new DefaultRules(newRules);
- assertThat(rules.find(RuleKey.of("repo", "key"))).isNotNull();
- }
-
- private NewRule createRule(String key, String repo, String internalKey) {
- RuleKey ruleKey = RuleKey.of(repo, key);
- NewRule newRule = new NewRule(ruleKey);
- newRule.setInternalKey(internalKey);
-
- return newRule;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.api.batch.rule.internal;
-
-import org.junit.Test;
-import org.sonar.api.batch.rule.Rule;
-import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.rule.Severity;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-public class RulesBuilderTest {
-
- @Test
- public void no_rules() {
- RulesBuilder builder = new RulesBuilder();
- Rules rules = builder.build();
- assertThat(rules.findAll()).isEmpty();
- }
-
- @Test
- public void build_rules() {
- RulesBuilder builder = new RulesBuilder();
- NewRule newJava1 = builder.add(RuleKey.of("java", "S0001"));
- newJava1.setName("Detect bug");
- newJava1.setDescription("Detect potential bug");
- newJava1.setInternalKey("foo=bar");
- newJava1.setSeverity(org.sonar.api.rule.Severity.CRITICAL);
- newJava1.setStatus(RuleStatus.BETA);
- newJava1.addParam("min");
- newJava1.addParam("max").setDescription("Maximum");
- // most simple rule
- builder.add(RuleKey.of("java", "S0002"));
- builder.add(RuleKey.of("findbugs", "NPE"));
-
- Rules rules = builder.build();
-
- assertThat(rules.findAll()).hasSize(3);
- assertThat(rules.findByRepository("java")).hasSize(2);
- assertThat(rules.findByRepository("findbugs")).hasSize(1);
- assertThat(rules.findByRepository("unknown")).isEmpty();
-
- Rule java1 = rules.find(RuleKey.of("java", "S0001"));
- assertThat(java1.key().repository()).isEqualTo("java");
- assertThat(java1.key().rule()).isEqualTo("S0001");
- assertThat(java1.name()).isEqualTo("Detect bug");
- assertThat(java1.description()).isEqualTo("Detect potential bug");
- assertThat(java1.internalKey()).isEqualTo("foo=bar");
- assertThat(java1.status()).isEqualTo(RuleStatus.BETA);
- assertThat(java1.severity()).isEqualTo(org.sonar.api.rule.Severity.CRITICAL);
- assertThat(java1.params()).hasSize(2);
- assertThat(java1.param("min").key()).isEqualTo("min");
- assertThat(java1.param("min").description()).isNull();
- assertThat(java1.param("max").key()).isEqualTo("max");
- assertThat(java1.param("max").description()).isEqualTo("Maximum");
-
- Rule java2 = rules.find(RuleKey.of("java", "S0002"));
- assertThat(java2.key().repository()).isEqualTo("java");
- assertThat(java2.key().rule()).isEqualTo("S0002");
- assertThat(java2.description()).isNull();
- assertThat(java2.internalKey()).isNull();
- assertThat(java2.status()).isEqualTo(RuleStatus.defaultStatus());
- assertThat(java2.severity()).isEqualTo(Severity.defaultSeverity());
- assertThat(java2.params()).isEmpty();
- }
-
- @Test
- public void fail_to_add_twice_the_same_rule() {
- RulesBuilder builder = new RulesBuilder();
- builder.add(RuleKey.of("java", "S0001"));
-
- assertThatThrownBy(() -> builder.add(RuleKey.of("java", "S0001")))
- .isInstanceOf(IllegalStateException.class)
- .hasMessage("Rule 'java:S0001' already exists");
- }
-
- @Test
- public void fail_to_add_twice_the_same_param() {
- RulesBuilder builder = new RulesBuilder();
- NewRule newRule = builder.add(RuleKey.of("java", "S0001"));
- newRule.addParam("min");
- newRule.addParam("max");
-
- assertThatThrownBy(() -> newRule.addParam("min"))
- .isInstanceOf(IllegalStateException.class)
- .hasMessage("Parameter 'min' already exists on rule 'java:S0001'");
- }
-}
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.DefaultTextPointer;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.rule.ActiveRules;
assertThat(tester.measures("foo:src/Foo.java")).hasSize(2);
assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull();
assertThat(tester.measure("foo:src/Foo.java", "lines")).isNotNull();
- tester.<Integer>newMeasure()
- .on(new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder())))
- .forMetric(CoreMetrics.DIRECTORIES)
- .withValue(4)
- .save();
- assertThat(tester.measures("foo")).hasSize(1);
- assertThat(tester.measure("foo", "directories")).isNotNull();
}
@Test(expected = IllegalStateException.class)
@Property(key = "integer", name = "Integer", defaultValue = "12345"),
@Property(key = "array", name = "Array", defaultValue = "one,two,three"),
@Property(key = "multi_values", name = "Array", defaultValue = "1,2,3", multiValues = true),
- @Property(key = "sonar.jira", name = "Jira Server", type = PropertyType.PROPERTY_SET, propertySetKey = "jira"),
+ @Property(key = "sonar.jira", name = "Jira Server", type = PropertyType.PROPERTY_SET),
@Property(key = "newKey", name = "New key", deprecatedKey = "oldKey"),
@Property(key = "newKeyWithDefaultValue", name = "New key with default value", deprecatedKey = "oldKeyWithDefaultValue", defaultValue = "default_value"),
@Property(key = "new_multi_values", name = "New multi values", defaultValue = "1,2,3", multiValues = true, deprecatedKey = "old_multi_values")
}
return StringUtils.removeEnd(baseUrl, "/");
}
-
- @Override
- public boolean isSecured() {
- return false;
- }
-
- @Override
- public String getPermanentServerId() {
- return getId();
- }
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.scanner.rule;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import org.apache.commons.io.IOUtils;
-import org.sonar.scanner.bootstrap.DefaultScannerWsClient;
-import org.sonarqube.ws.Rules.ListResponse;
-import org.sonarqube.ws.Rules.ListResponse.Rule;
-import org.sonarqube.ws.client.GetRequest;
-
-public class DefaultRulesLoader implements RulesLoader {
- private static final String RULES_SEARCH_URL = "/api/rules/list.protobuf";
-
- private final DefaultScannerWsClient wsClient;
-
- public DefaultRulesLoader(DefaultScannerWsClient wsClient) {
- this.wsClient = wsClient;
- }
-
- @Override
- public List<Rule> load() {
- GetRequest getRequest = new GetRequest(RULES_SEARCH_URL);
- ListResponse list = loadFromStream(wsClient.call(getRequest).contentStream());
- return list.getRulesList();
- }
-
- private static ListResponse loadFromStream(InputStream is) {
- try {
- return ListResponse.parseFrom(is);
- } catch (IOException e) {
- throw new IllegalStateException("Unable to get rules", e);
- } finally {
- IOUtils.closeQuietly(is);
- }
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.scanner.rule;
-
-import java.util.List;
-import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.batch.rule.internal.NewRule;
-import org.sonar.api.batch.rule.internal.RulesBuilder;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.utils.log.Profiler;
-import org.sonarqube.ws.Rules.ListResponse.Rule;
-import org.springframework.context.annotation.Bean;
-
-public class RulesProvider {
- private static final Logger LOG = Loggers.get(RulesProvider.class);
- private static final String LOG_MSG = "Load server rules";
-
- @Bean("Rules")
- public Rules provide(RulesLoader ref) {
- Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
- List<Rule> loadedRules = ref.load();
- RulesBuilder builder = new RulesBuilder();
-
- for (Rule r : loadedRules) {
- NewRule newRule = builder.add(RuleKey.of(r.getRepository(), r.getKey()));
- newRule.setName(r.getName());
- newRule.setInternalKey(r.getInternalKey());
- }
-
- profiler.stopInfo();
- return builder.build();
- }
-}
import javax.annotation.Nullable;
import javax.annotation.Priority;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.batch.fs.internal.SensorStrategy;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.api.utils.MessageException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.core.config.ScannerProperties;
import org.sonar.core.extension.CoreExtensionsInstaller;
import org.sonar.core.language.LanguagesProvider;
import org.sonar.scanner.repository.settings.DefaultProjectSettingsLoader;
import org.sonar.scanner.rule.ActiveRulesProvider;
import org.sonar.scanner.rule.DefaultActiveRulesLoader;
-import org.sonar.scanner.rule.DefaultRulesLoader;
import org.sonar.scanner.rule.QProfileVerifier;
-import org.sonar.scanner.rule.RulesProvider;
import org.sonar.scanner.scan.branch.BranchConfiguration;
import org.sonar.scanner.scan.branch.BranchConfigurationProvider;
import org.sonar.scanner.scan.branch.BranchType;
ResourceTypes.class,
ProjectReactorValidator.class,
ProjectInfo.class,
- new RulesProvider(),
new BranchConfigurationProvider(),
new ProjectBranchesProvider(),
ProjectRepositoriesProvider.class,
add(SvnScmSupport.getObjects());
add(DefaultProjectSettingsLoader.class,
- DefaultRulesLoader.class,
DefaultActiveRulesLoader.class,
DefaultQualityProfileLoader.class,
DefaultProjectRepositoriesLoader.class);
getComponentByType(DeprecatedPropertiesWarningGenerator.class).execute();
-
getComponentByType(ProjectFileIndexer.class).index();
// Log detected languages and their profiles after FS is indexed and languages detected
assertThat(metadata.getVersion()).isEqualTo("2.2");
assertThat(metadata.getStartedAt()).isNotNull();
assertThat(metadata.getPublicRootUrl()).isEqualTo("http://foo.com");
- assertThat(metadata.getPermanentServerId()).isEqualTo("123");
assertThat(metadata.getContextPath()).isNull();
- assertThat(metadata.isSecured()).isFalse();
}
@Test
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.scanner.rule;
-
-import com.google.common.io.ByteSource;
-import com.google.common.io.Resources;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import org.junit.Test;
-import org.sonar.scanner.WsTestUtil;
-import org.sonar.scanner.bootstrap.DefaultScannerWsClient;
-import org.sonarqube.ws.Rules.ListResponse.Rule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
-
-public class DefaultRulesLoaderTest {
-
- @Test
- public void testParseServerResponse() throws IOException {
- DefaultScannerWsClient wsClient = mock(DefaultScannerWsClient.class);
- InputStream is = Resources.asByteSource(this.getClass().getResource("DefaultRulesLoaderTest/response.protobuf")).openBufferedStream();
- WsTestUtil.mockStream(wsClient, is);
- DefaultRulesLoader loader = new DefaultRulesLoader(wsClient);
- List<Rule> ruleList = loader.load();
- assertThat(ruleList).hasSize(318);
- }
-
- @Test
- public void testError() throws IOException {
- DefaultScannerWsClient wsClient = mock(DefaultScannerWsClient.class);
- InputStream is = ByteSource.wrap("trash".getBytes()).openBufferedStream();
- WsTestUtil.mockStream(wsClient, is);
- DefaultRulesLoader loader = new DefaultRulesLoader(wsClient);
-
- assertThatThrownBy(() -> loader.load())
- .isInstanceOf(IllegalStateException.class)
- .hasMessage("Unable to get rules");
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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.scanner.rule;
-
-import com.google.common.collect.Lists;
-import org.junit.Test;
-import org.sonar.api.batch.rule.Rules;
-import org.sonarqube.ws.Rules.ListResponse.Rule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class RulesProviderTest {
- @Test
- public void testRuleTranslation() {
- RulesLoader loader = mock(RulesLoader.class);
- when(loader.load()).thenReturn(Lists.newArrayList(getTestRule()));
-
- RulesProvider provider = new RulesProvider();
-
- Rules rules = provider.provide(loader);
-
- assertThat(rules.findAll()).hasSize(1);
- assertRule(rules.findAll().iterator().next());
- }
-
- private static void assertRule(org.sonar.api.batch.rule.Rule r) {
- Rule testRule = getTestRule();
-
- assertThat(r.name()).isEqualTo(testRule.getName());
- assertThat(r.internalKey()).isEqualTo(testRule.getInternalKey());
- assertThat(r.key().rule()).isEqualTo(testRule.getKey());
- assertThat(r.key().repository()).isEqualTo(testRule.getRepository());
- }
-
- private static Rule getTestRule() {
- Rule.Builder ruleBuilder = Rule.newBuilder();
- ruleBuilder.setKey("key1");
- ruleBuilder.setRepository("repo1");
- ruleBuilder.setName("name");
- ruleBuilder.setInternalKey("key1");
- return ruleBuilder.build();
-
- }
-}