fixed caching issue with Exam Config changes on running exams
This commit is contained in:
parent
278bdf4673
commit
5aa3671608
13 changed files with 136 additions and 10 deletions
1
docker/.gitignore
vendored
Normal file
1
docker/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/test/
|
|
@ -32,7 +32,7 @@ ENTRYPOINT exec java \
|
||||||
-Dcom.sun.management.jmxremote \
|
-Dcom.sun.management.jmxremote \
|
||||||
-Dcom.sun.management.jmxremote.port=9090 \
|
-Dcom.sun.management.jmxremote.port=9090 \
|
||||||
-Dcom.sun.management.jmxremote.rmi.port=9090 \
|
-Dcom.sun.management.jmxremote.rmi.port=9090 \
|
||||||
-Djava.rmi.server.hostname=0.0.0.0 \
|
-Djava.rmi.server.hostname=127.0.0.1 \
|
||||||
-Dcom.sun.management.jmxremote.ssl=false \
|
-Dcom.sun.management.jmxremote.ssl=false \
|
||||||
-Dcom.sun.management.jmxremote.authenticate=false \
|
-Dcom.sun.management.jmxremote.authenticate=false \
|
||||||
-jar seb-server-"${SEBSERVER_VERSION}"-SNAPSHOT.jar \
|
-jar seb-server-"${SEBSERVER_VERSION}"-SNAPSHOT.jar \
|
||||||
|
|
|
@ -6,7 +6,7 @@ server.servlet.session.cookie.http-only=true
|
||||||
server.servlet.session.tracking-modes=cookie
|
server.servlet.session.tracking-modes=cookie
|
||||||
|
|
||||||
# database server
|
# database server
|
||||||
datastore.mariadb.server.address=test-mariadb
|
datastore.mariadb.server.address=seb-server-mariadb
|
||||||
datastore.mariadb.server.port=3306
|
datastore.mariadb.server.port=3306
|
||||||
|
|
||||||
# data source configuration
|
# data source configuration
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO;
|
||||||
|
@ -21,14 +23,14 @@ public interface ExamConfigurationMapDAO extends
|
||||||
* @param examId The Exam mapping identifier
|
* @param examId The Exam mapping identifier
|
||||||
* @param configurationNodeId the ConfigurationNode mapping identifier
|
* @param configurationNodeId the ConfigurationNode mapping identifier
|
||||||
* @return Result refer to the ExamConfigurationMap with specified mapping or to an exception if happened */
|
* @return Result refer to the ExamConfigurationMap with specified mapping or to an exception if happened */
|
||||||
public Result<ExamConfigurationMap> byMapping(Long examId, Long configurationNodeId);
|
Result<ExamConfigurationMap> byMapping(Long examId, Long configurationNodeId);
|
||||||
|
|
||||||
/** Get the password cipher of a specific ExamConfigurationMap by the mapping identifiers
|
/** Get the password cipher of a specific ExamConfigurationMap by the mapping identifiers
|
||||||
*
|
*
|
||||||
* @param examId The Exam mapping identifier
|
* @param examId The Exam mapping identifier
|
||||||
* @param configurationNodeId the ConfigurationNode mapping identifier
|
* @param configurationNodeId the ConfigurationNode mapping identifier
|
||||||
* @return Result refer to the password cipher of specified mapping or to an exception if happened */
|
* @return Result refer to the password cipher of specified mapping or to an exception if happened */
|
||||||
public Result<CharSequence> getConfigPasswortCipher(Long examId, Long configurationNodeId);
|
Result<CharSequence> getConfigPasswortCipher(Long examId, Long configurationNodeId);
|
||||||
|
|
||||||
/** Get the ConfigurationNode identifier of the default Exam Configuration of
|
/** Get the ConfigurationNode identifier of the default Exam Configuration of
|
||||||
* the Exam with specified identifier.
|
* the Exam with specified identifier.
|
||||||
|
@ -36,7 +38,7 @@ public interface ExamConfigurationMapDAO extends
|
||||||
* @param examId The Exam identifier
|
* @param examId The Exam identifier
|
||||||
* @return ConfigurationNode identifier of the default Exam Configuration of
|
* @return ConfigurationNode identifier of the default Exam Configuration of
|
||||||
* the Exam with specified identifier */
|
* the Exam with specified identifier */
|
||||||
public Result<Long> getDefaultConfigurationForExam(Long examId);
|
Result<Long> getDefaultConfigurationForExam(Long examId);
|
||||||
|
|
||||||
/** Get the ConfigurationNode identifier of the Exam Configuration of
|
/** Get the ConfigurationNode identifier of the Exam Configuration of
|
||||||
* the Exam for a specified user identifier.
|
* the Exam for a specified user identifier.
|
||||||
|
@ -45,6 +47,12 @@ public interface ExamConfigurationMapDAO extends
|
||||||
* @param userId the user identifier
|
* @param userId the user identifier
|
||||||
* @return ConfigurationNode identifier of the Exam Configuration of
|
* @return ConfigurationNode identifier of the Exam Configuration of
|
||||||
* the Exam for a specified user identifier */
|
* the Exam for a specified user identifier */
|
||||||
public Result<Long> getUserConfigurationIdForExam(final Long examId, final String userId);
|
Result<Long> getUserConfigurationIdForExam(final Long examId, final String userId);
|
||||||
|
|
||||||
|
/** Get all id of Exams that has a relation to the given configuration id.
|
||||||
|
*
|
||||||
|
* @param configurationId
|
||||||
|
* @return */
|
||||||
|
Result<Collection<Long>> getExamIdsForConfigId(Long configurationId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,17 @@ public interface ExamDAO extends ActivatableEntityDAO<Exam, Exam>, BulkActionSup
|
||||||
|
|
||||||
Result<Collection<Long>> allIdsOfInstituion(Long institutionId);
|
Result<Collection<Long>> allIdsOfInstituion(Long institutionId);
|
||||||
|
|
||||||
|
/** Saves the Exam and updates the running exam cache. */
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(
|
@CacheEvict(
|
||||||
cacheNames = ExamSessionCacheService.CACHE_NAME_RUNNING_EXAM,
|
cacheNames = ExamSessionCacheService.CACHE_NAME_RUNNING_EXAM,
|
||||||
key = "#exam.id")
|
key = "#exam.id")
|
||||||
Result<Exam> save(Exam exam);
|
Result<Exam> save(Exam exam);
|
||||||
|
|
||||||
|
/** Get an Exam by a given ClientConnection id.
|
||||||
|
*
|
||||||
|
* @param connectionId
|
||||||
|
* @return a Result containing the Exam by a given ClientConnection id or refer to an error if happened */
|
||||||
Result<Exam> byClientConnection(Long connectionId);
|
Result<Exam> byClientConnection(Long connectionId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,9 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.Configuration
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationNodeRecordDynamicSqlSupport;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationNodeRecordMapper;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationNodeRecordMapper;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationRecordDynamicSqlSupport;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamConfigurationMapRecordDynamicSqlSupport;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamConfigurationMapRecordDynamicSqlSupport;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamConfigurationMapRecordMapper;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamConfigurationMapRecordMapper;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordDynamicSqlSupport;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordDynamicSqlSupport;
|
||||||
|
@ -285,6 +287,35 @@ public class ExamConfigurationMapDAOImpl implements ExamConfigurationMapDAO {
|
||||||
return getDependencies(bulkAction, selectionFunction);
|
return getDependencies(bulkAction, selectionFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Result<Collection<Long>> getExamIdsForConfigId(final Long configurationId) {
|
||||||
|
return Result.tryCatch(() -> {
|
||||||
|
final Long configNodeId = this.configurationNodeRecordMapper.selectIdsByExample()
|
||||||
|
.leftJoin(ConfigurationRecordDynamicSqlSupport.configurationRecord)
|
||||||
|
.on(
|
||||||
|
ConfigurationRecordDynamicSqlSupport.configurationNodeId,
|
||||||
|
equalTo(ConfigurationNodeRecordDynamicSqlSupport.id))
|
||||||
|
.where(
|
||||||
|
ConfigurationRecordDynamicSqlSupport.id,
|
||||||
|
isEqualTo(configurationId))
|
||||||
|
.build()
|
||||||
|
.execute()
|
||||||
|
.stream()
|
||||||
|
.collect(Utils.toSingleton());
|
||||||
|
|
||||||
|
return this.examConfigurationMapRecordMapper.selectByExample()
|
||||||
|
.where(
|
||||||
|
ExamConfigurationMapRecordDynamicSqlSupport.configurationNodeId,
|
||||||
|
isEqualTo(configNodeId))
|
||||||
|
.build()
|
||||||
|
.execute()
|
||||||
|
.stream()
|
||||||
|
.map(record -> record.getExamId())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private Result<ExamConfigurationMapRecord> recordById(final Long id) {
|
private Result<ExamConfigurationMapRecord> recordById(final Long id) {
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
final ExamConfigurationMapRecord record = this.examConfigurationMapRecordMapper
|
final ExamConfigurationMapRecord record = this.examConfigurationMapRecordMapper
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig;
|
||||||
|
|
||||||
|
public class ConfigurationChangedEvent {
|
||||||
|
|
||||||
|
public final Long configurationId;
|
||||||
|
|
||||||
|
public ConfigurationChangedEvent(final Long configurationId) {
|
||||||
|
this.configurationId = configurationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,11 +12,14 @@ import java.io.OutputStream;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConfigurationChangedEvent;
|
||||||
|
|
||||||
/** A Service to handle running exam sessions */
|
/** A Service to handle running exam sessions */
|
||||||
public interface ExamSessionService {
|
public interface ExamSessionService {
|
||||||
|
@ -84,4 +87,7 @@ public interface ExamSessionService {
|
||||||
* of a running exam */
|
* of a running exam */
|
||||||
Result<Collection<ClientConnectionData>> getConnectionData(Long examId);
|
Result<Collection<ClientConnectionData>> getConnectionData(Long examId);
|
||||||
|
|
||||||
|
@EventListener(ConfigurationChangedEvent.class)
|
||||||
|
void updateExamConfigCache(ConfigurationChangedEvent configChanged);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@ -30,8 +31,10 @@ import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientConnectionDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientConnectionDAO;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamConfigurationMapDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConfigurationChangedEvent;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
@ -44,16 +47,19 @@ public class ExamSessionServiceImpl implements ExamSessionService {
|
||||||
private final ClientConnectionDAO clientConnectionDAO;
|
private final ClientConnectionDAO clientConnectionDAO;
|
||||||
private final ExamSessionCacheService examSessionCacheService;
|
private final ExamSessionCacheService examSessionCacheService;
|
||||||
private final ExamDAO examDAO;
|
private final ExamDAO examDAO;
|
||||||
|
private final ExamConfigurationMapDAO examConfigurationMapDAO;
|
||||||
private final CacheManager cacheManager;
|
private final CacheManager cacheManager;
|
||||||
|
|
||||||
protected ExamSessionServiceImpl(
|
protected ExamSessionServiceImpl(
|
||||||
final ExamSessionCacheService examSessionCacheService,
|
final ExamSessionCacheService examSessionCacheService,
|
||||||
final ExamDAO examDAO,
|
final ExamDAO examDAO,
|
||||||
|
final ExamConfigurationMapDAO examConfigurationMapDAO,
|
||||||
final ClientConnectionDAO clientConnectionDAO,
|
final ClientConnectionDAO clientConnectionDAO,
|
||||||
final CacheManager cacheManager) {
|
final CacheManager cacheManager) {
|
||||||
|
|
||||||
this.examSessionCacheService = examSessionCacheService;
|
this.examSessionCacheService = examSessionCacheService;
|
||||||
this.examDAO = examDAO;
|
this.examDAO = examDAO;
|
||||||
|
this.examConfigurationMapDAO = examConfigurationMapDAO;
|
||||||
this.clientConnectionDAO = clientConnectionDAO;
|
this.clientConnectionDAO = clientConnectionDAO;
|
||||||
this.cacheManager = cacheManager;
|
this.cacheManager = cacheManager;
|
||||||
}
|
}
|
||||||
|
@ -191,6 +197,20 @@ public class ExamSessionServiceImpl implements ExamSessionService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@EventListener(ConfigurationChangedEvent.class)
|
||||||
|
public void updateExamConfigCache(final ConfigurationChangedEvent configChanged) {
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Flush exam config cache for configuration: {}", configChanged.configurationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.examConfigurationMapDAO
|
||||||
|
.getExamIdsForConfigId(configChanged.configurationId)
|
||||||
|
.getOrElse(() -> Collections.emptyList())
|
||||||
|
.forEach(this.examSessionCacheService::evictDefaultSebConfig);
|
||||||
|
}
|
||||||
|
|
||||||
private void flushCache(final Exam exam) {
|
private void flushCache(final Exam exam) {
|
||||||
try {
|
try {
|
||||||
this.examSessionCacheService.evict(exam);
|
this.examSessionCacheService.evict(exam);
|
||||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.mybatis.dynamic.sql.SqlTable;
|
import org.mybatis.dynamic.sql.SqlTable;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
@ -23,12 +24,14 @@ import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationRecordDynamicSqlSupport;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationRecordDynamicSqlSupport;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConfigurationChangedEvent;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
||||||
|
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
|
@ -37,6 +40,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe
|
||||||
public class ConfigurationController extends ReadonlyEntityController<Configuration, Configuration> {
|
public class ConfigurationController extends ReadonlyEntityController<Configuration, Configuration> {
|
||||||
|
|
||||||
private final ConfigurationDAO configurationDAO;
|
private final ConfigurationDAO configurationDAO;
|
||||||
|
private final ApplicationEventPublisher applicationEventPublisher;
|
||||||
|
|
||||||
protected ConfigurationController(
|
protected ConfigurationController(
|
||||||
final AuthorizationService authorization,
|
final AuthorizationService authorization,
|
||||||
|
@ -44,7 +48,8 @@ public class ConfigurationController extends ReadonlyEntityController<Configurat
|
||||||
final ConfigurationDAO entityDAO,
|
final ConfigurationDAO entityDAO,
|
||||||
final UserActivityLogDAO userActivityLogDAO,
|
final UserActivityLogDAO userActivityLogDAO,
|
||||||
final PaginationService paginationService,
|
final PaginationService paginationService,
|
||||||
final BeanValidationService beanValidationService) {
|
final BeanValidationService beanValidationService,
|
||||||
|
final ApplicationEventPublisher applicationEventPublisher) {
|
||||||
|
|
||||||
super(authorization,
|
super(authorization,
|
||||||
bulkActionService,
|
bulkActionService,
|
||||||
|
@ -54,6 +59,7 @@ public class ConfigurationController extends ReadonlyEntityController<Configurat
|
||||||
beanValidationService);
|
beanValidationService);
|
||||||
|
|
||||||
this.configurationDAO = entityDAO;
|
this.configurationDAO = entityDAO;
|
||||||
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
|
@ -67,6 +73,7 @@ public class ConfigurationController extends ReadonlyEntityController<Configurat
|
||||||
.flatMap(this.authorization::checkModify)
|
.flatMap(this.authorization::checkModify)
|
||||||
.flatMap(config -> this.configurationDAO.saveToHistory(config.configurationNodeId))
|
.flatMap(config -> this.configurationDAO.saveToHistory(config.configurationNodeId))
|
||||||
.flatMap(this.userActivityLogDAO::logSaveToHistory)
|
.flatMap(this.userActivityLogDAO::logSaveToHistory)
|
||||||
|
.flatMap(this::publishConfigChanged)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +88,7 @@ public class ConfigurationController extends ReadonlyEntityController<Configurat
|
||||||
.flatMap(this.authorization::checkModify)
|
.flatMap(this.authorization::checkModify)
|
||||||
.flatMap(config -> this.configurationDAO.undo(config.configurationNodeId))
|
.flatMap(config -> this.configurationDAO.undo(config.configurationNodeId))
|
||||||
.flatMap(this.userActivityLogDAO::logUndo)
|
.flatMap(this.userActivityLogDAO::logUndo)
|
||||||
|
.flatMap(this::publishConfigChanged)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +104,7 @@ public class ConfigurationController extends ReadonlyEntityController<Configurat
|
||||||
return this.entityDAO.byModelId(modelId)
|
return this.entityDAO.byModelId(modelId)
|
||||||
.flatMap(this.authorization::checkModify)
|
.flatMap(this.authorization::checkModify)
|
||||||
.flatMap(config -> this.configurationDAO.restoreToVersion(configurationNodeId, config.getId()))
|
.flatMap(config -> this.configurationDAO.restoreToVersion(configurationNodeId, config.getId()))
|
||||||
|
.flatMap(this::publishConfigChanged)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,4 +118,9 @@ public class ConfigurationController extends ReadonlyEntityController<Configurat
|
||||||
return ConfigurationRecordDynamicSqlSupport.configurationRecord;
|
return ConfigurationRecordDynamicSqlSupport.configurationRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Result<Configuration> publishConfigChanged(final Configuration config) {
|
||||||
|
this.applicationEventPublisher.publishEvent(new ConfigurationChangedEvent(config.id));
|
||||||
|
return Result.of(config);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Objects;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
import org.mybatis.dynamic.sql.SqlTable;
|
import org.mybatis.dynamic.sql.SqlTable;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
@ -35,6 +36,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionServic
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConfigurationChangedEvent;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
||||||
|
|
||||||
|
@ -46,6 +48,7 @@ public class ConfigurationValueController extends EntityController<Configuration
|
||||||
private final ConfigurationDAO configurationDAO;
|
private final ConfigurationDAO configurationDAO;
|
||||||
private final ConfigurationValueDAO configurationValueDAO;
|
private final ConfigurationValueDAO configurationValueDAO;
|
||||||
private final SebExamConfigService sebExamConfigService;
|
private final SebExamConfigService sebExamConfigService;
|
||||||
|
private final ApplicationEventPublisher applicationEventPublisher;
|
||||||
|
|
||||||
protected ConfigurationValueController(
|
protected ConfigurationValueController(
|
||||||
final AuthorizationService authorization,
|
final AuthorizationService authorization,
|
||||||
|
@ -55,7 +58,8 @@ public class ConfigurationValueController extends EntityController<Configuration
|
||||||
final PaginationService paginationService,
|
final PaginationService paginationService,
|
||||||
final BeanValidationService beanValidationService,
|
final BeanValidationService beanValidationService,
|
||||||
final ConfigurationDAO configurationDAO,
|
final ConfigurationDAO configurationDAO,
|
||||||
final SebExamConfigService sebExamConfigService) {
|
final SebExamConfigService sebExamConfigService,
|
||||||
|
final ApplicationEventPublisher applicationEventPublisher) {
|
||||||
|
|
||||||
super(authorization,
|
super(authorization,
|
||||||
bulkActionService,
|
bulkActionService,
|
||||||
|
@ -67,6 +71,19 @@ public class ConfigurationValueController extends EntityController<Configuration
|
||||||
this.configurationDAO = configurationDAO;
|
this.configurationDAO = configurationDAO;
|
||||||
this.configurationValueDAO = entityDAO;
|
this.configurationValueDAO = entityDAO;
|
||||||
this.sebExamConfigService = sebExamConfigService;
|
this.sebExamConfigService = sebExamConfigService;
|
||||||
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<ConfigurationValue> notifySaved(final ConfigurationValue entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return super.notifySaved(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.applicationEventPublisher.publishEvent(
|
||||||
|
new ConfigurationChangedEvent(entity.configurationId));
|
||||||
|
|
||||||
|
return super.notifySaved(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -124,6 +141,11 @@ public class ConfigurationValueController extends EntityController<Configuration
|
||||||
return this.configurationDAO.byPK(tableValue.configurationId)
|
return this.configurationDAO.byPK(tableValue.configurationId)
|
||||||
.flatMap(this.authorization::checkModify)
|
.flatMap(this.authorization::checkModify)
|
||||||
.flatMap(config -> this.configurationValueDAO.saveTableValues(tableValue))
|
.flatMap(config -> this.configurationValueDAO.saveTableValues(tableValue))
|
||||||
|
.map(config -> {
|
||||||
|
this.applicationEventPublisher.publishEvent(
|
||||||
|
new ConfigurationChangedEvent(config.configurationId));
|
||||||
|
return config;
|
||||||
|
})
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class HTTPClientBot {
|
||||||
this.apiVersion = args.getOrDefault("apiVersion", "v1");
|
this.apiVersion = args.getOrDefault("apiVersion", "v1");
|
||||||
this.examId = args.getOrDefault("examId", "2");
|
this.examId = args.getOrDefault("examId", "2");
|
||||||
this.institutionId = args.getOrDefault("institutionId", "1");
|
this.institutionId = args.getOrDefault("institutionId", "1");
|
||||||
this.numberOfConnections = Integer.parseInt(args.getOrDefault("numberOfConnections", "4"));
|
this.numberOfConnections = Integer.parseInt(args.getOrDefault("numberOfConnections", "1"));
|
||||||
this.pingInterval = Long.parseLong(args.getOrDefault("pingInterval", "200"));
|
this.pingInterval = Long.parseLong(args.getOrDefault("pingInterval", "200"));
|
||||||
this.errorInterval = Long.parseLong(args.getOrDefault("errorInterval", String.valueOf(TEN_SECONDS)));
|
this.errorInterval = Long.parseLong(args.getOrDefault("errorInterval", String.valueOf(TEN_SECONDS)));
|
||||||
this.runtime = Long.parseLong(args.getOrDefault("runtime", String.valueOf(ONE_MINUTE)));
|
this.runtime = Long.parseLong(args.getOrDefault("runtime", String.valueOf(ONE_MINUTE)));
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<Logger name="org.eth.demo.sebserver" level="TRACE" additivity="true" />
|
<Logger name="ch.ethz.seb.sebserver.HTTPClientBot" level="TRACE" additivity="true" />
|
||||||
|
|
||||||
<root level="INFO" additivity="true">
|
<root level="INFO" additivity="true">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
|
|
Loading…
Add table
Reference in a new issue