Skip to content

Commit

Permalink
SLLS-146 Switch issue sync to the new backend (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
kirill-knize-sonarsource authored May 17, 2023
1 parent 02df79d commit dc4deeb
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ public class SonarLintLanguageServer implements SonarLintExtendedLanguageServer,
this.settingsManager.addListener(lsLogOutput);
this.bindingManager = new ProjectBindingManager(enginesFactory, workspaceFoldersManager, settingsManager, client, globalLogOutput,
taintVulnerabilitiesCache, diagnosticPublisher, backendServiceFacade, openNotebooksCache);
vsCodeClient.setBindingManager(bindingManager);
this.settingsManager.setBindingManager(bindingManager);
this.telemetry = new SonarLintTelemetry(httpClientProvider, settingsManager, bindingManager, nodeJsRuntime, standaloneEngineManager, backendServiceFacade);
this.settingsManager.addListener(telemetry);
Expand All @@ -256,7 +257,7 @@ public class SonarLintLanguageServer implements SonarLintExtendedLanguageServer,
this.serverSentEventsHandler = new ServerSentEventsHandler(bindingManager, taintVulnerabilitiesCache,
taintVulnerabilityRaisedNotification, settingsManager, workspaceFoldersManager);
bindingManager.setServerSentEventsHandler(serverSentEventsHandler);
this.branchManager = new WorkspaceFolderBranchManager(client, bindingManager, serverSynchronizer);
this.branchManager = new WorkspaceFolderBranchManager(client, bindingManager, backendServiceFacade);
this.bindingManager.setBranchResolver(branchManager::getReferenceBranchNameForFolder);
this.workspaceFoldersManager.addListener(this.branchManager);
this.workspaceFoldersManager.setBindingManager(bindingManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.sonarsource.sonarlint.core.clientapi.backend.authentication.HelpGenerateUserTokenParams;
import org.sonarsource.sonarlint.core.clientapi.backend.authentication.HelpGenerateUserTokenResponse;
import org.sonarsource.sonarlint.core.clientapi.backend.binding.GetBindingSuggestionParams;
import org.sonarsource.sonarlint.core.clientapi.backend.branch.DidChangeActiveSonarProjectBranchParams;
import org.sonarsource.sonarlint.core.clientapi.backend.config.binding.BindingConfigurationDto;
import org.sonarsource.sonarlint.core.clientapi.backend.config.binding.DidUpdateBindingParams;
import org.sonarsource.sonarlint.core.clientapi.backend.config.scope.ConfigurationScopeDto;
Expand Down Expand Up @@ -167,6 +168,11 @@ public CompletableFuture<GetBindingSuggestionsResponse> getBindingSuggestion(Get
return initializedBackend().getBindingService().getBindingSuggestions(params);
}

public void notifyBackendOnBranchChanged(String folderUri, String newBranchName) {
var params = new DidChangeActiveSonarProjectBranchParams(folderUri, newBranchName);
initializedBackend().getSonarProjectBranchService().didChangeActiveSonarProjectBranch(params);
}

public CompletableFuture<HelpGenerateUserTokenResponse> helpGenerateUserToken(HelpGenerateUserTokenParams params) {
return initializedBackend().getAuthenticationHelperService().helpGenerateUserToken(params);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ private static InitializeParams toInitParams(BackendInitParams initParams) {
true,
initParams.getStandaloneRuleConfigByKey(),
true,
false,
false
true,
true
);
}

Expand Down Expand Up @@ -174,4 +174,8 @@ public CompletableFuture<HelpGenerateUserTokenResponse> helpGenerateUserToken(St
public void initialize(Map<String, ServerConnectionSettings> serverConnections) {
initOnce(serverConnections);
}

public void notifyBackendOnBranchChanged(String folderUri, String newBranchName) {
backend.notifyBackendOnBranchChanged(folderUri, newBranchName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.sonarsource.sonarlint.core.clientapi.client.sync.DidSynchronizeConfigurationScopeParams;
import org.sonarsource.sonarlint.core.commons.http.HttpClient;
import org.sonarsource.sonarlint.ls.SonarLintExtendedLanguageClient;
import org.sonarsource.sonarlint.ls.connected.ProjectBindingManager;
import org.sonarsource.sonarlint.ls.connected.api.RequestsHandlerServer;
import org.sonarsource.sonarlint.ls.connected.notifications.SmartNotifications;
import org.sonarsource.sonarlint.ls.http.ApacheHttpClientProvider;
Expand All @@ -44,6 +45,7 @@ public class SonarLintVSCodeClient implements SonarLintClient {
private final ApacheHttpClientProvider httpClientProvider;
private SmartNotifications smartNotifications;
private final RequestsHandlerServer server;
private ProjectBindingManager bindingManager;

public SonarLintVSCodeClient(SonarLintExtendedLanguageClient client, ApacheHttpClientProvider httpClientProvider, RequestsHandlerServer server) {
this.client = client;
Expand Down Expand Up @@ -123,23 +125,29 @@ public void showHotspot(org.sonarsource.sonarlint.core.clientapi.client.hotspot.

@Override
public CompletableFuture<Void> startProgress(StartProgressParams startProgressParams) {
throw new UnsupportedOperationException();
// no-op
return CompletableFuture.completedFuture(null);
}

@Override
public void reportProgress(ReportProgressParams reportProgressParams) {
throw new UnsupportedOperationException();
// no-op
}

@Override
public void didSynchronizeConfigurationScopes(DidSynchronizeConfigurationScopeParams didSynchronizeConfigurationScopeParams) {
throw new UnsupportedOperationException();
bindingManager.updateAllTaintIssues();
}

public void setSettingsManager(SettingsManager settingsManager) {
this.settingsManager = settingsManager;
}

public void setBindingManager(ProjectBindingManager bindingManager) {
this.bindingManager = bindingManager;
}


public void setSmartNotifications(SmartNotifications smartNotifications) {
this.smartNotifications = smartNotifications;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import org.sonarsource.sonarlint.core.commons.progress.ClientProgressMonitor;
import org.sonarsource.sonarlint.ls.AnalysisScheduler;
import org.sonarsource.sonarlint.ls.connected.ProjectBindingManager;
import org.sonarsource.sonarlint.ls.connected.ProjectBindingWrapper;
import org.sonarsource.sonarlint.ls.progress.ProgressFacade;
import org.sonarsource.sonarlint.ls.progress.ProgressManager;
import org.sonarsource.sonarlint.ls.settings.ServerConnectionSettings;
Expand Down Expand Up @@ -170,15 +169,6 @@ private static void syncIssuesForBranch(ConnectedSonarLintEngine engine, ServerC
engine.downloadAllServerHotspots(paramsAndHttpClient.getEndpointParams(), paramsAndHttpClient.getHttpClient(), projectKey, branchName, progressMonitor);
}

public void syncIssues(ProjectBindingWrapper binding, String branchName) {
var connectionId = binding.getConnectionId();
var paramsAndHttpClient = bindingManager.getServerConfigurationFor(connectionId);
if (paramsAndHttpClient == null) {
return;
}
syncIssuesForBranch(binding.getEngine(), paramsAndHttpClient, binding.getBinding().projectKey(), branchName, null);
}

public void shutdown() {
serverSyncTimer.cancel();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
import org.sonarsource.sonarlint.core.branch.GitUtils;
import org.sonarsource.sonarlint.ls.SonarLintExtendedLanguageClient;
import org.sonarsource.sonarlint.ls.backend.BackendServiceFacade;
import org.sonarsource.sonarlint.ls.connected.ProjectBindingManager;
import org.sonarsource.sonarlint.ls.connected.ProjectBindingWrapper;
import org.sonarsource.sonarlint.ls.connected.sync.ServerSynchronizer;
import org.sonarsource.sonarlint.ls.util.Utils;

public class WorkspaceFolderBranchManager implements WorkspaceFolderLifecycleListener {
Expand All @@ -44,18 +44,20 @@ public class WorkspaceFolderBranchManager implements WorkspaceFolderLifecycleLis
private final Map<URI, Optional<String>> referenceBranchNameByFolderUri = new ConcurrentHashMap<>();
private final SonarLintExtendedLanguageClient client;
private final ProjectBindingManager bindingManager;
private final ServerSynchronizer serverSynchronizer;
private final ExecutorService executorService;
private final BackendServiceFacade backendServiceFacade;

public WorkspaceFolderBranchManager(SonarLintExtendedLanguageClient client, ProjectBindingManager bindingManager, ServerSynchronizer serverSynchronizer) {
this(client, bindingManager, serverSynchronizer, Executors.newSingleThreadExecutor(Utils.threadFactory("SonarLint Language Server Branch Manager", false)));
public WorkspaceFolderBranchManager(SonarLintExtendedLanguageClient client, ProjectBindingManager bindingManager,
BackendServiceFacade backendServiceFacade) {
this(client, bindingManager, backendServiceFacade,
Executors.newSingleThreadExecutor(Utils.threadFactory("SonarLint Language Server Branch Manager", false)));
}

WorkspaceFolderBranchManager(SonarLintExtendedLanguageClient client, ProjectBindingManager bindingManager, ServerSynchronizer serverSynchronizer,
ExecutorService executorService) {
WorkspaceFolderBranchManager(SonarLintExtendedLanguageClient client, ProjectBindingManager bindingManager,
BackendServiceFacade backendServiceFacade, ExecutorService executorService) {
this.client = client;
this.bindingManager = bindingManager;
this.serverSynchronizer = serverSynchronizer;
this.backendServiceFacade = backendServiceFacade;
this.executorService = executorService;
}

Expand Down Expand Up @@ -89,7 +91,7 @@ public void didBranchNameChange(URI folderUri, @Nullable String branchName) {
if (electedBranchName == null) {
electedBranchName = serverBranches.getMainBranchName();
}
serverSynchronizer.syncIssues(binding, electedBranchName);
backendServiceFacade.notifyBackendOnBranchChanged(folderUri.toString(), electedBranchName);
}
client.setReferenceBranchNameForFolder(SonarLintExtendedLanguageClient.ReferenceBranchForFolder.of(folderUri.toString(), electedBranchName));
referenceBranchNameByFolderUri.put(folderUri, Optional.ofNullable(electedBranchName));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.sonarsource.sonarlint.core.analysis.api.ClientModuleFileEvent;
import org.sonarsource.sonarlint.core.client.api.connected.ConnectedSonarLintEngine;
import org.sonarsource.sonarlint.core.clientapi.SonarLintBackend;
import org.sonarsource.sonarlint.core.clientapi.backend.branch.DidChangeActiveSonarProjectBranchParams;
import org.sonarsource.sonarlint.core.clientapi.backend.branch.SonarProjectBranchService;
import org.sonarsource.sonarlint.core.clientapi.backend.config.ConfigurationService;
import org.sonarsource.sonarlint.core.clientapi.backend.config.binding.DidUpdateBindingParams;
import org.sonarsource.sonarlint.core.clientapi.backend.hotspot.HotspotService;
Expand All @@ -37,6 +41,7 @@

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -101,5 +106,19 @@ void getConfigScopeDtoWithoutBinding() {
assertThat(result.getBinding().isBindingSuggestionDisabled()).isFalse();
}

@Test
void notifyBackendOnBranchChanged() {
var branchService = mock(SonarProjectBranchService.class);
when(backend.getSonarProjectBranchService()).thenReturn(branchService);
var paramsArgumentCaptor = ArgumentCaptor.forClass(DidChangeActiveSonarProjectBranchParams.class);
var expectedParams = new DidChangeActiveSonarProjectBranchParams("f", "b");

underTest.notifyBackendOnBranchChanged("f", "b");

verify(branchService).didChangeActiveSonarProjectBranch(paramsArgumentCaptor.capture());
var actualParams = paramsArgumentCaptor.getValue();
assertThat(expectedParams.getConfigScopeId()).isEqualTo(actualParams.getConfigScopeId());
assertThat(expectedParams.getNewActiveBranchName()).isEqualTo(actualParams.getNewActiveBranchName());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -42,6 +43,7 @@
import org.sonarsource.sonarlint.core.clientapi.client.smartnotification.ShowSmartNotificationParams;
import org.sonarsource.sonarlint.core.clientapi.client.sync.DidSynchronizeConfigurationScopeParams;
import org.sonarsource.sonarlint.ls.SonarLintExtendedLanguageClient;
import org.sonarsource.sonarlint.ls.connected.ProjectBindingManager;
import org.sonarsource.sonarlint.ls.connected.api.RequestsHandlerServer;
import org.sonarsource.sonarlint.ls.connected.notifications.SmartNotifications;
import org.sonarsource.sonarlint.ls.http.ApacheHttpClient;
Expand Down Expand Up @@ -69,12 +71,14 @@ class SonarLintVSCodeClientTests {
SonarLintVSCodeClient underTest;

RequestsHandlerServer server = mock(RequestsHandlerServer.class);
ProjectBindingManager bindingManager = mock(ProjectBindingManager.class);

@BeforeEach
public void setup() {
underTest = new SonarLintVSCodeClient(client, httpClientProvider, server);
underTest.setSmartNotifications(smartNotifications);
underTest.setSettingsManager(settingsManager);
underTest.setBindingManager(bindingManager);
}

@Test
Expand Down Expand Up @@ -191,19 +195,15 @@ void shouldDoNothingOnShowSmartNotificationWhenConnectionIsNotFound() {
}

@Test
void shouldThrowForStartProgress() {
assertThrows(UnsupportedOperationException.class, () -> underTest.startProgress(mock(StartProgressParams.class)));
void shouldReturnEmptyFutureForStartProgress() throws ExecutionException, InterruptedException {
assertThat(underTest.startProgress(mock(StartProgressParams.class)).get()).isNull();
}

@Test
void shouldThrowForReportProgress() {
assertThrows(UnsupportedOperationException.class, () -> underTest.reportProgress(mock(ReportProgressParams.class)));
}
void shouldUpdateAllTaintIssuesForDidSynchronizeConfigurationScopes() {
underTest.didSynchronizeConfigurationScopes(mock(DidSynchronizeConfigurationScopeParams.class));

@Test
void shouldThrowForDidSynchronizeConfigurationScopes() {
assertThrows(UnsupportedOperationException.class, () ->
underTest.didSynchronizeConfigurationScopes(mock(DidSynchronizeConfigurationScopeParams.class)));
verify(bindingManager).updateAllTaintIssues();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,12 @@
import org.sonarsource.sonarlint.core.client.api.connected.ConnectedSonarLintEngine;
import org.sonarsource.sonarlint.core.client.api.connected.ProjectBranches;
import org.sonarsource.sonarlint.core.serverconnection.ProjectBinding;
import org.sonarsource.sonarlint.ls.AnalysisScheduler;
import org.sonarsource.sonarlint.ls.SonarLintExtendedLanguageClient;
import org.sonarsource.sonarlint.ls.backend.BackendServiceFacade;
import org.sonarsource.sonarlint.ls.connected.ProjectBindingManager;
import org.sonarsource.sonarlint.ls.connected.ProjectBindingWrapper;
import org.sonarsource.sonarlint.ls.connected.sync.ServerSynchronizer;
import org.sonarsource.sonarlint.ls.progress.ProgressManager;
import org.sonarsource.sonarlint.ls.settings.ServerConnectionSettings;
import org.sonarsource.sonarlint.ls.util.Utils;
import testutils.ImmediateExecutorService;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -54,14 +53,15 @@ class WorkspaceFolderBranchManagerTests {

private SonarLintExtendedLanguageClient client;
private ProjectBindingManager bindingManager;
private BackendServiceFacade backendServiceFacade;
private WorkspaceFolderBranchManager underTest;

@BeforeEach
void setUp() {
client = mock(SonarLintExtendedLanguageClient.class);
bindingManager = mock(ProjectBindingManager.class);
ServerSynchronizer serverSynchronizer = new ServerSynchronizer(client, new ProgressManager(client), bindingManager, mock(AnalysisScheduler.class));
underTest = new WorkspaceFolderBranchManager(client, bindingManager, serverSynchronizer, new ImmediateExecutorService());
backendServiceFacade = mock(BackendServiceFacade.class);
underTest = new WorkspaceFolderBranchManager(client, bindingManager, backendServiceFacade, new ImmediateExecutorService());
}

@Test
Expand Down Expand Up @@ -149,8 +149,7 @@ void didBranchNameChangeTriggersSync(@TempDir Path gitProjectBasedir) throws Exc

underTest.didBranchNameChange(folderUri, "branchName");

verify(engine).syncServerIssues(any(), any(), eq(projectKey), eq("branchName"), any());
verify(engine).syncServerTaintIssues(any(), any(), eq(projectKey), eq("branchName"), any());
verify(backendServiceFacade).notifyBackendOnBranchChanged(folderUri.toString(), "branchName");
}

private void createAndCheckoutBranch(Path gitProjectBasedir, String currentBranchName) throws IOException, GitAPIException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ protected void setUpFolderSettings(Map<String, Map<String, Object>> folderSettin
setShowVerboseLogs(client.globalSettings, true);
setShowAnalyzerLogs(client.globalSettings, true);
addSonarQubeConnection(client.globalSettings, CONNECTION_ID, mockWebServerExtension.url("/"), "xxxxx");
String folderUri = folder1BaseDir.toUri().toString();
var folderUri = folder1BaseDir.toUri().toString();
bindProject(getFolderSettings(folderUri), CONNECTION_ID, PROJECT_KEY);
client.readyForTestsLatch = new CountDownLatch(1);
}
Expand Down Expand Up @@ -382,34 +382,6 @@ void shouldThrowExceptionForUnknownConnection() {
awaitUntilAsserted(() -> assertThat(future).isCompletedExceptionally());
}

// @Test
// void shouldGetTokenServerPath() throws ExecutionException, InterruptedException {
// mockWebServerExtension.addStringResponse("/api/system/status", "{\"status\": \"UP\", \"version\": \"9.7\", \"id\": \"xzy\"}");
// var serverUrl = mockWebServerExtension.url("");
// var cleanUrl = stripTrailingSlash(serverUrl);
// var params = new SonarLintExtendedLanguageServer.GenerateTokenParams(cleanUrl);
//
// var result = lsProxy.generateToken(params);
// var actual = result.get();
//
// assertThat(actual.getServerUrl())
// // Local port range is dynamic in range [64120-64130]
// .startsWith(cleanUrl + "/sonarlint/auth?ideName=SonarLint+LS+Medium+tests&port=641");
// }
//
// @Test
// void shouldGetTokenServerPathOldVersion() throws ExecutionException, InterruptedException {
// mockWebServerExtension.addStringResponse("/api/system/status", "{\"status\": \"UP\", \"version\": \"9.6\", \"id\": \"xzy\"}");
// var serverUrl = mockWebServerExtension.url("");
// var cleanUrl = stripTrailingSlash(serverUrl);
// var params = new SonarLintExtendedLanguageServer.GenerateTokenParams(cleanUrl);
//
// var result = lsProxy.generateToken(params);
// var actual = result.get();
//
// assertThat(actual.getServerUrl()).isEqualTo(cleanUrl + "/account/security");
// }

@Test
void shouldReturnErrorForInvalidUrl() {
var params = new SonarLintExtendedLanguageServer.GenerateTokenParams("invalid/url");
Expand Down Expand Up @@ -467,13 +439,6 @@ void checkLocalDetectionSupportedNotBound() throws ExecutionException, Interrupt
assertThat(result.getReason()).isEqualTo("The provided configuration scope does not exist: notBound");
}

private String stripTrailingSlash(String url) {
if (url.endsWith("/")) {
return url.substring(0, url.length() - 1);
}
return url;
}

private void mockNoIssuesNoHotspotsForProject() {
mockWebServerExtension.addStringResponse("/api/system/status", "{\"status\": \"UP\", \"version\": \"9.7\", \"id\": \"xzy\"}");
mockWebServerExtension.addProtobufResponseDelimited(
Expand Down

0 comments on commit dc4deeb

Please sign in to comment.