private final SonarLintClientPermissionsValidator sonarLintClientPermissionsValidator;
private final List<SonarLintClient> clients = new CopyOnWriteArrayList<>();
+ private final RuleActivatorEventsDistributor eventsDistributor;
+
+ private boolean registeredToEvents = false;
public SonarLintClientsRegistry(RuleActivatorEventsDistributor ruleActivatorEventsDistributor, SonarLintClientPermissionsValidator permissionsValidator) {
this.sonarLintClientPermissionsValidator = permissionsValidator;
-
- ruleActivatorEventsDistributor.subscribe(this);
+ this.eventsDistributor = ruleActivatorEventsDistributor;
}
public void registerClient(SonarLintClient sonarLintClient) {
+ ensureListeningToEvents();
clients.add(sonarLintClient);
sonarLintClient.scheduleHeartbeat();
sonarLintClient.addListener(new SonarLintClientEventsListener(sonarLintClient));
LOG.debug("Registering new SonarLint client");
}
+ private synchronized void ensureListeningToEvents() {
+ if (registeredToEvents) {
+ return;
+ }
+ try {
+ eventsDistributor.subscribe(this);
+ registeredToEvents = true;
+ } catch (RuntimeException e) {
+ LOG.warn("Can not listen to rule activation events for server push. Web Server might not have started fully yet.", e);
+ }
+ }
+
public void unregisterClient(SonarLintClient client) {
client.close();
clients.remove(client);
import org.sonar.server.pushapi.qualityprofile.StandaloneRuleActivatorEventsDistributor;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
private final ServletOutputStream outputStream = mock(ServletOutputStream.class);
private final SonarLintClientPermissionsValidator permissionsValidator = mock(SonarLintClientPermissionsValidator.class);
+ private final StandaloneRuleActivatorEventsDistributor eventsDistributor = mock(StandaloneRuleActivatorEventsDistributor.class);
private SonarLintClientsRegistry underTest;
@Before
public void before() {
- underTest = new SonarLintClientsRegistry(mock(StandaloneRuleActivatorEventsDistributor.class), permissionsValidator);
+ underTest = new SonarLintClientsRegistry(eventsDistributor, permissionsValidator);
}
@Test
verify(sonarLintClient, times(2)).close();
}
+ @Test
+ public void registerClient_whenCalledFirstTime_registerAlsoToListenToEvents() {
+ underTest.registerClient(createSampleSLClient());
+
+ verify(eventsDistributor).subscribe(underTest);
+ }
+
+ @Test
+ public void registerClient_whenCalledSecondTime_doNotRegisterToEvents() {
+ underTest.registerClient(createSampleSLClient());
+ clearInvocations(eventsDistributor);
+
+ underTest.registerClient(createSampleSLClient());
+ verifyNoInteractions(eventsDistributor);
+ }
+
+ @Test
+ public void registerClient_whenExceptionAndCalledSecondTime_registerToEvents() {
+ doThrow(new RuntimeException()).when(eventsDistributor).subscribe(any());
+ underTest.registerClient(createSampleSLClient());
+ clearInvocations(eventsDistributor);
+
+ underTest.registerClient(createSampleSLClient());
+ verify(eventsDistributor).subscribe(underTest);
+ }
+
private SonarLintClient createSampleSLClient() {
SonarLintClient mock = mock(SonarLintClient.class);
when(mock.getLanguages()).thenReturn(Set.of("java"));