SEBSERV-266
This commit is contained in:
parent
a732b0c871
commit
8355e93d36
6 changed files with 100 additions and 32 deletions
|
@ -9,12 +9,15 @@
|
||||||
package ch.ethz.seb.sebserver.webservice;
|
package ch.ethz.seb.sebserver.webservice;
|
||||||
|
|
||||||
import org.flywaydb.core.Flyway;
|
import org.flywaydb.core.Flyway;
|
||||||
|
import org.flywaydb.core.api.MigrationInfo;
|
||||||
|
import org.flywaydb.core.api.MigrationInfoService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
|
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.SEBServerInit;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.WebserviceInfoDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.WebserviceInfoDAO;
|
||||||
|
|
||||||
|
@ -27,6 +30,8 @@ public class SEBServerMigrationStrategy implements FlywayMigrationStrategy {
|
||||||
private final boolean cleanDBOnStartup;
|
private final boolean cleanDBOnStartup;
|
||||||
private final WebserviceInfo webserviceInfo;
|
private final WebserviceInfo webserviceInfo;
|
||||||
private final WebserviceInfoDAO webserviceInfoDAO;
|
private final WebserviceInfoDAO webserviceInfoDAO;
|
||||||
|
private Flyway flyway;
|
||||||
|
private final boolean migrationApplied = false;
|
||||||
|
|
||||||
public SEBServerMigrationStrategy(
|
public SEBServerMigrationStrategy(
|
||||||
final WebserviceInfo webserviceInfo,
|
final WebserviceInfo webserviceInfo,
|
||||||
|
@ -40,31 +45,83 @@ public class SEBServerMigrationStrategy implements FlywayMigrationStrategy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void migrate(final Flyway flyway) {
|
public void migrate(final Flyway flyway) {
|
||||||
|
this.flyway = flyway;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyMigration() {
|
||||||
|
final String webserviceUUID = this.webserviceInfo.getWebserviceUUID();
|
||||||
|
if (this.migrationApplied) {
|
||||||
|
log.warn("Migration already applied for this webservice: {}", webserviceUUID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> ** Migration check START **");
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> Check database status");
|
||||||
|
|
||||||
|
final MigrationInfoService info = this.flyway.info();
|
||||||
|
if (SEBServerInit.INIT_LOGGER.isDebugEnabled()) {
|
||||||
|
SEBServerInit.INIT_LOGGER.debug("----> ** Migration Info **");
|
||||||
|
SEBServerInit.INIT_LOGGER.debug("----> {}", info);
|
||||||
|
}
|
||||||
|
|
||||||
|
final MigrationInfo[] pendingMigrations = info.pending();
|
||||||
|
if (pendingMigrations != null && pendingMigrations.length > 0) {
|
||||||
|
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> Found pending migrations: {}", pendingMigrations.length);
|
||||||
// If we are in a distributed setup only apply migration task if this is the master service
|
// If we are in a distributed setup only apply migration task if this is the master service
|
||||||
// or if there was no data base initialization yet at all.
|
// or if there was no data base initialization yet at all.
|
||||||
if (this.webserviceInfo.isDistributed()) {
|
if (this.webserviceInfo.isDistributed()) {
|
||||||
|
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> This is distributed setup, check master...");
|
||||||
|
|
||||||
if (this.webserviceInfoDAO.isInitialized()) {
|
if (this.webserviceInfoDAO.isInitialized()) {
|
||||||
final boolean isMaster = this.webserviceInfoDAO.isMaster(this.webserviceInfo.getWebserviceUUID());
|
final boolean isMaster = this.webserviceInfoDAO.isMaster(webserviceUUID);
|
||||||
if (!isMaster) {
|
if (!isMaster) {
|
||||||
log.info(
|
SEBServerInit.INIT_LOGGER.info(
|
||||||
"Skip migration task since this is not a master instance: {}",
|
"----> Skip migration task since this is not a master instance: {}",
|
||||||
this.webserviceInfo.getWebserviceUUID());
|
this.webserviceInfo.getWebserviceUUID());
|
||||||
|
} else {
|
||||||
return;
|
doMigration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
doMigration();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.cleanDBOnStartup) {
|
} else {
|
||||||
flyway.clean();
|
SEBServerInit.INIT_LOGGER.info("----> ");
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> No pending migrations found. Last migration --> {} --> {}",
|
||||||
|
info.current().getVersion(),
|
||||||
|
info.current().getDescription());
|
||||||
}
|
}
|
||||||
flyway.migrate();
|
|
||||||
|
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> ** Migration check END **");
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.error("Failed to apply migration task: ", e);
|
log.error("Failed to apply migration task: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doMigration() {
|
||||||
|
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> *** Start migration ***");
|
||||||
|
|
||||||
|
if (this.cleanDBOnStartup) {
|
||||||
|
|
||||||
|
SEBServerInit.INIT_LOGGER
|
||||||
|
.info("----> !!! Cleanup database as it was set on sebserver.webservice.clean-db-on-startup !!!");
|
||||||
|
|
||||||
|
this.flyway.clean();
|
||||||
|
}
|
||||||
|
this.flyway.migrate();
|
||||||
|
|
||||||
|
final MigrationInfoService info = this.flyway.info();
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> Migration finished, new current version is: {} --> {}",
|
||||||
|
info.current().getVersion(),
|
||||||
|
info.current().getDescription());
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> *** End migration ***");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent
|
||||||
private final ApplicationEventPublisher applicationEventPublisher;
|
private final ApplicationEventPublisher applicationEventPublisher;
|
||||||
private final WebserviceInfoDAO webserviceInfoDAO;
|
private final WebserviceInfoDAO webserviceInfoDAO;
|
||||||
private final DBIntegrityChecker dbIntegrityChecker;
|
private final DBIntegrityChecker dbIntegrityChecker;
|
||||||
|
private final SEBServerMigrationStrategy sebServerMigrationStrategy;
|
||||||
|
|
||||||
protected WebserviceInit(
|
protected WebserviceInit(
|
||||||
final SEBServerInit sebServerInit,
|
final SEBServerInit sebServerInit,
|
||||||
|
@ -48,7 +49,8 @@ public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent
|
||||||
final ApplicationEventPublisher applicationEventPublisher,
|
final ApplicationEventPublisher applicationEventPublisher,
|
||||||
final WebserviceInfoDAO webserviceInfoDAO,
|
final WebserviceInfoDAO webserviceInfoDAO,
|
||||||
final DBIntegrityChecker dbIntegrityChecker,
|
final DBIntegrityChecker dbIntegrityChecker,
|
||||||
final ApplicationContext applicationContext) {
|
final ApplicationContext applicationContext,
|
||||||
|
final SEBServerMigrationStrategy sebServerMigrationStrategy) {
|
||||||
|
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
this.sebServerInit = sebServerInit;
|
this.sebServerInit = sebServerInit;
|
||||||
|
@ -58,7 +60,7 @@ public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent
|
||||||
this.applicationEventPublisher = applicationEventPublisher;
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
this.webserviceInfoDAO = webserviceInfoDAO;
|
this.webserviceInfoDAO = webserviceInfoDAO;
|
||||||
this.dbIntegrityChecker = dbIntegrityChecker;
|
this.dbIntegrityChecker = dbIntegrityChecker;
|
||||||
|
this.sebServerMigrationStrategy = sebServerMigrationStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApplicationContext getApplicationContext() {
|
public ApplicationContext getApplicationContext() {
|
||||||
|
@ -87,6 +89,11 @@ public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent
|
||||||
SEBServerInit.INIT_LOGGER.error("----> Failed to register webservice: ", e);
|
SEBServerInit.INIT_LOGGER.error("----> Failed to register webservice: ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply migration if needed and possible
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> ");
|
||||||
|
this.sebServerMigrationStrategy.applyMigration();
|
||||||
|
SEBServerInit.INIT_LOGGER.info("----> ");
|
||||||
|
|
||||||
SEBServerInit.INIT_LOGGER.info("----> ");
|
SEBServerInit.INIT_LOGGER.info("----> ");
|
||||||
SEBServerInit.INIT_LOGGER.info("----> Initialize Services...");
|
SEBServerInit.INIT_LOGGER.info("----> Initialize Services...");
|
||||||
SEBServerInit.INIT_LOGGER.info("----> ");
|
SEBServerInit.INIT_LOGGER.info("----> ");
|
||||||
|
|
|
@ -119,8 +119,7 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO {
|
||||||
final long now = Utils.getMillisecondsNow();
|
final long now = Utils.getMillisecondsNow();
|
||||||
final long lastUpdateSince = now - masterRec.getUpdateTime();
|
final long lastUpdateSince = now - masterRec.getUpdateTime();
|
||||||
if (lastUpdateSince > this.masterDelayTimeThreshold || this.forceMaster) {
|
if (lastUpdateSince > this.masterDelayTimeThreshold || this.forceMaster) {
|
||||||
forceMaster(uuid, masterRec.getUuid(), masterRec.getId());
|
return forceMaster(uuid, masterRec.getUuid(), masterRec.getId());
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -136,13 +135,14 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void forceMaster(final String uuid, final String otherUUID, final Long otherId) {
|
private boolean forceMaster(final String uuid, final String otherUUID, final Long otherId) {
|
||||||
|
|
||||||
log.info("Change webservice master form uuid: {} to uuid: {}", otherUUID, uuid);
|
log.info("Change webservice master from uuid: {} to uuid: {}", otherUUID, uuid);
|
||||||
|
|
||||||
this.webserviceServerInfoRecordMapper.updateByPrimaryKeySelective(
|
this.webserviceServerInfoRecordMapper.updateByPrimaryKeySelective(
|
||||||
new WebserviceServerInfoRecord(otherId, null, null, 0, 0L));
|
new WebserviceServerInfoRecord(otherId, null, null, 0, 0L));
|
||||||
setMasterTo(uuid);
|
|
||||||
|
return setMasterTo(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setMasterTo(final String uuid) {
|
private boolean setMasterTo(final String uuid) {
|
||||||
|
@ -156,9 +156,7 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO {
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
if (entries == null || entries.isEmpty()) {
|
if (entries == null || entries.isEmpty()) {
|
||||||
if (log.isDebugEnabled()) {
|
log.warn("The webservice with uuid: {} is not registered and cannot become a master", uuid);
|
||||||
log.debug("The webservice with uuid: {} is not registered and cannot become a master", uuid);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,10 +88,11 @@ class ExamSessionControlTask implements DisposableBean {
|
||||||
SEBServerInit.INIT_LOGGER.info(
|
SEBServerInit.INIT_LOGGER.info(
|
||||||
"------> Activate SEB lost-ping-event update background task on a fix rate of: {} milliseconds",
|
"------> Activate SEB lost-ping-event update background task on a fix rate of: {} milliseconds",
|
||||||
this.pingUpdateRate);
|
this.pingUpdateRate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "${sebserver.webservice.api.exam.update-interval:1 * * * * *}")
|
@Scheduled(
|
||||||
|
fixedDelayString = "${sebserver.webservice.api.exam.update-interval:60000}",
|
||||||
|
initialDelay = 30000)
|
||||||
public void examRunUpdateTask() {
|
public void examRunUpdateTask() {
|
||||||
|
|
||||||
if (!this.webserviceInfoDAO.isMaster(this.webserviceInfo.getWebserviceUUID())) {
|
if (!this.webserviceInfoDAO.isMaster(this.webserviceInfo.getWebserviceUUID())) {
|
||||||
|
@ -109,7 +110,9 @@ class ExamSessionControlTask implements DisposableBean {
|
||||||
this.examDAO.releaseAgedLocks();
|
this.examDAO.releaseAgedLocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(fixedDelayString = "${sebserver.webservice.api.seb.lostping.update:5000}")
|
@Scheduled(
|
||||||
|
fixedDelayString = "${sebserver.webservice.api.seb.lostping.update:5000}",
|
||||||
|
initialDelay = 30000)
|
||||||
public void examSessionUpdateTask() {
|
public void examSessionUpdateTask() {
|
||||||
|
|
||||||
this.sebClientConnectionService.updatePingEvents();
|
this.sebClientConnectionService.updatePingEvents();
|
||||||
|
@ -122,7 +125,9 @@ class ExamSessionControlTask implements DisposableBean {
|
||||||
this.examProcotringRoomService.updateProctoringCollectingRooms();
|
this.examProcotringRoomService.updateProctoringCollectingRooms();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(fixedRateString = "${sebserver.webservice.api.exam.session-cleanup:30000}")
|
@Scheduled(
|
||||||
|
fixedRateString = "${sebserver.webservice.api.exam.session-cleanup:30000}",
|
||||||
|
initialDelay = 30000)
|
||||||
public void examSessionCleanupTask() {
|
public void examSessionCleanupTask() {
|
||||||
|
|
||||||
if (!this.webserviceInfoDAO.isMaster(this.webserviceInfo.getWebserviceUUID())) {
|
if (!this.webserviceInfoDAO.isMaster(this.webserviceInfo.getWebserviceUUID())) {
|
||||||
|
|
|
@ -25,8 +25,8 @@ sebserver.webservice.clean-db-on-startup=false
|
||||||
|
|
||||||
# webservice configuration
|
# webservice configuration
|
||||||
sebserver.init.adminaccount.gen-on-init=false
|
sebserver.init.adminaccount.gen-on-init=false
|
||||||
sebserver.webservice.distributed=true
|
sebserver.webservice.distributed=false
|
||||||
sebserver.webservice.master.delay.threshold=10000
|
#sebserver.webservice.master.delay.threshold=10000
|
||||||
sebserver.webservice.http.external.scheme=http
|
sebserver.webservice.http.external.scheme=http
|
||||||
sebserver.webservice.http.external.servername=localhost
|
sebserver.webservice.http.external.servername=localhost
|
||||||
sebserver.webservice.http.external.port=${server.port}
|
sebserver.webservice.http.external.port=${server.port}
|
||||||
|
|
|
@ -7,6 +7,7 @@ server.port=8080
|
||||||
server.servlet.context-path=/
|
server.servlet.context-path=/
|
||||||
server.tomcat.uri-encoding=UTF-8
|
server.tomcat.uri-encoding=UTF-8
|
||||||
|
|
||||||
|
logging.level.ROOT=INFO
|
||||||
logging.level.ch=INFO
|
logging.level.ch=INFO
|
||||||
logging.level.ch.ethz.seb.sebserver.webservice.datalayer=INFO
|
logging.level.ch.ethz.seb.sebserver.webservice.datalayer=INFO
|
||||||
logging.level.org.springframework.cache=INFO
|
logging.level.org.springframework.cache=INFO
|
||||||
|
@ -19,7 +20,7 @@ logging.level.ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicat
|
||||||
#logging.level.ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper=DEBUG
|
#logging.level.ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper=DEBUG
|
||||||
#logging.level.ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordMapper=DEBUG
|
#logging.level.ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordMapper=DEBUG
|
||||||
#logging.level.ch.ethz.seb.sebserver.webservice.weblayer.api.ExamAPI_V1_Controller=TRACE
|
#logging.level.ch.ethz.seb.sebserver.webservice.weblayer.api.ExamAPI_V1_Controller=TRACE
|
||||||
logging.level.com.zaxxer.hikari=DEBUG
|
logging.level.com.zaxxer.hikari=INFO
|
||||||
|
|
||||||
sebserver.http.client.connect-timeout=15000
|
sebserver.http.client.connect-timeout=15000
|
||||||
sebserver.http.client.connection-request-timeout=10000
|
sebserver.http.client.connection-request-timeout=10000
|
||||||
|
|
Loading…
Add table
Reference in a new issue