fixes and server init
This commit is contained in:
parent
7ce1baafa5
commit
1da72a0f31
11 changed files with 168 additions and 79 deletions
|
@ -38,7 +38,7 @@ The SEB Server Setup repository contains predefined, docker-based installation d
|
||||||
Install SEB Server
|
Install SEB Server
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
For a complete guide to install SEB Server please go to `SEB Server Installation Guide <https://seb-server-setup.readthedocs.io/en/latest/#>`_
|
For a complete guide to install SEB Server please go to `SEB Server Installation Guide <https://seb-server-setup.readthedocs.io/en/latest/overview.html>`_
|
||||||
|
|
||||||
Getting started with SEB Server
|
Getting started with SEB Server
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
31
src/main/java/ch/ethz/seb/sebserver/gui/GuiInit.java
Normal file
31
src/main/java/ch/ethz/seb/sebserver/gui/GuiInit.java
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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.gui;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@GuiProfile
|
||||||
|
public class GuiInit implements ApplicationListener<ApplicationReadyEvent> {
|
||||||
|
|
||||||
|
static final Logger INIT_LOGGER = LoggerFactory.getLogger("SEB SERVER INIT");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(final ApplicationReadyEvent event) {
|
||||||
|
INIT_LOGGER.info("----> SEB Server GUI Component sucessfully initialized!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -51,7 +51,7 @@ class AdminUserInitializer {
|
||||||
@Qualifier(WebSecurityConfig.USER_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder passwordEncoder,
|
@Qualifier(WebSecurityConfig.USER_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder passwordEncoder,
|
||||||
@Value("${sebserver.init.adminaccount.gen-on-init:false}") final boolean initializeAdmin,
|
@Value("${sebserver.init.adminaccount.gen-on-init:false}") final boolean initializeAdmin,
|
||||||
@Value("${sebserver.init.adminaccount.username:seb-server-admin}") final String adminName,
|
@Value("${sebserver.init.adminaccount.username:seb-server-admin}") final String adminName,
|
||||||
@Value("${sebserver.init.organisation.name:ETHZ}") final String orgName) {
|
@Value("${sebserver.init.organisation.name:[SET_ORGANIZATION_NAME]}") final String orgName) {
|
||||||
|
|
||||||
this.userDAO = userDAO;
|
this.userDAO = userDAO;
|
||||||
this.institutionDAO = institutionDAO;
|
this.institutionDAO = institutionDAO;
|
||||||
|
@ -67,72 +67,78 @@ class AdminUserInitializer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Create initial admin account is switched on. Check database if exists...");
|
try {
|
||||||
final Result<SEBServerUser> byUsername = this.userDAO.sebServerUserByUsername(this.adminName);
|
|
||||||
if (byUsername.hasValue()) {
|
|
||||||
|
|
||||||
log.debug("Initial admin account already exists. Check if the password must be reset...");
|
log.debug("Create initial admin account is switched on. Check database if exists...");
|
||||||
|
final Result<SEBServerUser> byUsername = this.userDAO.sebServerUserByUsername(this.adminName);
|
||||||
|
if (byUsername.hasValue()) {
|
||||||
|
|
||||||
final SEBServerUser sebServerUser = byUsername.get();
|
log.debug("Initial admin account already exists. Check if the password must be reset...");
|
||||||
final String password = sebServerUser.getPassword();
|
|
||||||
if (this.passwordEncoder.matches("admin", password)) {
|
|
||||||
|
|
||||||
log.debug("Setting new generated password for already existing admin account");
|
final SEBServerUser sebServerUser = byUsername.get();
|
||||||
|
final String password = sebServerUser.getPassword();
|
||||||
|
if (this.passwordEncoder.matches("admin", password)) {
|
||||||
|
|
||||||
|
log.debug("Setting new generated password for already existing admin account");
|
||||||
|
final CharSequence generateAdminPassword = this.generateAdminPassword();
|
||||||
|
if (generateAdminPassword != null) {
|
||||||
|
this.userDAO.changePassword(
|
||||||
|
sebServerUser.getUserInfo().getModelId(),
|
||||||
|
generateAdminPassword);
|
||||||
|
this.writeAdminCredentials(this.adminName, generateAdminPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
final CharSequence generateAdminPassword = this.generateAdminPassword();
|
final CharSequence generateAdminPassword = this.generateAdminPassword();
|
||||||
if (generateAdminPassword != null) {
|
if (generateAdminPassword != null) {
|
||||||
this.userDAO.changePassword(
|
|
||||||
sebServerUser.getUserInfo().getModelId(),
|
|
||||||
generateAdminPassword);
|
|
||||||
this.writeAdminCredentials(this.adminName, generateAdminPassword);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final CharSequence generateAdminPassword = this.generateAdminPassword();
|
|
||||||
if (generateAdminPassword != null) {
|
|
||||||
|
|
||||||
Long institutionId = this.institutionDAO.allMatching(new FilterMap())
|
Long institutionId = this.institutionDAO.allMatching(new FilterMap())
|
||||||
.getOrElse(() -> Collections.emptyList())
|
.getOrElse(() -> Collections.emptyList())
|
||||||
.stream()
|
.stream()
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.filter(Institution::isActive)
|
.filter(Institution::isActive)
|
||||||
.map(Institution::getInstitutionId)
|
|
||||||
.orElseGet(() -> -1L);
|
|
||||||
|
|
||||||
if (institutionId < 0) {
|
|
||||||
|
|
||||||
log.debug("Create new initial institution");
|
|
||||||
institutionId = this.institutionDAO.createNew(new Institution(
|
|
||||||
null,
|
|
||||||
this.orgName,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
true))
|
|
||||||
.map(inst -> this.institutionDAO.setActive(inst, true).getOrThrow())
|
|
||||||
.map(Institution::getInstitutionId)
|
.map(Institution::getInstitutionId)
|
||||||
|
.orElseGet(() -> -1L);
|
||||||
|
|
||||||
|
if (institutionId < 0) {
|
||||||
|
|
||||||
|
log.debug("Create new initial institution");
|
||||||
|
institutionId = this.institutionDAO.createNew(new Institution(
|
||||||
|
null,
|
||||||
|
this.orgName,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true))
|
||||||
|
.map(inst -> this.institutionDAO.setActive(inst, true).getOrThrow())
|
||||||
|
.map(Institution::getInstitutionId)
|
||||||
|
.getOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.userDAO.createNew(new UserMod(
|
||||||
|
this.adminName,
|
||||||
|
institutionId,
|
||||||
|
this.adminName,
|
||||||
|
this.adminName,
|
||||||
|
generateAdminPassword,
|
||||||
|
generateAdminPassword,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
new HashSet<>(Arrays.asList(UserRole.SEB_SERVER_ADMIN.name()))))
|
||||||
|
.flatMap(account -> this.userDAO.setActive(account, true))
|
||||||
|
.map(account -> {
|
||||||
|
writeAdminCredentials(this.adminName, generateAdminPassword);
|
||||||
|
return account;
|
||||||
|
})
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.userDAO.createNew(new UserMod(
|
|
||||||
this.adminName,
|
|
||||||
institutionId,
|
|
||||||
this.adminName,
|
|
||||||
this.adminName,
|
|
||||||
generateAdminPassword,
|
|
||||||
generateAdminPassword,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
new HashSet<>(Arrays.asList(UserRole.SEB_SERVER_ADMIN.name()))))
|
|
||||||
.flatMap(account -> this.userDAO.setActive(account, true))
|
|
||||||
.map(account -> {
|
|
||||||
writeAdminCredentials(this.adminName, generateAdminPassword);
|
|
||||||
return account;
|
|
||||||
})
|
|
||||||
.getOrThrow();
|
|
||||||
}
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
WebserviceInit.INIT_LOGGER.error("---->");
|
||||||
|
WebserviceInit.INIT_LOGGER.error("----> SEB Server initial admin-account creation failed: ", e);
|
||||||
|
WebserviceInit.INIT_LOGGER.error("---->");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeAdminCredentials(final String name, final CharSequence pwd) {
|
private void writeAdminCredentials(final String name, final CharSequence pwd) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class WebserviceInfo {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(WebserviceInfo.class);
|
private static final Logger log = LoggerFactory.getLogger(WebserviceInfo.class);
|
||||||
|
|
||||||
|
private static final String VERSION_KEY = "sebserver.version";
|
||||||
private static final String WEB_SERVICE_TEST_PROPERTY = "sebserver.test.property";
|
private static final String WEB_SERVICE_TEST_PROPERTY = "sebserver.test.property";
|
||||||
private static final String WEB_SERVICE_SERVER_NAME_KEY = "sebserver.webservice.http.server.name";
|
private static final String WEB_SERVICE_SERVER_NAME_KEY = "sebserver.webservice.http.server.name";
|
||||||
private static final String WEB_SERVICE_HTTP_SCHEME_KEY = "sebserver.webservice.http.scheme";
|
private static final String WEB_SERVICE_HTTP_SCHEME_KEY = "sebserver.webservice.http.scheme";
|
||||||
|
@ -43,6 +44,7 @@ public class WebserviceInfo {
|
||||||
"sebserver.webservice.api.exam.endpoint.discovery";
|
"sebserver.webservice.api.exam.endpoint.discovery";
|
||||||
private static final String WEB_SERVICE_EXTERNAL_ADDRESS_ALIAS = "sebserver.webservice.lms.address.alias";
|
private static final String WEB_SERVICE_EXTERNAL_ADDRESS_ALIAS = "sebserver.webservice.lms.address.alias";
|
||||||
|
|
||||||
|
private final String sebServerVersion;
|
||||||
private final String testProperty;
|
private final String testProperty;
|
||||||
private final String httpScheme;
|
private final String httpScheme;
|
||||||
private final String hostAddress; // internal
|
private final String hostAddress; // internal
|
||||||
|
@ -57,6 +59,7 @@ public class WebserviceInfo {
|
||||||
private Map<String, String> externalAddressAlias;
|
private Map<String, String> externalAddressAlias;
|
||||||
|
|
||||||
public WebserviceInfo(final Environment environment) {
|
public WebserviceInfo(final Environment environment) {
|
||||||
|
this.sebServerVersion = environment.getRequiredProperty(VERSION_KEY);
|
||||||
this.testProperty = environment.getProperty(WEB_SERVICE_TEST_PROPERTY, "NOT_AVAILABLE");
|
this.testProperty = environment.getProperty(WEB_SERVICE_TEST_PROPERTY, "NOT_AVAILABLE");
|
||||||
this.httpScheme = environment.getRequiredProperty(WEB_SERVICE_HTTP_SCHEME_KEY);
|
this.httpScheme = environment.getRequiredProperty(WEB_SERVICE_HTTP_SCHEME_KEY);
|
||||||
this.hostAddress = environment.getRequiredProperty(WEB_SERVICE_HOST_ADDRESS_KEY);
|
this.hostAddress = environment.getRequiredProperty(WEB_SERVICE_HOST_ADDRESS_KEY);
|
||||||
|
@ -100,6 +103,10 @@ public class WebserviceInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSebServerVersion() {
|
||||||
|
return this.sebServerVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTestProperty() {
|
public String getTestProperty() {
|
||||||
return this.testProperty;
|
return this.testProperty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,21 +58,24 @@ public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent
|
||||||
INIT_LOGGER.info("---->");
|
INIT_LOGGER.info("---->");
|
||||||
INIT_LOGGER.info("----> SEB Server successfully started up!");
|
INIT_LOGGER.info("----> SEB Server successfully started up!");
|
||||||
INIT_LOGGER.info("---->");
|
INIT_LOGGER.info("---->");
|
||||||
|
INIT_LOGGER.info("----> Version: {}", this.webserviceInfo.getSebServerVersion());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
INIT_LOGGER.info("----> config server address: {}", this.environment.getProperty("server.address"));
|
INIT_LOGGER.info("----> Server address: {}", this.environment.getProperty("server.address"));
|
||||||
INIT_LOGGER.info("----> config server port: {}", this.environment.getProperty("server.port"));
|
INIT_LOGGER.info("----> Server port: {}", this.environment.getProperty("server.port"));
|
||||||
|
INIT_LOGGER.info("---->");
|
||||||
INIT_LOGGER.info("----> local host address: {}", InetAddress.getLocalHost().getHostAddress());
|
INIT_LOGGER.info("----> Local-Host address: {}", InetAddress.getLocalHost().getHostAddress());
|
||||||
INIT_LOGGER.info("----> local host name: {}", InetAddress.getLocalHost().getHostName());
|
INIT_LOGGER.info("----> Local-Host name: {}", InetAddress.getLocalHost().getHostName());
|
||||||
|
INIT_LOGGER.info("---->");
|
||||||
INIT_LOGGER.info("----> remote host address: {}", InetAddress.getLoopbackAddress().getHostAddress());
|
INIT_LOGGER.info("----> Remote-Host address: {}", InetAddress.getLoopbackAddress().getHostAddress());
|
||||||
INIT_LOGGER.info("----> remote host name: {}", InetAddress.getLoopbackAddress().getHostName());
|
INIT_LOGGER.info("----> Remote-Host name: {}", InetAddress.getLoopbackAddress().getHostName());
|
||||||
} catch (final UnknownHostException e) {
|
} catch (final UnknownHostException e) {
|
||||||
log.error("Unknown Host: ", e);
|
log.error("Unknown Host: ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_LOGGER.info("----> {}", this.webserviceInfo);
|
INIT_LOGGER.info("---->");
|
||||||
|
INIT_LOGGER.info("----> HTTP Scheme {}", this.webserviceInfo.getHttpScheme());
|
||||||
|
INIT_LOGGER.info("----> Property Override Test: {}", this.webserviceInfo.getTestProperty());
|
||||||
|
|
||||||
// TODO integration of Flyway for database initialization and migration: https://flywaydb.org
|
// TODO integration of Flyway for database initialization and migration: https://flywaydb.org
|
||||||
// see also https://flywaydb.org/getstarted/firststeps/api
|
// see also https://flywaydb.org/getstarted/firststeps/api
|
||||||
|
|
|
@ -96,6 +96,12 @@ public interface ExamDAO extends ActivatableEntityDAO<Exam, Exam>, BulkActionSup
|
||||||
* @return Result refer to the specified exam or to an error if happened */
|
* @return Result refer to the specified exam or to an error if happened */
|
||||||
Result<Long> forceUnlock(Long examId);
|
Result<Long> forceUnlock(Long examId);
|
||||||
|
|
||||||
|
/** Used to force unlock all locked exams for a specified updateId
|
||||||
|
*
|
||||||
|
* @param updateId the update identifier
|
||||||
|
* @return list of identifiers of unlocked exams */
|
||||||
|
Result<Collection<Long>> forceUnlockAll(String updateId);
|
||||||
|
|
||||||
/** Indicates if the exam with specified identifier has an internal write lock.
|
/** Indicates if the exam with specified identifier has an internal write lock.
|
||||||
*
|
*
|
||||||
* @param examId the exam identifier
|
* @param examId the exam identifier
|
||||||
|
|
|
@ -465,7 +465,9 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
public Result<Long> forceUnlock(final Long examId) {
|
public Result<Long> forceUnlock(final Long examId) {
|
||||||
|
|
||||||
log.info("forceUnlock for exam: {}", examId);
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("forceUnlock for exam: {}", examId);
|
||||||
|
}
|
||||||
|
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
final ExamRecord examRecord = new ExamRecord(
|
final ExamRecord examRecord = new ExamRecord(
|
||||||
|
@ -481,6 +483,30 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
|
public Result<Collection<Long>> forceUnlockAll(final String updateId) {
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("forceUnlock for updateId: {}", updateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.tryCatch(() -> {
|
||||||
|
final Collection<Long> result = this.examRecordMapper.selectIdsByExample()
|
||||||
|
.where(ExamRecordDynamicSqlSupport.lastupdate, isEqualTo(updateId))
|
||||||
|
.build()
|
||||||
|
.execute()
|
||||||
|
.stream()
|
||||||
|
.map(this::forceUnlock)
|
||||||
|
.flatMap(Result::skipOnError)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
})
|
||||||
|
.onError(TransactionHandler::rollback);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public Result<Boolean> isLocked(final Long examId) {
|
public Result<Boolean> isLocked(final Long examId) {
|
||||||
|
|
|
@ -293,8 +293,12 @@ public class UserDAOImpl implements UserDAO {
|
||||||
.build()
|
.build()
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
return ids.stream()
|
return this.userRecordMapper.selectByExample()
|
||||||
.map(id -> new EntityKey(id, EntityType.USER))
|
.where(UserRecordDynamicSqlSupport.id, isIn(ids))
|
||||||
|
.build()
|
||||||
|
.execute()
|
||||||
|
.stream()
|
||||||
|
.map(record -> new EntityKey(record.getUuid(), EntityType.USER))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
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.ExamConfigurationMapDAO;
|
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.TransactionHandler;
|
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamConfigUpdateService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamConfigUpdateService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
|
||||||
|
|
||||||
|
@ -150,7 +149,7 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
|
||||||
|
|
||||||
return examIdsFirstCheck;
|
return examIdsFirstCheck;
|
||||||
})
|
})
|
||||||
.onError(TransactionHandler::rollback);
|
.onError(t -> this.examDAO.forceUnlockAll(updateId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -180,7 +179,8 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
|
||||||
checkActiveClientConnections(exam);
|
checkActiveClientConnections(exam);
|
||||||
|
|
||||||
// lock the exam
|
// lock the exam
|
||||||
this.examDAO.placeLock(exam.id, updateId)
|
this.examDAO
|
||||||
|
.placeLock(exam.id, updateId)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
// check again if there are no new active client connections in the meantime
|
// check again if there are no new active client connections in the meantime
|
||||||
|
@ -188,7 +188,8 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
|
||||||
|
|
||||||
// apply the referenced change action. On error the change is rolled back and
|
// apply the referenced change action. On error the change is rolled back and
|
||||||
// this processing returns immediately with the error
|
// this processing returns immediately with the error
|
||||||
final T result = changeAction.apply(mapping)
|
final T result = changeAction
|
||||||
|
.apply(mapping)
|
||||||
.onError(t -> log.error("Fauled to save exam configuration: {}",
|
.onError(t -> log.error("Fauled to save exam configuration: {}",
|
||||||
mapping.configurationNodeId))
|
mapping.configurationNodeId))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
@ -205,11 +206,13 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
|
||||||
|
|
||||||
// flush the exam cache. If there was an error during flush, it is logged but this process goes on
|
// flush the exam cache. If there was an error during flush, it is logged but this process goes on
|
||||||
// and the saved changes are not rolled back
|
// and the saved changes are not rolled back
|
||||||
this.examSessionService.flushCache(exam)
|
this.examSessionService
|
||||||
|
.flushCache(exam)
|
||||||
.onError(t -> log.error("Failed to flush cache for exam: {}", exam));
|
.onError(t -> log.error("Failed to flush cache for exam: {}", exam));
|
||||||
|
|
||||||
// release the exam lock
|
// release the exam lock
|
||||||
this.examDAO.releaseLock(exam.id, updateId)
|
this.examDAO
|
||||||
|
.releaseLock(exam.id, updateId)
|
||||||
.onError(t -> log.error("Failed to release lock for exam: {}", exam));
|
.onError(t -> log.error("Failed to release lock for exam: {}", exam));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -238,7 +241,8 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
|
||||||
configurationId);
|
configurationId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Configuration config = this.configurationDAO.byPK(configurationId)
|
final Configuration config = this.configurationDAO
|
||||||
|
.byPK(configurationId)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final Collection<Long> involvedExams = this.examConfigurationMapDAO
|
final Collection<Long> involvedExams = this.examConfigurationMapDAO
|
||||||
|
@ -260,7 +264,8 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Result<Long>> forceReleaseUpdateLocks(final Collection<Long> examIds) {
|
public Collection<Result<Long>> forceReleaseUpdateLocks(final Collection<Long> examIds) {
|
||||||
return examIds.stream()
|
return examIds
|
||||||
|
.stream()
|
||||||
.map(this.examDAO::forceUnlock)
|
.map(this.examDAO::forceUnlock)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ sebserver.http.client.connection-request-timeout=10000
|
||||||
sebserver.http.client.read-timeout=10000
|
sebserver.http.client.read-timeout=10000
|
||||||
|
|
||||||
# webservice configuration
|
# webservice configuration
|
||||||
|
sebserver.init.adminaccount.gen-on-init=false
|
||||||
sebserver.webservice.distributed=false
|
sebserver.webservice.distributed=false
|
||||||
sebserver.webservice.http.scheme=http
|
sebserver.webservice.http.scheme=http
|
||||||
sebserver.webservice.http.server.name=${server.address}
|
sebserver.webservice.http.server.name=${server.address}
|
||||||
|
|
|
@ -79,8 +79,8 @@ public class HTTPClientBot {
|
||||||
|
|
||||||
public HTTPClientBot(final Map<String, String> args) {
|
public HTTPClientBot(final Map<String, String> args) {
|
||||||
|
|
||||||
this.webserviceAddress = args.getOrDefault("webserviceAddress", "http://ralph.ethz.ch:8080");
|
// this.webserviceAddress = args.getOrDefault("webserviceAddress", "http://ralph.ethz.ch:8080");
|
||||||
// this.webserviceAddress = args.getOrDefault("webserviceAddress", "http://localhost:8080");
|
this.webserviceAddress = args.getOrDefault("webserviceAddress", "http://localhost:8080");
|
||||||
//this.webserviceAddress = args.getOrDefault("webserviceAddress", "https://seb.test-swissmooc.ch");
|
//this.webserviceAddress = args.getOrDefault("webserviceAddress", "https://seb.test-swissmooc.ch");
|
||||||
|
|
||||||
this.accessTokenEndpoint = args.getOrDefault("accessTokenEndpoint", "/oauth/token");
|
this.accessTokenEndpoint = args.getOrDefault("accessTokenEndpoint", "/oauth/token");
|
||||||
|
|
Loading…
Reference in a new issue