Browse Source

SONAR-20389 Prevent race condition from happening when servlet is starting up

tags/10.3.0.82913
Aurelien Poscia 8 months ago
parent
commit
f48dd4c125

+ 12
- 1
server/sonar-webserver/src/main/java/org/sonar/server/platform/web/ApiV2Servlet.java View File

@@ -21,6 +21,7 @@ package org.sonar.server.platform.web;

import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.function.Function;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
@@ -42,6 +43,8 @@ public class ApiV2Servlet implements Servlet {
private DispatcherServlet dispatcherLevel4 = null;
private DispatcherServlet dispatcherSafeMode = null;

private final CountDownLatch safeModeInitializationCompletedLatch = new CountDownLatch(2);

public ApiV2Servlet() {
this.servletProvider = DispatcherServlet::new;
}
@@ -69,11 +72,13 @@ public class ApiV2Servlet implements Servlet {
}
if (dispatcherSafeMode != null) {
dispatcherSafeMode.init(config);
safeModeInitializationCompletedLatch.countDown();
}
}

public void initDispatcherSafeMode(PlatformLevel platformLevel) {
this.dispatcherSafeMode = initDispatcherServlet(platformLevel, SafeModeWebConfig.class);
dispatcherSafeMode = initDispatcherServlet(platformLevel, SafeModeWebConfig.class);
safeModeInitializationCompletedLatch.countDown();
}

public void initDispatcherLevel4(PlatformLevel platformLevel) {
@@ -116,6 +121,12 @@ public class ApiV2Servlet implements Servlet {

private void destroyDispatcherSafeMode() {
if (dispatcherSafeMode != null) {
try {
safeModeInitializationCompletedLatch.await();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new IllegalStateException(ie);
}
DispatcherServlet dispatcherToDestroy = dispatcherSafeMode;
dispatcherSafeMode = null;
dispatcherToDestroy.destroy();

+ 5
- 3
server/sonar-webserver/src/test/java/org/sonar/server/platform/web/ApiV2ServletTest.java View File

@@ -97,8 +97,8 @@ public class ApiV2ServletTest {
DispatcherServlet mockDispatcherServletLevel4 = mock(DispatcherServlet.class);

underTest.setServletProvider(context -> mockDispatcherServletSafeMode);
underTest.init(mock(ServletConfig.class));
underTest.initDispatcherSafeMode(mockPlatformLevel);
underTest.init(mock(ServletConfig.class));
ServletRequest mockRequest1 = mock(ServletRequest.class);
ServletResponse mockResponse1 = mock(ServletResponse.class);
underTest.service(mockRequest1, mockResponse1);
@@ -141,13 +141,14 @@ public class ApiV2ServletTest {
}

@Test
public void initDispatcherServlet_initLevel4ShouldDestroySafeMode() {
public void initDispatcherServlet_initLevel4ShouldDestroySafeMode() throws ServletException {
PlatformLevel mockPlatformLevel = getMockPlatformLevel();
ApiV2Servlet underTest = new ApiV2Servlet();

DispatcherServlet mockDispatcherServletSafeMode = mock(DispatcherServlet.class);
underTest.setServletProvider(context -> mockDispatcherServletSafeMode);
underTest.initDispatcherSafeMode(mockPlatformLevel);
underTest.init(mock(ServletConfig.class));

underTest.setServletProvider(context -> mock(DispatcherServlet.class));

@@ -171,13 +172,14 @@ public class ApiV2ServletTest {
}

@Test
public void destroy_shouldDestroyDispatcherSafeMode() {
public void destroy_shouldDestroyDispatcherSafeMode() throws ServletException {
PlatformLevel mockPlatformLevel = getMockPlatformLevel();
ApiV2Servlet underTest = new ApiV2Servlet();
DispatcherServlet mockDispatcherServletSafeMode = mock(DispatcherServlet.class);

underTest.setServletProvider(context -> mockDispatcherServletSafeMode);
underTest.initDispatcherSafeMode(mockPlatformLevel);
underTest.init(mock(ServletConfig.class));

underTest.destroy();


Loading…
Cancel
Save