From 69d4485ff196a67ca318afed5e8cd65c2f057dcd Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 5 Jan 2022 13:44:09 +0100 Subject: [PATCH 1/4] mockup update --- .../lms/impl/mockup/MockupLmsAPITemplate.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupLmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupLmsAPITemplate.java index 35e67a9f..fd039f43 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupLmsAPITemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupLmsAPITemplate.java @@ -66,22 +66,22 @@ public class MockupLmsAPITemplate implements LmsAPITemplate { "2020-01-01T09:00:00Z", null, "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( "quiz2", institutionId, lmsSetupId, lmsType, "Demo Quiz 2 (MOCKUP)", "

Demo Quiz Mockup

", - "2020-01-01T09:00:00Z", "2022-01-01T09:00:00Z", "http://lms.mockup.com/api/")); + "2020-01-01T09:00:00Z", "2025-01-01T09:00:00Z", "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( "quiz3", institutionId, lmsSetupId, lmsType, "Demo Quiz 3 (MOCKUP)", "

Demo Quiz Mockup

", "2018-07-30T09:00:00Z", "2018-08-01T00:00:00Z", "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( "quiz4", institutionId, lmsSetupId, lmsType, "Demo Quiz 4 (MOCKUP)", "

Demo Quiz Mockup

", - "2018-01-01T00:00:00Z", "2019-01-01T00:00:00Z", "http://lms.mockup.com/api/")); + "2018-01-01T00:00:00Z", "2025-01-01T00:00:00Z", "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( "quiz5", institutionId, lmsSetupId, lmsType, "Demo Quiz 5 (MOCKUP)", "

Demo Quiz Mockup

", - "2018-01-01T09:00:00Z", "2022-01-01T09:00:00Z", "http://lms.mockup.com/api/")); + "2018-01-01T09:00:00Z", "2025-01-01T09:00:00Z", "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( "quiz6", institutionId, lmsSetupId, lmsType, "Demo Quiz 6 (MOCKUP)", "

Demo Quiz Mockup

", - "2019-01-01T09:00:00Z", "2022-01-01T09:00:00Z", "http://lms.mockup.com/api/")); + "2019-01-01T09:00:00Z", "2025-01-01T09:00:00Z", "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( "quiz7", institutionId, lmsSetupId, lmsType, "Demo Quiz 7 (MOCKUP)", "

Demo Quiz Mockup

", - "2018-01-01T09:00:00Z", "2022-01-01T09:00:00Z", "http://lms.mockup.com/api/")); + "2018-01-01T09:00:00Z", "2025-01-01T09:00:00Z", "http://lms.mockup.com/api/")); this.mockups.add(new QuizData( "quiz10", institutionId, lmsSetupId, lmsType, "Demo Quiz 10 (MOCKUP)", From 8435a3a6a0b9a65f450c0310130e5fd4cdb57ac4 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 5 Jan 2022 15:22:17 +0100 Subject: [PATCH 2/4] fixed OAuth2 JDBCTokenCache --- .../weblayer/oauth/CachableJdbcTokenStore.java | 10 +++++----- src/main/resources/config/ehcache.xml | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/CachableJdbcTokenStore.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/CachableJdbcTokenStore.java index 8933b1bd..8dd35ed5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/CachableJdbcTokenStore.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/CachableJdbcTokenStore.java @@ -50,10 +50,6 @@ public class CachableJdbcTokenStore implements TokenStore { } @Override - @Cacheable( - cacheNames = CACHE_NAME, - key = "#token", - unless = "#result == null") public OAuth2Authentication readAuthentication(final OAuth2AccessToken token) { if (log.isDebugEnabled()) { log.debug("Read authentication from persistent and cache if available"); @@ -68,6 +64,10 @@ public class CachableJdbcTokenStore implements TokenStore { } @Override + @Cacheable( + cacheNames = CACHE_NAME, + key = "#tokenValue", + unless = "#result == null") public OAuth2AccessToken readAccessToken(final String tokenValue) { return this.jdbcTokenStore.readAccessToken(tokenValue); } @@ -75,7 +75,7 @@ public class CachableJdbcTokenStore implements TokenStore { @Override @CacheEvict( cacheNames = CACHE_NAME, - key = "#token") + key = "#token.getValue()") public void removeAccessToken(final OAuth2AccessToken token) { if (log.isDebugEnabled()) { log.debug("Evict token from cache and remove it also from persistent store"); diff --git a/src/main/resources/config/ehcache.xml b/src/main/resources/config/ehcache.xml index ecc1b6f6..db9b470a 100644 --- a/src/main/resources/config/ehcache.xml +++ b/src/main/resources/config/ehcache.xml @@ -61,10 +61,10 @@ - org.springframework.security.oauth2.common.OAuth2AccessToken - org.springframework.security.oauth2.provider.OAuth2Authentication + java.lang.String + org.springframework.security.oauth2.common.OAuth2AccessToken - 24 + 1 100 From c0c58763bf1a999b3fdb9c87d11fe03aa8d615df Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 5 Jan 2022 15:29:49 +0100 Subject: [PATCH 3/4] fixed OAuth2 JDBCTokenStore cache --- .../weblayer/oauth/CachableJdbcTokenStore.java | 10 +++++----- src/main/resources/config/ehcache.xml | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/CachableJdbcTokenStore.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/CachableJdbcTokenStore.java index 8933b1bd..8dd35ed5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/CachableJdbcTokenStore.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/CachableJdbcTokenStore.java @@ -50,10 +50,6 @@ public class CachableJdbcTokenStore implements TokenStore { } @Override - @Cacheable( - cacheNames = CACHE_NAME, - key = "#token", - unless = "#result == null") public OAuth2Authentication readAuthentication(final OAuth2AccessToken token) { if (log.isDebugEnabled()) { log.debug("Read authentication from persistent and cache if available"); @@ -68,6 +64,10 @@ public class CachableJdbcTokenStore implements TokenStore { } @Override + @Cacheable( + cacheNames = CACHE_NAME, + key = "#tokenValue", + unless = "#result == null") public OAuth2AccessToken readAccessToken(final String tokenValue) { return this.jdbcTokenStore.readAccessToken(tokenValue); } @@ -75,7 +75,7 @@ public class CachableJdbcTokenStore implements TokenStore { @Override @CacheEvict( cacheNames = CACHE_NAME, - key = "#token") + key = "#token.getValue()") public void removeAccessToken(final OAuth2AccessToken token) { if (log.isDebugEnabled()) { log.debug("Evict token from cache and remove it also from persistent store"); diff --git a/src/main/resources/config/ehcache.xml b/src/main/resources/config/ehcache.xml index ecc1b6f6..db9b470a 100644 --- a/src/main/resources/config/ehcache.xml +++ b/src/main/resources/config/ehcache.xml @@ -61,10 +61,10 @@ - org.springframework.security.oauth2.common.OAuth2AccessToken - org.springframework.security.oauth2.provider.OAuth2Authentication + java.lang.String + org.springframework.security.oauth2.common.OAuth2AccessToken - 24 + 1 100 From fda22b5b7e1e67cc5786feda61137e9f9cae2138 Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 6 Jan 2022 09:28:41 +0100 Subject: [PATCH 4/4] Made monitoring instruction propagation async to not block the request --- .../session/SEBClientInstructionService.java | 26 +++++++++++++++++++ .../impl/SEBClientInstructionServiceImpl.java | 4 +-- .../api/ExamMonitoringController.java | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/SEBClientInstructionService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/SEBClientInstructionService.java index e06ba41a..878b37da 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/SEBClientInstructionService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/SEBClientInstructionService.java @@ -14,8 +14,14 @@ import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import ch.ethz.seb.sebserver.SEBServerInitEvent; import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.async.AsyncServiceSpringConfig; import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction; import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType; import ch.ethz.seb.sebserver.gbl.util.Result; @@ -27,11 +33,31 @@ import ch.ethz.seb.sebserver.webservice.WebserviceInfo; * If there is an instruction in the queue for a specified SEB Client. */ public interface SEBClientInstructionService { + static final Logger log = LoggerFactory.getLogger(SEBClientInstructionService.class); + /** Get the underling WebserviceInfo * * @return the underling WebserviceInfo */ WebserviceInfo getWebserviceInfo(); + /** This is called from the SEB Server initializer to initialize this service. + * Do not use this directly. */ + @EventListener(SEBServerInitEvent.class) + void init(); + + /** Used to register a SEB client instruction for one or more active client connections + * within an other background thread. This is none-blocking. + * + * @param clientInstruction the ClientInstruction instance to register + * @return A Result refer to a void marker or to an error if happened */ + @Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME) + default void registerInstructionAsync(final ClientInstruction clientInstruction) { + registerInstruction(clientInstruction, false) + .onError(error -> log.error("Failed to register client instruction asynchronously: {}", + clientInstruction, + error)); + } + /** Used to register a SEB client instruction for one or more active client connections * * @param clientInstruction the ClientInstruction instance to register diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientInstructionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientInstructionServiceImpl.java index 513f77ec..40e04a0c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientInstructionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientInstructionServiceImpl.java @@ -22,11 +22,9 @@ import org.joda.time.DateTimeZone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import ch.ethz.seb.sebserver.SEBServerInit; -import ch.ethz.seb.sebserver.SEBServerInitEvent; import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.JSONMapper; import ch.ethz.seb.sebserver.gbl.model.EntityKey; @@ -80,7 +78,7 @@ public class SEBClientInstructionServiceImpl implements SEBClientInstructionServ return this.webserviceInfo; } - @EventListener(SEBServerInitEvent.class) + @Override public void init() { SEBServerInit.INIT_LOGGER.info("------>"); SEBServerInit.INIT_LOGGER.info("------> Run SEBInstructionService..."); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamMonitoringController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamMonitoringController.java index d0e06bed..072c65a8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamMonitoringController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamMonitoringController.java @@ -222,7 +222,7 @@ public class ExamMonitoringController { @Valid @RequestBody final ClientInstruction clientInstruction) { checkPrivileges(institutionId, examId); - this.sebClientInstructionService.registerInstruction(clientInstruction); + this.sebClientInstructionService.registerInstructionAsync(clientInstruction); } @RequestMapping(