SEBSERV-455

This commit is contained in:
anhefti 2024-03-07 10:28:47 +01:00
parent eebd8506c2
commit e821c22504
7 changed files with 160 additions and 380 deletions

View file

@ -60,11 +60,16 @@ public class DBIntegrityChecker {
final Result<String> applyCheck = dbIntegrityCheck.applyCheck(this.tryFix);
if (applyCheck.hasError()) {
if (applyCheck.getError() instanceof WebserviceInitException) {
throw applyCheck.getError();
}
SEBServerInit.INIT_LOGGER.info("--------> Unexpected Error: {}", applyCheck.getError().getMessage());
} else {
SEBServerInit.INIT_LOGGER.info("--------> Result: {}", applyCheck.get());
}
} catch (final WebserviceInitException initE) {
throw initE;
} catch (final Exception e) {
log.error("Unexpected error while trying to apply data base integrity check: {}", dbIntegrityCheck);
}

View file

@ -99,10 +99,10 @@ public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent
this.applicationEventPublisher.publishEvent(new SEBServerInitEvent(this));
// Run the data base integrity checks and fixes if configured
// Run the database integrity checks and fixes if configured
this.dbIntegrityChecker.checkIntegrity();
// Create an initial admin account if requested and not already in the data-base
// Create an initial admin account if requested and not already in the database
this.adminUserInitializer.initAdminAccount();
SEBServerInit.INIT_LOGGER.info("----> *********************************************************");

View file

@ -0,0 +1,12 @@
package ch.ethz.seb.sebserver.webservice;
public class WebserviceInitException extends RuntimeException {
public WebserviceInitException(final String message) {
super(message);
}
public WebserviceInitException(final String message, final Throwable cause) {
super(message, cause);
}
}

View file

