diff options
Diffstat (limited to 'server/sonar-webserver-core')
7 files changed, 117 insertions, 50 deletions
diff --git a/server/sonar-webserver-core/build.gradle b/server/sonar-webserver-core/build.gradle index 63f2814ea6a..99ab89c9f2d 100644 --- a/server/sonar-webserver-core/build.gradle +++ b/server/sonar-webserver-core/build.gradle @@ -63,8 +63,6 @@ dependencies { testImplementation 'org.apache.logging.log4j:log4j-core' testImplementation 'org.assertj:assertj-core' testImplementation 'org.assertj:assertj-guava' - testImplementation 'org.eclipse.jetty:jetty-server' - testImplementation 'org.eclipse.jetty:jetty-servlet' testImplementation 'org.hamcrest:hamcrest' testImplementation 'org.junit.jupiter:junit-jupiter-api' testImplementation 'org.junit.jupiter:junit-jupiter-params' diff --git a/server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java b/server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java index 1278205a383..814f5b2b20d 100644 --- a/server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java +++ b/server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java @@ -44,7 +44,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; public class RegisterMetricsIT { - public static final int SOON_TO_BE_REMOVED_COMPLEXITY_METRICS_COUNT = 7; @Rule public DbTester dbTester = DbTester.create(System2.INSTANCE); @@ -144,9 +143,7 @@ public class RegisterMetricsIT { .isEqualTo(CoreMetrics.getMetrics().size() // Metric CoreMetrics.WONT_FIX_ISSUES was renamed to CoreMetrics.ACCEPTED_ISSUES in 10.3. // We don't want to insert it anymore - - 1 - // SONAR-12647 We are exclusing complexity metrics, they will be removed from the plugin API soon - - SOON_TO_BE_REMOVED_COMPLEXITY_METRICS_COUNT); + - 1); } @Test diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexCreationTelemetry.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexCreationTelemetry.java index 213c4e153fc..a1fffb536c7 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexCreationTelemetry.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexCreationTelemetry.java @@ -19,6 +19,7 @@ */ package org.sonar.server.issue.index; +import com.google.common.annotations.VisibleForTesting; import java.io.IOException; import java.time.Clock; import java.util.Set; @@ -50,7 +51,6 @@ public class AsyncIssueIndexCreationTelemetry { private static final Logger LOGGER = LoggerFactory.getLogger(AsyncIssueIndexCreationTelemetry.class); - private final IssueIndexSyncProgressChecker issueIndexSyncProgressChecker; private final DbClient dbClient; private final TelemetryClient telemetryClient; private final Server server; @@ -63,9 +63,8 @@ public class AsyncIssueIndexCreationTelemetry { private long startTime; private int nbIndexingTasks; - public AsyncIssueIndexCreationTelemetry(IssueIndexSyncProgressChecker issueIndexSyncProgressChecker, DbClient dbClient, - TelemetryClient telemetryClient, Server server, UuidFactory uuidFactory, Clock clock, IssueIndexMonitoringScheduler scheduler, Configuration config) { - this.issueIndexSyncProgressChecker = issueIndexSyncProgressChecker; + public AsyncIssueIndexCreationTelemetry(DbClient dbClient, TelemetryClient telemetryClient, Server server, UuidFactory uuidFactory, Clock clock, + IssueIndexMonitoringScheduler scheduler, Configuration config) { this.dbClient = dbClient; this.telemetryClient = telemetryClient; this.server = server; @@ -86,18 +85,21 @@ public class AsyncIssueIndexCreationTelemetry { } startTime = clock.millis(); this.nbIndexingTasks = nbIndexingTasks; - if(currentMonitoring != null) { + if (currentMonitoring != null) { currentMonitoring.cancel(false); } - currentMonitoring = scheduler.scheduleAtFixedRate(() -> { - try (DbSession dbSession = dbClient.openSession(false)) { - if (!issueIndexSyncProgressChecker.isIssueSyncInProgress(dbSession)) { - sendIssueIndexationTelemetry(dbSession); - currentMonitoring.cancel(false); - } - } - }, 0, 5, TimeUnit.SECONDS); + currentMonitoring = scheduler.scheduleAtFixedRate(this::tryToSendTelemetry, 0, 5, TimeUnit.SECONDS); + + } + @VisibleForTesting + void tryToSendTelemetry() { + try (DbSession dbSession = dbClient.openSession(false)) { + if (!dbClient.ceQueueDao().hasAnyIssueSyncTaskPendingOrInProgress(dbSession)) { + sendIssueIndexationTelemetry(dbSession); + currentMonitoring.cancel(false); + } + } } private void sendIssueIndexationTelemetry(DbSession dbSession) { diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/RulesRegistrationContext.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/RulesRegistrationContext.java index a3533a80743..e124a467ae8 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/RulesRegistrationContext.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/RulesRegistrationContext.java @@ -83,9 +83,11 @@ class RulesRegistrationContext { String ruleUuid = entry.getKey(); RuleDto rule = dbRulesByRuleUuid.get(ruleUuid); if (rule == null) { - LOG.warn("Could not retrieve rule with uuid %s referenced by a deprecated rule key. " + - "The following deprecated rule keys seem to be referencing a non-existing rule", - ruleUuid, entry.getValue()); + LOG.warn("Could not retrieve rule with uuid {} referenced by a deprecated rule key. " + + "The following deprecated rule keys seem to be referencing a non-existing rule: {}", + ruleUuid, entry.getValue().stream() + .map(SingleDeprecatedRuleKey::getOldRuleKeyAsRuleKey) + .collect(Collectors.toSet())); } else { entry.getValue().forEach(d -> rulesByKey.put(d.getOldRuleKeyAsRuleKey(), rule)); } diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java index 05fcb23d55c..08965b0c895 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java @@ -20,11 +20,10 @@ package org.sonar.server.startup; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.FluentIterable; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.sonar.api.Startable; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; @@ -39,24 +38,12 @@ import org.sonar.db.metric.MetricDto; import org.sonar.server.metric.MetricToDto; import org.springframework.beans.factory.annotation.Autowired; -import static com.google.common.collect.FluentIterable.concat; import static com.google.common.collect.Lists.newArrayList; import static org.sonar.db.metric.RemovedMetricConverter.REMOVED_METRIC; public class RegisterMetrics implements Startable { private static final Logger LOG = Loggers.get(RegisterMetrics.class); - /** - * Those metrics will be removed soon from the plugin API, so let's not register them in the database - */ - private static final Set<String> SOON_TO_BE_REMOVED_FROM_CORE_API_METRIC = Set.of( - CoreMetrics.COMPLEXITY_IN_CLASSES_KEY, - CoreMetrics.COMPLEXITY_IN_FUNCTIONS_KEY, - CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION_KEY, - CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY, - CoreMetrics.FUNCTION_COMPLEXITY_KEY, - CoreMetrics.CLASS_COMPLEXITY_KEY, - CoreMetrics.FILE_COMPLEXITY_KEY); private final DbClient dbClient; private final UuidFactory uuidFactory; @@ -79,8 +66,10 @@ public class RegisterMetrics implements Startable { @Override public void start() { - FluentIterable<Metric> metricsToRegister = concat(getCoreMetrics(), getPluginMetrics()) - .filter(m -> !REMOVED_METRIC.equals(m.getKey())); + List<Metric> metricsToRegister = new ArrayList<>(); + metricsToRegister.addAll(CoreMetrics.getMetrics()); + metricsToRegister.addAll(getPluginMetrics()); + metricsToRegister.removeIf(m -> REMOVED_METRIC.equals(m.getKey())); register(metricsToRegister); } @@ -131,13 +120,6 @@ public class RegisterMetrics implements Startable { } } - private static List<Metric> getCoreMetrics() { - return CoreMetrics.getMetrics() - .stream() - .filter(m -> !SOON_TO_BE_REMOVED_FROM_CORE_API_METRIC.contains(m.getKey())) - .toList(); - } - @VisibleForTesting List<Metric> getPluginMetrics() { List<Metric> metricsToRegister = newArrayList(); @@ -153,7 +135,7 @@ public class RegisterMetrics implements Startable { private static void checkMetrics(Map<String, Metrics> metricsByRepository, Metrics metrics) { for (Metric metric : metrics.getMetrics()) { String metricKey = metric.getKey(); - if (getCoreMetrics().contains(metric)) { + if (CoreMetrics.getMetrics().contains(metric)) { throw new IllegalStateException(String.format("Metric [%s] is already defined by SonarQube", metricKey)); } Metrics anotherRepository = metricsByRepository.get(metricKey); diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/issue/index/AsyncIssueIndexCreationTelemetryTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/issue/index/AsyncIssueIndexCreationTelemetryTest.java index cb8bab7a24d..631d0f5464e 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/issue/index/AsyncIssueIndexCreationTelemetryTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/issue/index/AsyncIssueIndexCreationTelemetryTest.java @@ -20,11 +20,13 @@ package org.sonar.server.issue.index; import java.io.IOException; +import java.lang.reflect.Field; import java.time.Clock; import java.util.Optional; import java.util.concurrent.ScheduledFuture; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.platform.commons.util.ReflectionUtils; import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.sonar.api.config.Configuration; @@ -32,6 +34,7 @@ import org.sonar.api.platform.Server; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; +import org.sonar.db.ce.CeQueueDao; import org.sonar.telemetry.core.TelemetryClient; import static org.assertj.core.api.Assertions.assertThat; @@ -58,8 +61,7 @@ class AsyncIssueIndexCreationTelemetryTest { private final IssueIndexMonitoringScheduler scheduler = mock(); private final ArgumentCaptor<Runnable> telemetrySyncRunnable = ArgumentCaptor.forClass(Runnable.class); private final Configuration configuration = mock(); - private final AsyncIssueIndexCreationTelemetry asyncIssueIndexCreationTelemetry = new AsyncIssueIndexCreationTelemetry( - issueIndexSyncProgressChecker, + private final AsyncIssueIndexCreationTelemetry underTest = new AsyncIssueIndexCreationTelemetry( dbClient, telemetryClient, server, @@ -84,14 +86,14 @@ class AsyncIssueIndexCreationTelemetryTest { reset(configuration); when(configuration.getBoolean(SONAR_TELEMETRY_ENABLE.getKey())).thenReturn(Optional.of(false)); - asyncIssueIndexCreationTelemetry.startIndexCreationMonitoringToSendTelemetry(100); + underTest.startIndexCreationMonitoringToSendTelemetry(100); verify(scheduler, never()).scheduleAtFixedRate(any(), anyLong(), anyLong(), any()); } @Test void whenSynchroIsNotFinished_thenRetry() throws IOException { - asyncIssueIndexCreationTelemetry.startIndexCreationMonitoringToSendTelemetry(100); + underTest.startIndexCreationMonitoringToSendTelemetry(100); verify(scheduler).scheduleAtFixedRate(any(), anyLong(), anyLong(), any()); @@ -107,4 +109,19 @@ class AsyncIssueIndexCreationTelemetryTest { .contains(AsyncIssueIndexCreationTelemetry.KEY_ASYNC_ISSUE_INDEXING_TASK_TOTAL_COUNT) .contains(AsyncIssueIndexCreationTelemetry.KEY_ASYNC_ISSUE_INDEXING_TASK_FAILURE_COUNT); } + + @Test + void tryToSendTelemetry_whenNoPendingTasks_thenSendTelemetry() throws IOException, IllegalAccessException { + CeQueueDao ceQueueDao = mock(); + when(ceQueueDao.hasAnyIssueSyncTaskPendingOrInProgress(any())).thenReturn(false); + when(dbClient.ceQueueDao()).thenReturn(ceQueueDao); + + Field field = ReflectionUtils.findFields(underTest.getClass(), f -> f.getName().equals("currentMonitoring"), ReflectionUtils.HierarchyTraversalMode.TOP_DOWN).get(0); + field.setAccessible(true); + field.set(underTest, mock(ScheduledFuture.class)); + + underTest.tryToSendTelemetry(); + + verify(telemetryClient).uploadMetric(any()); + } } diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/RulesRegistrationContextTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/RulesRegistrationContextTest.java new file mode 100644 index 00000000000..4ea0c11e7c6 --- /dev/null +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/RulesRegistrationContextTest.java @@ -0,0 +1,69 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.rule.registration; + +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.event.Level; +import org.sonar.api.testfixtures.log.LogTesterJUnit5; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.rule.DeprecatedRuleKeyDto; +import org.sonar.db.rule.RuleDao; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class RulesRegistrationContextTest { + + @RegisterExtension + private final LogTesterJUnit5 logTester = new LogTesterJUnit5(); + + @Test + void whenDeprecatedRuleIsNotFound_thenWarningLogTraceIsProduced() { + DbClient dbClient = mock(); + DbSession dbSession = mock(); + RuleDao ruleDao = mock(); + when(dbClient.ruleDao()).thenReturn(ruleDao); + when(ruleDao.selectAll(dbSession)).thenReturn(List.of()); + when(ruleDao.selectAllDeprecatedRuleKeys(dbSession)).thenReturn(Set.of( + createDeprecatedRuleKeyDto("oldKey", "oldRepo", "newKey", "uuid") + )); + when(ruleDao.selectAllRuleParams(dbSession)).thenReturn(List.of()); + + RulesRegistrationContext.create(dbClient, dbSession); + + assertThat(logTester.logs(Level.WARN)). + contains("Could not retrieve rule with uuid newKey referenced by a deprecated rule key. " + + "The following deprecated rule keys seem to be referencing a non-existing rule: [oldRepo:oldKey]"); + } + + private DeprecatedRuleKeyDto createDeprecatedRuleKeyDto(String oldKey, String oldRepo, String newKey, String uuid) { + DeprecatedRuleKeyDto dto = new DeprecatedRuleKeyDto(); + dto.setOldRuleKey(oldKey); + dto.setOldRepositoryKey(oldRepo); + dto.setRuleUuid(newKey); + dto.setUuid(uuid); + return dto; + } +} |