diff options
Diffstat (limited to 'dozentenmodulserver/src/main/java')
-rw-r--r-- | dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java | 82 | ||||
-rw-r--r-- | dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java | 189 |
2 files changed, 173 insertions, 98 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java index 74a3eb96..2fa830cf 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java @@ -50,7 +50,7 @@ public class DbImage { + " i.sharemode, i.istemplate, i.canlinkdefault, i.candownloaddefault," + " i.caneditdefault, i.canadmindefault," + " lat.expiretime, lat.filesize, lat.isrestricted, lat.isvalid," - + " lat.uploaderid, lat.isprocessed," + + " lat.uploaderid, lat.isprocessed, lat.createtime AS uploadtime," + " perm.canlink, perm.candownload, perm.canedit, perm.canadmin" + " FROM imagebase i" + " LEFT JOIN imageversion lat ON (lat.imageversionid = i.latestversionid)" @@ -133,8 +133,8 @@ public class DbImage { ImageSummaryRead entry = new ImageSummaryRead(rs.getString("imagebaseid"), rs.getString("latestversionid"), rs.getString("displayname"), rs.getInt("osid"), rs.getString("virtid"), rs.getLong("createtime"), rs.getLong("updatetime"), - rs.getLong("expiretime"), rs.getString("ownerid"), rs.getString("uploaderid"), - toShareMode(rs.getString("sharemode")), rs.getLong("filesize"), + rs.getLong("uploadtime"), rs.getLong("expiretime"), rs.getString("ownerid"), + rs.getString("uploaderid"), toShareMode(rs.getString("sharemode")), rs.getLong("filesize"), rs.getByte("isrestricted") != 0, rs.getByte("isvalid") != 0, rs.getByte("isprocessed") != 0, rs.getByte("istemplate") != 0, defaultPermissions); entry.userPermissions = DbImagePermissions.fromResultSetUser(rs); @@ -169,7 +169,7 @@ public class DbImage { + " i.sharemode, i.istemplate, i.canlinkdefault, i.candownloaddefault," + " i.caneditdefault, i.canadmindefault," + " lat.expiretime, lat.filesize, lat.isrestricted, lat.isvalid," - + " lat.uploaderid, lat.isprocessed," + + " lat.uploaderid, lat.isprocessed, lat.createtime AS uploadtime," + " perm.canlink, perm.candownload, perm.canedit, perm.canadmin" + " FROM imagebase i" + " LEFT JOIN imageversion lat ON (lat.imageversionid = i.latestversionid)" @@ -184,7 +184,7 @@ public class DbImage { return resultSetToSummary(user, rs); } - private static List<ImageVersionDetails> getImageVersions(MysqlConnection connection, String imageBaseId) + protected static List<ImageVersionDetails> getImageVersions(MysqlConnection connection, String imageBaseId) throws SQLException { List<ImageVersionDetails> versionList = new ArrayList<>(); MysqlStatement stmt = connection.prepareStatement("SELECT" @@ -366,14 +366,41 @@ public class DbImage { * * @param imageVersionId UUID of image version to delete * @throws SQLException + * @throws TNotFoundException */ - public static void markForDeletion(String imageVersionId) throws SQLException { + public static void markForDeletion(String imageVersionId) throws SQLException, TNotFoundException { try (MysqlConnection connection = Database.getConnection()) { - MysqlStatement stmt = connection.prepareStatement("UPDATE imageversion SET" - + " expiretime = UNIX_TIMESTAMP() - 1, isvalid = 0" + // Determine new latest version, as we might have to update the imagebase and lecture tables + List<ImageVersionDetails> versions = DbImage.getImageVersions(connection, + DbImage.getBaseIdForVersionId(connection, imageVersionId)); + ImageVersionDetails newVersion = null; + ImageVersionDetails oldVersion = null; + for (ImageVersionDetails version : versions) { + if (version.versionId.equals(imageVersionId)) { + oldVersion = version; + } else if (version.isValid + && (newVersion == null || version.createTime > newVersion.createTime)) { + newVersion = version; + } + } + if (oldVersion == null) { + LOGGER.warn("BUG: old version ninja'd away on markForDeletion (" + imageVersionId + ")"); + throw new TNotFoundException(); + } + // Disable version in question + MysqlStatement disableStmt = connection.prepareStatement("UPDATE imageversion SET" + + " expiretime = UNIX_TIMESTAMP() - 86400 * 5, isvalid = 0" + " WHERE imageversionid = :versionid"); - stmt.setString("versionid", imageVersionId); - stmt.executeUpdate(); + disableStmt.setString("versionid", imageVersionId); + disableStmt.executeUpdate(); + // Switch any lectures linking to this version + DbLecture.autoSwitchUsedImage(connection, oldVersion, newVersion); + // Now update the latestversionid of the baseimage if applicable + MysqlStatement latestStmt = connection.prepareStatement("UPDATE imagebase SET latestversionid = :newversionid" + + " WHERE latestversionid = :oldversionid"); + latestStmt.setString("newversionid", newVersion == null ? null : newVersion.versionId); + latestStmt.setString("oldversionid", oldVersion.versionId); + latestStmt.executeUpdate(); connection.commit(); } catch (SQLException e) { LOGGER.error("Query failed in DbImage.markForDeletion()", e); @@ -400,26 +427,33 @@ public class DbImage { byte[] machineDescription) throws SQLException { try (MysqlConnection connection = Database.getConnection()) { final long nowSecs = System.currentTimeMillis() / 1000; - MysqlStatement stmt = connection.prepareStatement("INSERT INTO imageversion" + MysqlStatement verStmt = connection.prepareStatement("INSERT INTO imageversion" + " (imageversionid, imagebaseid, createtime, expiretime, filesize, filepath, uploaderid," + " isrestricted, isvalid, isprocessed, mastersha1, virtualizerconfig)" + " VALUES " + " (:imageversionid, :imagebaseid, :createtime, :expiretime, :filesize, :filepath," + " :uploaderid, :isrestricted, :isvalid, :isprocessed, :mastersha1, :virtualizerconfig)"); - stmt.setString("imageversionid", imageVersionId); - stmt.setString("imagebaseid", imageBaseId); - stmt.setLong("createtime", nowSecs); - stmt.setLong("expiretime", nowSecs + 86400 * 365); // TODO: Config! - stmt.setLong("filesize", fileSize); - stmt.setString("filepath", filePath); - stmt.setString("uploaderid", owner.userId); - stmt.setBoolean("isrestricted", versionSettings == null ? false : versionSettings.isRestricted); - stmt.setBoolean("isvalid", true); // TODO - stmt.setBoolean("isprocessed", false); - stmt.setBinary("mastersha1", null); // TODO - stmt.setBinary("virtualizerconfig", machineDescription); - stmt.executeUpdate(); + verStmt.setString("imageversionid", imageVersionId); + verStmt.setString("imagebaseid", imageBaseId); + verStmt.setLong("createtime", nowSecs); + verStmt.setLong("expiretime", nowSecs + 86400 * 365); // TODO: Config! + verStmt.setLong("filesize", fileSize); + verStmt.setString("filepath", filePath); + verStmt.setString("uploaderid", owner.userId); + verStmt.setBoolean("isrestricted", versionSettings == null ? false : versionSettings.isRestricted); + verStmt.setBoolean("isvalid", true); // TODO + verStmt.setBoolean("isprocessed", false); + verStmt.setBinary("mastersha1", null); // TODO + verStmt.setBinary("virtualizerconfig", machineDescription); + verStmt.executeUpdate(); // TODO: Write chunk hashes to DB + // Make this version the latest version + MysqlStatement baseStmt = connection.prepareStatement("UPDATE imagebase SET" + + " latestversionid = :imageversionid WHERE imagebaseid = :imagebaseid LIMIT 1"); + baseStmt.setString("imageversionid", imageVersionId); + baseStmt.setString("imagebaseid", imageBaseId); + baseStmt.executeUpdate(); + DbLecture.autoUpdateUsedImage(connection, imageBaseId, imageVersionId); connection.commit(); } catch (SQLException e) { LOGGER.error("Query failed in DbImage.createImageVersion()", e); diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java index efd9f78b..4ad815ec 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java @@ -13,6 +13,7 @@ import org.openslx.bwlp.sat.database.MysqlConnection; import org.openslx.bwlp.sat.database.MysqlStatement; import org.openslx.bwlp.sat.permissions.User; import org.openslx.bwlp.sat.util.Json; +import org.openslx.bwlp.thrift.iface.ImageVersionDetails; import org.openslx.bwlp.thrift.iface.LectureRead; import org.openslx.bwlp.thrift.iface.LectureSummary; import org.openslx.bwlp.thrift.iface.LectureWrite; @@ -26,10 +27,45 @@ public class DbLecture { private static final Logger LOGGER = Logger.getLogger(DbLecture.class); - public static String create(UserInfo user, LectureWrite lecture) throws SQLException { + private static void setWriteFields(MysqlStatement stmt, String lectureId, LectureWrite lecture, + UserInfo updatingUser) throws SQLException { if (lecture.lectureName.length() > 100) { lecture.lectureName = lecture.lectureName.substring(0, 100); } + String nicsJson = null; + if (lecture.nics != null && !lecture.nics.isEmpty()) { + for (;;) { + nicsJson = Json.serialize(lecture.nics); + if (nicsJson.length() < 200) + break; + lecture.nics.remove(0); + } + } + String netruleJson; + if (lecture.networkExceptions == null) { + netruleJson = null; + } else { + netruleJson = Json.serialize(lecture.networkExceptions); + } + stmt.setString("lectureid", lectureId); + stmt.setString("displayname", lecture.lectureName); + stmt.setString("description", lecture.description); + stmt.setString("imageversionid", lecture.imageVersionId); + stmt.setBoolean("autoupdate", lecture.autoUpdate); + stmt.setBoolean("isenabled", lecture.isEnabled); + stmt.setLong("starttime", lecture.startTime); + stmt.setLong("endtime", lecture.endTime); + stmt.setString("updaterid", updatingUser.userId); + stmt.setString("runscript", lecture.runscript); + stmt.setString("nics", nicsJson); + stmt.setString("netrules", netruleJson); + stmt.setBoolean("isexam", lecture.isExam); + stmt.setBoolean("hasinternetaccess", lecture.hasInternetAccess); + stmt.setBoolean("caneditdefault", lecture.defaultPermissions.edit); + stmt.setBoolean("canadmindefault", lecture.defaultPermissions.admin); + } + + public static String create(UserInfo user, LectureWrite lecture) throws SQLException { try (MysqlConnection connection = Database.getConnection()) { MysqlStatement stmt = connection.prepareStatement("INSERT INTO lecture" + " (lectureid, displayname, description, imageversionid, autoupdate," @@ -39,23 +75,12 @@ public class DbLecture { + " VALUES " + " (:lectureid, :displayname, :description, :imageversionid, :autoupdate," + " :isenabled, :starttime, :endtime, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()," - + " :userid, :userid, NULL, NULL, NULL, :isexam, :hasinternetaccess, :canedit, :canadmin)"); + + " :ownerid, :updaterid, :runscript, :nics, :netrules, :isexam," + + " :hasinternetaccess, :caneditdefault, :canadmindefault)"); String lectureId = UUID.randomUUID().toString(); - stmt.setString("lectureid", lectureId); - stmt.setString("displayname", lecture.lectureName); - stmt.setString("description", lecture.description); - stmt.setString("imageversionid", lecture.imageVersionId); - stmt.setBoolean("autoupdate", lecture.autoUpdate); - stmt.setBoolean("isenabled", lecture.isEnabled); - stmt.setLong("starttime", lecture.startTime); - stmt.setLong("endtime", lecture.endTime); - stmt.setString("userid", user.userId); - stmt.setBoolean("isexam", lecture.isExam); - stmt.setBoolean("hasinternetaccess", lecture.hasInternetAccess); - stmt.setBoolean("canedit", lecture.defaultPermissions.edit); - stmt.setBoolean("canadmin", lecture.defaultPermissions.admin); + setWriteFields(stmt, lectureId, lecture, user); + stmt.setString("ownerid", user.userId); stmt.executeUpdate(); - update(connection, user, lectureId, lecture); // TODO: WTF connection.commit(); return lectureId; } catch (SQLException e) { @@ -64,20 +89,18 @@ public class DbLecture { } } - public static void setOwner(UserInfo user, String lectureId, String newOwnerId) throws SQLException { - try (MysqlConnection connection = Database.getConnection()) { - MysqlStatement stmt = connection.prepareStatement("UPDATE lecture" - + " SET ownerid = :ownerid, updaterid = :userid, updatetime = UNIX_TIMESTAMP()" - + " WHERE lectureid = :lectureid"); - stmt.setString("ownerid", newOwnerId); - stmt.setString("userid", user.userId); - stmt.setString("lectureid", lectureId); - stmt.executeUpdate(); - connection.commit(); - } catch (SQLException e) { - LOGGER.error("Query failed in DbLecture.setOwner()", e); - throw e; - } + private static void update(MysqlConnection connection, UserInfo user, String lectureId, + LectureWrite lecture) throws SQLException { + MysqlStatement stmt = connection.prepareStatement("UPDATE lecture SET " + + " displayname = :displayname, description = :description, imageversionid = :imageversionid," + + " autoupdate = :autoupdate, isenabled = :isenabled, starttime = :starttime," + + " endtime = :endtime, updatetime = UNIX_TIMESTAMP()," + + " updaterid = :updaterid, runscript = :runscript, nics = :nics," + + " netrules = :netrules, isexam = :isexam, hasinternetaccess = :hasinternetaccess," + + " caneditdefault = :caneditdefault, canadmindefault = :canadmindefault" + + " WHERE lectureid = :lectureid"); + setWriteFields(stmt, lectureId, lecture, user); + stmt.executeUpdate(); } public static void update(UserInfo user, String lectureId, LectureWrite lecture) throws SQLException { @@ -90,51 +113,20 @@ public class DbLecture { } } - private static void update(MysqlConnection connection, UserInfo user, String lectureId, - LectureWrite lecture) throws SQLException { - if (lecture.lectureName.length() > 100) { - lecture.lectureName = lecture.lectureName.substring(0, 100); - } - String nicsJson = null; - if (lecture.nics != null && !lecture.nics.isEmpty()) { - for (;;) { - nicsJson = Json.serialize(lecture.nics); - if (nicsJson.length() < 200) - break; - lecture.nics.remove(0); - } - } - String netruleJson; - if (lecture.networkExceptions == null) { - netruleJson = null; - } else { - netruleJson = Json.serialize(lecture.networkExceptions); + public static void setOwner(UserInfo user, String lectureId, String newOwnerId) throws SQLException { + try (MysqlConnection connection = Database.getConnection()) { + MysqlStatement stmt = connection.prepareStatement("UPDATE lecture" + + " SET ownerid = :ownerid, updaterid = :updaterid, updatetime = UNIX_TIMESTAMP()" + + " WHERE lectureid = :lectureid"); + stmt.setString("ownerid", newOwnerId); + stmt.setString("updaterid", user.userId); + stmt.setString("lectureid", lectureId); + stmt.executeUpdate(); + connection.commit(); + } catch (SQLException e) { + LOGGER.error("Query failed in DbLecture.setOwner()", e); + throw e; } - MysqlStatement stmt = connection.prepareStatement("UPDATE lecture SET " - + " displayname = :displayname, description = :description, imageversionid = :imageversionid," - + " autoupdate = :autoupdate, isenabled = :isenabled, starttime = :starttime," - + " endtime = :endtime, updatetime = UNIX_TIMESTAMP()," - + " updaterid = :updaterid, runscript = :runscript, nics = :nics," - + " netrules = :netrules, isexam = :isexam, hasinternetaccess = :hasinternetaccess," - + " caneditdefault = :caneditdefault, canadmindefault = :canadmindefault" - + " WHERE lectureid = :lectureid"); - stmt.setString("lectureid", lectureId); - stmt.setString("displayname", lecture.lectureName); - stmt.setString("description", lecture.description); - stmt.setString("imageversionid", lecture.imageVersionId); - stmt.setBoolean("autoupdate", lecture.autoUpdate); - stmt.setBoolean("isenabled", lecture.isEnabled); - stmt.setLong("starttime", lecture.startTime); - stmt.setLong("endtime", lecture.endTime); - stmt.setString("updaterid", user.userId); - stmt.setString("runscript", lecture.runscript); - stmt.setString("nics", nicsJson); - stmt.setString("netrules", netruleJson); - stmt.setBoolean("isexam", lecture.isExam); - stmt.setBoolean("hasinternetaccess", lecture.hasInternetAccess); - stmt.setBoolean("caneditdefault", lecture.defaultPermissions.edit); - stmt.setBoolean("canadmindefault", lecture.defaultPermissions.admin); - stmt.executeUpdate(); } public static LectureSummary getLectureSummary(UserInfo user, String lectureId) throws SQLException, @@ -219,6 +211,18 @@ public class DbLecture { } } + protected static List<String> getAllUsingImageVersion(MysqlConnection connection, String imageVersionId) + throws SQLException { + MysqlStatement stmt = connection.prepareStatement("SELECT lectureid FROM lecture WHERE imageversionid = :imageversionid"); + stmt.setString("imageversionid", imageVersionId); + ResultSet rs = stmt.executeQuery(); + List<String> list = new ArrayList<>(); + while (rs.next()) { + list.add(rs.getString("lectureid")); + } + return list; + } + public static LectureRead getLectureDetails(UserInfo user, String lectureId) throws SQLException, TNotFoundException { try (MysqlConnection connection = Database.getConnection()) { @@ -297,4 +301,41 @@ public class DbLecture { } return affected == 1; } + + protected static void autoUpdateUsedImage(MysqlConnection connection, String imageBaseId, + String imageVersionId) throws SQLException { + // TODO: select first so we can email + MysqlStatement stmt = connection.prepareStatement("UPDATE lecture l, imageversion v SET" + + " l.imageversionid = :imageversionid" + + " WHERE v.imageversionid = l.imageversionid AND v.imagebaseid = :imagebaseid" + + " AND l.autoupdate = 1"); + stmt.setString("imageversionid", imageVersionId); + stmt.setString("imagebaseid", imageBaseId); + stmt.executeUpdate(); + } + + /** + * Called when an image version is deleted or marked for deletion, so that + * linking lectures switch over to other available versions. + */ + protected static void autoSwitchUsedImage(MysqlConnection connection, ImageVersionDetails oldVersion, ImageVersionDetails newVersion) + throws TNotFoundException, SQLException { + // First, get list of lectures using the image version to switch away to + List<String> lectures = getAllUsingImageVersion(connection, oldVersion.versionId); + if (lectures.isEmpty()) + return; + // TODO: If there is no new candidate to switch to, send a warning via mail + if (newVersion == null) { + // ... email stuff + return; + } + // Update and send info mail + MysqlStatement stmt = connection.prepareStatement("UPDATE lecture SET imageversionid = :newversionid" + + " WHERE imageversionid = :oldversionid"); + stmt.setString("oldversionid", oldVersion.versionId); + stmt.setString("newversionid", newVersion.versionId); + stmt.executeUpdate(); + // TODO: Send mails .. Something.sendLectureChangeNotify(lectures, oldVersion, newVersion); + } + } |