summaryrefslogtreecommitdiffstats
path: root/dozentenmodulserver
diff options
context:
space:
mode:
authorSimon Rettberg2015-08-18 15:04:17 +0200
committerSimon Rettberg2015-08-18 15:04:17 +0200
commitc87ec3599fb22bd4b97d7ffbb7542fdbb22f3ca9 (patch)
treef7fe4d94708729459ae136fe2d981a0d8f6417d4 /dozentenmodulserver
parent[client] Handle TTransferRejectedException in ThriftError.showMessage (diff)
downloadtutor-module-c87ec3599fb22bd4b97d7ffbb7542fdbb22f3ca9.tar.gz
tutor-module-c87ec3599fb22bd4b97d7ffbb7542fdbb22f3ca9.tar.xz
tutor-module-c87ec3599fb22bd4b97d7ffbb7542fdbb22f3ca9.zip
[server] Update lectures and images when image versions change or get deleted
Diffstat (limited to 'dozentenmodulserver')
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java5
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlConnection.java1
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java105
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java16
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java17
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java9
6 files changed, 118 insertions, 35 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
index 261fbf5a..81898d7c 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
@@ -64,11 +64,12 @@ public class App {
@Override
public boolean thriftError(int failCount, String method, Throwable t) {
- if (failCount > 2 || (t != null && !(t instanceof TTransportException))) {
+ if (failCount > 2 || t == null || !(t instanceof TTransportException)) {
LOGGER.warn("Thrift Client error for " + method + ", FAIL.");
return false;
}
- LOGGER.info("Thrift Client error for " + method + ", retrying...");
+ LOGGER.info("Thrift transport error " + ((TTransportException) t).getType() + " for "
+ + method + ", retrying...");
try {
Thread.sleep(failCount * 250);
} catch (InterruptedException e) {
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlConnection.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlConnection.java
index c17b7946..253d45f2 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlConnection.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlConnection.java
@@ -51,6 +51,7 @@ public class MysqlConnection implements AutoCloseable {
public void close() {
if (hasPendingQueries) {
LOGGER.warn("Mysql connection had uncommited queries on .close()");
+ hasPendingQueries = false;
}
try {
rawConnection.rollback();
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 605dff1a..a6b6d4b8 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
@@ -23,6 +23,8 @@ import org.openslx.bwlp.thrift.iface.ShareMode;
import org.openslx.bwlp.thrift.iface.TNotFoundException;
import org.openslx.bwlp.thrift.iface.UserInfo;
import org.openslx.filetransfer.util.ChunkList;
+import org.openslx.util.QuickTimer;
+import org.openslx.util.QuickTimer.Task;
public class DbImage {
@@ -387,42 +389,18 @@ public class DbImage {
*/
public static void markForDeletion(String imageVersionId) throws SQLException, TNotFoundException {
try (MysqlConnection connection = Database.getConnection()) {
- // 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");
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);
throw e;
}
+ updateLatestVersionAsync(imageVersionId, null);
}
public static void setShareMode(String imageBaseId, ImageBaseWrite newData) throws SQLException {
@@ -478,4 +456,81 @@ public class DbImage {
}
}
+ public static void markValid(LocalImageVersion imageVersion, boolean valid) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("UPDATE imageversion SET isvalid = :valid"
+ + " WHERE imageversionid = :imageversionid");
+ stmt.setString("imageversionid", imageVersion.imageVersionId);
+ stmt.setBoolean("valid", valid);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.markInvalid()", e);
+ throw e;
+ }
+ updateLatestVersionAsync(imageVersion.imageVersionId, imageVersion.imageBaseId);
+ }
+
+ private static void updateLatestVersionAsync(final String changingImageVersionId, final String imageBaseId) {
+ QuickTimer.scheduleOnce(new Task() {
+ @Override
+ public void fire() {
+ try (MysqlConnection connection = Database.getConnection()) {
+ updateLatestVersion(connection, changingImageVersionId, imageBaseId);
+ connection.commit();
+ } catch (SQLException | TNotFoundException e) {
+ LOGGER.error("Query failed in DbImage.updateLatestVersion()", e);
+ }
+ }
+ });
+ }
+
+ /**
+ * Makes sure the latestVersionId-field of the given base image is
+ * consistent, while also updating any affected lectures.
+ *
+ * @param connection mysql connection to use
+ * @param changingImageVersionId the version id of the image that changed
+ * (REQUIRED)
+ * @param imageBaseId the base id of the image that changed (OPTIONAL, will
+ * be determined if missing)
+ * @throws TNotFoundException
+ * @throws SQLException
+ */
+ private static void updateLatestVersion(MysqlConnection connection, String changingImageVersionId,
+ String imageBaseId) throws TNotFoundException, SQLException {
+ if (imageBaseId == null) {
+ imageBaseId = DbImage.getBaseIdForVersionId(connection, changingImageVersionId);
+ if (imageBaseId == null)
+ throw new TNotFoundException();
+ }
+ // Determine new latest version, as we might have to update the imagebase and lecture tables
+ List<ImageVersionDetails> versions = DbImage.getImageVersions(connection, imageBaseId);
+ ImageVersionDetails newVersion = null;
+ ImageVersionDetails oldVersion = null;
+ for (ImageVersionDetails version : versions) {
+ if (version.versionId.equals(changingImageVersionId)) {
+ oldVersion = version;
+ }
+ if (version.isValid && (newVersion == null || version.createTime > newVersion.createTime)) {
+ newVersion = version;
+ }
+ }
+ if (oldVersion == null) {
+ LOGGER.warn("BUG: oldVersion ninjad away on updateLatestVersion (" + changingImageVersionId + ")");
+ } else {
+ // Switch any lectures linking to this version if applicable
+ if (oldVersion.isValid) {
+ DbLecture.autoUpdateUsedImage(connection, imageBaseId, newVersion.versionId);
+ } else {
+ DbLecture.forcefullySwitchUsedImage(connection, oldVersion, newVersion);
+ }
+ }
+ // Now update the latestversionid of the baseimage if applicable
+ MysqlStatement latestStmt = connection.prepareStatement("UPDATE imagebase SET latestversionid = :newversionid"
+ + " WHERE imagebaseid = :imagebaseid");
+ latestStmt.setString("newversionid", newVersion == null ? null : newVersion.versionId);
+ latestStmt.setString("imagebaseid", imageBaseId);
+ latestStmt.executeUpdate();
+ }
}
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 cbc4c690..c44d40ed 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
@@ -308,6 +308,15 @@ public class DbLecture {
return affected == 1;
}
+ /**
+ * Called when a new version for an image is uploaded. Update all lectures
+ * using the same base image which have the autoUpdate-flag set.
+ *
+ * @param connection
+ * @param imageBaseId
+ * @param imageVersionId
+ * @throws SQLException
+ */
protected static void autoUpdateUsedImage(MysqlConnection connection, String imageBaseId,
String imageVersionId) throws SQLException {
// TODO: select first so we can email
@@ -324,9 +333,12 @@ public class DbLecture {
* 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,
+ protected static void forcefullySwitchUsedImage(MysqlConnection connection, ImageVersionDetails oldVersion,
ImageVersionDetails newVersion) throws TNotFoundException, SQLException {
- // First, get list of lectures using the image version to switch away to
+ if (oldVersion == newVersion
+ || (newVersion != null && newVersion.versionId.equals(oldVersion.versionId)))
+ return;
+ // First, get list of lectures using the image version to switch away from
List<String> lectures = getAllUsingImageVersion(connection, oldVersion.versionId);
if (lectures.isEmpty())
return;
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
index 3232374e..cc54ba94 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -16,6 +17,7 @@ import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import org.apache.log4j.Logger;
+import org.openslx.bwlp.sat.database.mappers.DbImage;
import org.openslx.bwlp.sat.database.models.LocalImageVersion;
import org.openslx.bwlp.sat.util.Configuration;
import org.openslx.bwlp.sat.util.Constants;
@@ -181,9 +183,22 @@ public class FileServer implements IncomingEvent {
if (!srcFile.canRead()) {
LOGGER.warn("Rejecting download of VID " + localImageData.imageVersionId + ": Missing "
+ srcFile.getPath());
- // TODO: Mark as invalid in DB
+ try {
+ DbImage.markValid(localImageData, false);
+ } catch (SQLException e) {
+ }
throw new TTransferRejectedException("File missing on server");
}
+ if (srcFile.length() != localImageData.fileSize) {
+ LOGGER.warn("Rejecting download of VID " + localImageData.imageVersionId + ": Size mismatch for "
+ + srcFile.getPath() + " (expected " + localImageData.fileSize + ", is "
+ + srcFile.length() + ")");
+ try {
+ DbImage.markValid(localImageData, false);
+ } catch (SQLException e) {
+ }
+ throw new TTransferRejectedException("File corrupted on server");
+ }
String key = UUID.randomUUID().toString();
ActiveDownload transfer = new ActiveDownload(key, srcFile);
downloads.put(key, transfer);
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java
index 41d790bc..6e5e4d32 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java
@@ -30,11 +30,11 @@ public class User {
private static final LecturePermissions lectureNothing = new LecturePermissions(false, false);
public static boolean isTutor(UserInfo user) {
- return user.role == Role.TUTOR;
+ return user != null && user.role == Role.TUTOR;
}
public static boolean isStudent(UserInfo user) {
- return user.role == Role.STUDENT;
+ return user != null && user.role == Role.STUDENT;
}
/**
@@ -175,10 +175,9 @@ public class User {
} catch (SQLException e) {
throw new TInternalServerError();
}
- if (user != null && user.role != Role.STUDENT) {
- if (image.userPermissions.download)
+ if (image.userPermissions.download) {
+ if (isTutor(user))
return;
- } else {
// User is unknown role or student, check version's restricted flag
for (ImageVersionDetails version : image.versions) {
if (!version.isRestricted && version.versionId.equals(imageVersionId))