aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-06-08 17:51:17 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-07-11 10:15:10 +0200
commit81a6eef465d500e89d7bbf3a818fed1910951c84 (patch)
tree35f93b4f050e55345e1e62a8027f57eeae21a2c8 /server/sonar-server
parentb631f20affe9c7d1bb4bf2e66c1b47d68a8438b5 (diff)
downloadsonarqube-81a6eef465d500e89d7bbf3a818fed1910951c84.tar.gz
sonarqube-81a6eef465d500e89d7bbf3a818fed1910951c84.zip
SONAR-8785 cache DbSession in ThreadLocals for HTTP requests
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java21
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/metric/DefaultMetricFinderTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/metric/ws/DomainsActionTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java29
5 files changed, 51 insertions, 7 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java
index 10bffed4ced..6de6ea8288a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java
@@ -21,6 +21,7 @@ package org.sonar.server.platform.platformlevel;
import java.util.Properties;
import javax.annotation.Nullable;
+import org.sonar.db.DBSessionsImpl;
import org.sonar.api.SonarQubeSide;
import org.sonar.api.SonarQubeVersion;
import org.sonar.api.internal.ApiVersion;
@@ -102,6 +103,7 @@ public class PlatformLevel1 extends PlatformLevel {
ThreadLocalUserSession.class,
// DB
+ DBSessionsImpl.class,
DbClient.class,
DaoModule.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java b/server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java
index d20232aae20..26c23e569bd 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java
@@ -30,12 +30,16 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.sonar.db.DBSessions;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import org.sonar.server.authentication.UserSessionInitializer;
import org.sonar.server.organization.DefaultOrganizationCache;
import org.sonar.server.platform.Platform;
import org.sonar.server.setting.ThreadLocalSettings;
public class UserSessionFilter implements Filter {
+ private static final Logger LOG = Loggers.get(UserSessionFilter.class);
private final Platform platform;
public UserSessionFilter() {
@@ -52,20 +56,27 @@ public class UserSessionFilter implements Filter {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
+ DBSessions dbSessions = platform.getContainer().getComponentByType(DBSessions.class);
ThreadLocalSettings settings = platform.getContainer().getComponentByType(ThreadLocalSettings.class);
DefaultOrganizationCache defaultOrganizationCache = platform.getContainer().getComponentByType(DefaultOrganizationCache.class);
UserSessionInitializer userSessionInitializer = platform.getContainer().getComponentByType(UserSessionInitializer.class);
- defaultOrganizationCache.load();
+ LOG.trace("{} serves {}", Thread.currentThread(), request.getRequestURI());
+ dbSessions.enableCaching();
try {
- settings.load();
+ defaultOrganizationCache.load();
try {
- doFilter(request, response, chain, userSessionInitializer);
+ settings.load();
+ try {
+ doFilter(request, response, chain, userSessionInitializer);
+ } finally {
+ settings.unload();
+ }
} finally {
- settings.unload();
+ defaultOrganizationCache.unload();
}
} finally {
- defaultOrganizationCache.unload();
+ dbSessions.disableCaching();
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/metric/DefaultMetricFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/metric/DefaultMetricFinderTest.java
index c72140fd88a..504249c23cf 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/metric/DefaultMetricFinderTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/metric/DefaultMetricFinderTest.java
@@ -26,6 +26,7 @@ import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
+import org.sonar.db.TestDBSessions;
import org.sonar.db.metric.MetricDao;
import static org.hamcrest.core.Is.is;
@@ -43,7 +44,7 @@ public class DefaultMetricFinderTest {
@Before
public void setUp() {
dbTester.prepareDbUnit(DefaultMetricFinderTest.class, "shared.xml");
- finder = new DefaultMetricFinder(new DbClient(dbTester.database(), dbTester.myBatis(), new MetricDao()));
+ finder = new DefaultMetricFinder(new DbClient(dbTester.database(), dbTester.myBatis(), new TestDBSessions(dbTester.myBatis()), new MetricDao()));
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/metric/ws/DomainsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/metric/ws/DomainsActionTest.java
index 84c89561028..cbee45038ed 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/metric/ws/DomainsActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/metric/ws/DomainsActionTest.java
@@ -27,6 +27,7 @@ import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.TestDBSessions;
import org.sonar.db.metric.MetricDao;
import org.sonar.db.metric.MetricDto;
import org.sonar.server.ws.WsTester;
@@ -45,7 +46,7 @@ public class DomainsActionTest {
@Before
public void setUp() {
- dbClient = new DbClient(db.database(), db.myBatis(), new MetricDao());
+ dbClient = new DbClient(db.database(), db.myBatis(), new TestDBSessions(db.myBatis()), new MetricDao());
dbSession = dbClient.openSession(false);
ws = new WsTester(new MetricsWs(new DomainsAction(dbClient)));
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java
index 4ea52d16890..79ef9e2d898 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java
@@ -29,6 +29,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.Mockito;
+import org.sonar.db.DBSessions;
import org.sonar.server.authentication.UserSessionInitializer;
import org.sonar.server.organization.DefaultOrganizationCache;
import org.sonar.server.platform.Platform;
@@ -51,12 +52,14 @@ public class UserSessionFilterTest {
private HttpServletRequest request = mock(HttpServletRequest.class);
private HttpServletResponse response = mock(HttpServletResponse.class);
private FilterChain chain = mock(FilterChain.class);
+ private DBSessions dbSessions = mock(DBSessions.class);
private ThreadLocalSettings settings = mock(ThreadLocalSettings.class);
private DefaultOrganizationCache defaultOrganizationCache = mock(DefaultOrganizationCache.class);
private UserSessionFilter underTest = new UserSessionFilter(platform);
@Before
public void setUp() {
+ when(platform.getContainer().getComponentByType(DBSessions.class)).thenReturn(dbSessions);
when(platform.getContainer().getComponentByType(ThreadLocalSettings.class)).thenReturn(settings);
when(platform.getContainer().getComponentByType(DefaultOrganizationCache.class)).thenReturn(defaultOrganizationCache);
}
@@ -118,6 +121,32 @@ public class UserSessionFilterTest {
}
@Test
+ public void doFilter_enables_and_disables_caching_in_DbSessions() throws Exception {
+ mockNoUserSessionInitializer();
+
+ underTest.doFilter(request, response, chain);
+
+ InOrder inOrder = inOrder(dbSessions);
+ inOrder.verify(dbSessions).enableCaching();
+ inOrder.verify(dbSessions).disableCaching();
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void doFilter_disables_caching_in_DbSessions_even_if_chain_throws_exception() throws Exception {
+ mockNoUserSessionInitializer();
+ RuntimeException thrown = mockChainDoFilterError();
+
+ try {
+ underTest.doFilter(request, response, chain);
+ fail("A RuntimeException should have been thrown");
+ } catch (RuntimeException e) {
+ assertThat(e).isSameAs(thrown);
+ verify(dbSessions).disableCaching();
+ }
+ }
+
+ @Test
public void doFilter_unloads_Settings_even_if_DefaultOrganizationCache_unload_fails() throws Exception {
mockNoUserSessionInitializer();
RuntimeException thrown = new RuntimeException("Faking DefaultOrganizationCache.unload failing");