143 lines
6 KiB
Java
143 lines
6 KiB
Java
/*
|
|
* Copyright (c) 2021 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;
|
|
|
|
import org.flywaydb.core.Flyway;
|
|
import org.flywaydb.core.api.MigrationInfo;
|
|
import org.flywaydb.core.api.MigrationInfoService;
|
|
import org.flywaydb.core.api.output.ValidateResult;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import ch.ethz.seb.sebserver.SEBServerInit;
|
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.WebserviceInfoDAO;
|
|
|
|
@Component
|
|
@WebServiceProfile
|
|
public class SEBServerMigrationStrategy implements FlywayMigrationStrategy {
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(SEBServerMigrationStrategy.class);
|
|
|
|
private final boolean cleanDBOnStartup;
|
|
private final WebserviceInfo webserviceInfo;
|
|
private final WebserviceInfoDAO webserviceInfoDAO;
|
|
private Flyway flyway;
|
|
|
|
public SEBServerMigrationStrategy(
|
|
final WebserviceInfo webserviceInfo,
|
|
final WebserviceInfoDAO webserviceInfoDAO,
|
|
@Value("${sebserver.webservice.clean-db-on-startup:false}") final boolean cleanDBOnStartup) {
|
|
|
|
this.webserviceInfo = webserviceInfo;
|
|
this.webserviceInfoDAO = webserviceInfoDAO;
|
|
this.cleanDBOnStartup = cleanDBOnStartup;
|
|
}
|
|
|
|
@Override
|
|
public void migrate(final Flyway flyway) {
|
|
this.flyway = flyway;
|
|
}
|
|
|
|
public void applyMigration() {
|
|
if (this.webserviceInfo.hasProfile("test")) {
|
|
SEBServerInit.INIT_LOGGER.info("No migration applies for test profile");
|
|
return;
|
|
}
|
|
|
|
final String webserviceUUID = this.webserviceInfo.getWebserviceUUID();
|
|
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
|
|
// or if there was no data base initialization yet at all.
|
|
if (this.webserviceInfo.isDistributed() && this.webserviceInfoDAO.isInitialized()) {
|
|
|
|
SEBServerInit.INIT_LOGGER.info("----> This is distributed setup, check master...");
|
|
|
|
if (this.webserviceInfoDAO.isInitialized()) {
|
|
final boolean isMaster = this.webserviceInfoDAO.isMaster(webserviceUUID);
|
|
if (!isMaster) {
|
|
SEBServerInit.INIT_LOGGER.info(
|
|
"----> Skip migration task since this is not a master instance: {}",
|
|
this.webserviceInfo.getWebserviceUUID());
|
|
} else {
|
|
doMigration();
|
|
}
|
|
}
|
|
} else {
|
|
doMigration();
|
|
}
|
|
|
|
} else {
|
|
SEBServerInit.INIT_LOGGER.info("----> ");
|
|
SEBServerInit.INIT_LOGGER.info("----> No pending migrations found. Last migration --> {} --> {}",
|
|
info.current().getVersion(),
|
|
info.current().getDescription());
|
|
}
|
|
|
|
SEBServerInit.INIT_LOGGER.info("----> ** Migration check END **");
|
|
} catch (final Exception e) {
|
|
log.error("Failed to apply migration task: ", e);
|
|
}
|
|
}
|
|
|
|
private void doMigration() {
|
|
|
|
SEBServerInit.INIT_LOGGER.info("----> *********************************************************");
|
|
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();
|
|
}
|
|
|
|
// repair checksum mismatch if needed
|
|
final ValidateResult validateWithResult = this.flyway.validateWithResult();
|
|
if (!validateWithResult.validationSuccessful
|
|
&& validateWithResult.getAllErrorMessages().contains("checksum mismatch")) {
|
|
|
|
SEBServerInit.INIT_LOGGER.info("----> Migration validation checksum mismatch error detected: ");
|
|
SEBServerInit.INIT_LOGGER.info("----> {}", validateWithResult.getAllErrorMessages());
|
|
SEBServerInit.INIT_LOGGER.info("----> Try to run repair task...");
|
|
|
|
this.flyway.repair();
|
|
|
|
}
|
|
|
|
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 **************************************");
|
|
SEBServerInit.INIT_LOGGER.info("----> *********************************************************");
|
|
}
|
|
|
|
}
|