diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-06-08 17:51:17 +0200 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-07-11 10:15:10 +0200 |
commit | 81a6eef465d500e89d7bbf3a818fed1910951c84 (patch) | |
tree | 35f93b4f050e55345e1e62a8027f57eeae21a2c8 /server/sonar-server | |
parent | b631f20affe9c7d1bb4bf2e66c1b47d68a8438b5 (diff) | |
download | sonarqube-81a6eef465d500e89d7bbf3a818fed1910951c84.tar.gz sonarqube-81a6eef465d500e89d7bbf3a818fed1910951c84.zip |
SONAR-8785 cache DbSession in ThreadLocals for HTTP requests
Diffstat (limited to 'server/sonar-server')
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"); |