@ -0,0 +1,138 @@
package ch.ethz.seb.sebserver.webservice.datalayer.checks;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.DBIntegrityCheck;
import ch.ethz.seb.sebserver.webservice.WebserviceInitException;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.*;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationAttributeRecord;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.OrientationRecord;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Lazy
@Component
@WebServiceProfile
public class DowngradeSEBSettingsCheck implements DBIntegrityCheck {
public static final Logger INIT_LOGGER = LoggerFactory.getLogger("ch.ethz.seb.SEB_SERVER_INIT");
private final OrientationRecordMapper orientationRecordMapper;
private final ConfigurationAttributeRecordMapper configurationAttributeRecordMapper;
private final ConfigurationValueRecordMapper configurationValueRecordMapper;
private final String versionAttributeIds =
"1,2,3,4,8,10,11,12,13,14,15,16,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,42,43,44,45,46,47,48," +
"50,51,52,53,54,55,56,57,58,59,60,61,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,81,82,85,86,87,88," +
"89,90,91,92,93,94,95,96,97,98,99,100,200,201,202,203,204,205,206,210,220,221,222,223,231,233,234,235,236," +
"237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262," +
"263,264,265,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322," +
"400,401,402,403,404,405,406,407,408,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516," +
"517,518,519,520,804,812,900,901,904,919,928,940,941,942,950,951,952,953,960,961,970,971,972,973,974,975," +
"1100,1101,1102,1103,1104,1105,1106,1108,1116,1120,1121,1122,1123,1124,1125,1129,1130,1131,1132,1133,1500," +
"1501,1502,1503,1504,1505,1506,1508,1516,1530,1531,1532,1533,1551,1578,";
private final boolean fixDowngrade;
public DowngradeSEBSettingsCheck(
final OrientationRecordMapper orientationRecordMapper,
final ConfigurationAttributeRecordMapper configurationAttributeRecordMapper,
final ConfigurationValueRecordMapper configurationValueRecordMapper,
@Value("${sebserver.init.database.integrity.fix.downgrade:false}") final boolean fixDowngrade) {
this.orientationRecordMapper = orientationRecordMapper;
this.configurationAttributeRecordMapper = configurationAttributeRecordMapper;
this.configurationValueRecordMapper = configurationValueRecordMapper;
this.fixDowngrade = fixDowngrade;
}
@Override
public String name() {
return "DowngradeSEBSettingsCheck";
}
@Override
public String description() {
return "Check if there are additional SEB Settings orientations within the database that do not match the once for the current SEB Server version.";
}
@Override
public Result<String> applyCheck(boolean tryFix) {
return Result.tryCatch(() -> {
final String[] split = StringUtils.split(versionAttributeIds, Constants.LIST_SEPARATOR_CHAR);
final List<Long> config_attrs_ids = Arrays.stream(split).map(s -> {
try {
return Long.valueOf(s.trim());
} catch (final Exception e) {
return 0L;
}
}).collect(Collectors.toList());
final List<Long> attributeIds = orientationRecordMapper.selectByExample()
.where(OrientationRecordDynamicSqlSupport.templateId, SqlBuilder.isEqualTo(0L))
.and(OrientationRecordDynamicSqlSupport.configAttributeId, SqlBuilder.isNotIn(config_attrs_ids))
.build()
.execute()
.stream()
.map(OrientationRecord::getConfigAttributeId)
.collect(Collectors.toList());
if (attributeIds.isEmpty()) {
return "No additional SEB Settings orientations for downgrading found.";
}
final Set<String> allNames = configurationAttributeRecordMapper
.selectByExample()
.where(ConfigurationAttributeRecordDynamicSqlSupport.id, SqlBuilder.isIn(attributeIds))
.build()
.execute()
.stream()
.map(ConfigurationAttributeRecord::getName)
.collect(Collectors.toSet());
if (!fixDowngrade) {
INIT_LOGGER.error(" ---> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
INIT_LOGGER.error(" ---> !!! Detected a Database version integrity violation, probably due to SEB Server version downgrade.");
INIT_LOGGER.error(" ---> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
INIT_LOGGER.error(" ---> !!!! Please check the following correction and set 'sebserver.init.database.integrity.fix.downgrade'");
INIT_LOGGER.error(" ---> !!!! to true to apply repair with next startup. Then SEB Server will apply the repair task");
INIT_LOGGER.error(" ---> !!!! After successfully repair you can set 'sebserver.init.database.integrity.fix.downgrade' back to false ");
INIT_LOGGER.error(" ---> !!!! NOTE: Repair will delete the following SEB Settings orientation for Exam Configuration default Views");
INIT_LOGGER.error(" ---> !!!! Exam Configurations built from Configuration Template will stay the same and might have incorrect View Tabs");
INIT_LOGGER.error(" ---> !!!! Repair will remove following SEB Settings from default view:\n {}", allNames);
INIT_LOGGER.error(" ---> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
throw new WebserviceInitException("Detected a Database version integrity violation, probably due to SEB Server version downgrade. See logs above");
//return "Downgrade SEB Settings correction would delete the following SEB Settings: " + allNames;
} else {
// TODO delete orientations
try {
final Integer deletedOrientation = orientationRecordMapper
.deleteByExample()
.where(OrientationRecordDynamicSqlSupport.configAttributeId, SqlBuilder.isIn(attributeIds))
.and(OrientationRecordDynamicSqlSupport.templateId, SqlBuilder.isEqualTo(0L))
.build()
.execute();
INIT_LOGGER.info(" ---> Deleted {} entries from table orientation", deletedOrientation);
return "Successfully deleted SEB Settings attributes: " + allNames;
} catch (final Exception e) {
INIT_LOGGER.error("Failed to delete SEB Settings attributes: ", e);
return "Failed to delete SEB Settings attributes: " + allNames;
}
}
});
}
}

View file

@ -14,12 +14,8 @@ import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import ch.ethz.seb.sebserver.gbl.Constants;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@ -50,7 +46,6 @@ public class ConfigurationAttributeDAOImpl implements ConfigurationAttributeDAO
private final ConfigurationAttributeRecordMapper configurationAttributeRecordMapper;
private final ConfigurationValueRecordMapper configurationValueRecordMapper;
private final OrientationRecordMapper orientationRecordMapper;
private final Set<Long> config_attrs_ids;
protected ConfigurationAttributeDAOImpl(
final ConfigurationAttributeRecordMapper configurationAttributeRecordMapper,
@ -60,25 +55,6 @@ public class ConfigurationAttributeDAOImpl implements ConfigurationAttributeDAO
this.configurationAttributeRecordMapper = configurationAttributeRecordMapper;
this.configurationValueRecordMapper = configurationValueRecordMapper;
this.orientationRecordMapper = orientationRecordMapper;
Set<Long> _config_attrs_ids = null;
try {
final ClassPathResource configFileResource = new ClassPathResource("config/examConfigAttrVersionTable");
final String ids_comma_separated = IOUtils.toString(configFileResource.getInputStream());
final String[] split = StringUtils.split(ids_comma_separated, Constants.LIST_SEPARATOR_CHAR);
_config_attrs_ids = Arrays.stream(split).map(s -> {
try {
return Long.valueOf(s.trim());
} catch (Exception e) {
return 0L;
}
}).collect(Collectors.toSet());
} catch (final Exception e) {
log.error("Failed to get exam config attribute version infos: ", e);
_config_attrs_ids = null;
}
config_attrs_ids = _config_attrs_ids;
}
@Override
@ -176,16 +152,11 @@ public class ConfigurationAttributeDAOImpl implements ConfigurationAttributeDAO
.build()
.execute()
.stream()
.filter(this::settingsVersionFilter)
.map(ConfigurationAttributeDAOImpl::toDomainModel)
.flatMap(DAOLoggingSupport::logAndSkipOnError)
.collect(Collectors.toList()));
}
private boolean settingsVersionFilter(final ConfigurationAttributeRecord record) {
return config_attrs_ids == null || config_attrs_ids.contains(record.getId());
}
@Override
@Transactional
public Result<ConfigurationAttribute> createNew(final ConfigurationAttribute data) {

View file

@ -61,4 +61,6 @@ springdoc.swagger-ui.enabled=true
management.server.port=${server.port}
management.endpoints.web.base-path=/management
management.endpoints.web.exposure.include=logfile,loggers,jolokia
management.endpoints.web.path-mapping.jolokia=jmx
management.endpoints.web.path-mapping.jolokia=jmx
sebserver.init.database.integrity.fix.downgrade=false

View file

@ -1,348 +0,0 @@
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
91,
92,
93,
200,
201,
202,
210,
220,
300,
301,
302,
303,
304,
305,
306,
307,
308,
309,
310,
311,
312,
313,
314,
315,
316,
317,
318,
319,
320,
321,
322,
400,
401,
402,
403,
404,
405,
406,
407,
408,
500,
501,
502,
503,
504,
505,
506,
507,
508,
509,
510,
511,
512,
513,
514,
515,
516,
517,
518,
519,
520,
800,
801,
802,
803,
804,
805,
806,
807,
808,
809,
810,
812,
813,
900,
901,
902,
903,
904,
905,
906,
907,
908,
909,
910,
911,
912,
913,
914,
915,
917,
918,
919,
920,
921,
922,
923,
924,
925,
926,
927,
928,
929,
930,
931,
932,
933,
940,
941,
942,
943,
944,
945,
946,
947,
948,
950,
951,
952,
953,
960,
961,
970,
971,
972,
973,
974,
975,
1000,
1001,
1100,
1101,
1102,
1103,
1104,
1105,
1106,
1107,
1108,
1109,
1110,
1111,
1112,
1113,
1114,
1115,
1116,
1120,
1121,
1122,
1123,
1124,
1125,
1126,
1127,
1128,
1129,
1130,
1131,
1132,
1133,
1500,
1501,
1502,
1503,
1504,
1505,
1506,
1507,
1508,
1509,
1510,
1511,
1512,
1513,
1514,
1515,
1516,
1530,
1531,
1532,
1533,
1550,
1551,
1552,
1553,
1554,
1555,
1556,
1557,
1558,
1559,
1560,
1561,
1562,
1563,
1564,
1565,
1566,
1567,
1568,
1569,
1570,
1571,
1572,
1573,
1574,
1575,
1576,
1578,
74,
75,
76,
77,
78,
79,
81,
82,
85,
86,
87,
88,
89,
90,
94,
95,
96,
97,
98,
99,
100,
101,
102,
1577,
203,
204,
205,
206,
221,
222,
223,
231,
233,
234,
235,
236,
237,
238,
239,
240,
241,
242,
243,
244,
245,
246,
247,
248,
249,
250,
251,
252,
253,
254,
255,
256,
257,
258,
259,
260,
261,
262,
263,
264,
265