diff options
author | Simon Rettberg | 2016-04-18 15:18:59 +0200 |
---|---|---|
committer | Simon Rettberg | 2016-04-18 15:18:59 +0200 |
commit | a183af9133e033dac3d1be3d3a141296713cb36e (patch) | |
tree | bc11129b87b1d40d67cf9ddf20e01066f97213e7 /dozentenmodulserver/src | |
parent | (WiP) Global image sync (diff) | |
download | tutor-module-a183af9133e033dac3d1be3d3a141296713cb36e.tar.gz tutor-module-a183af9133e033dac3d1be3d3a141296713cb36e.tar.xz tutor-module-a183af9133e033dac3d1be3d3a141296713cb36e.zip |
[*] Make uploading images to central server work
Diffstat (limited to 'dozentenmodulserver/src')
5 files changed, 82 insertions, 54 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 8aafe862..563b8885 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 @@ -303,7 +303,7 @@ public class DbImage { */ public static void writeBaseImage(UserInfo user, ImagePublishData image) throws SQLException { if (user == null) { - user = image.user; + user = image.owner; } try (MysqlConnection connection = Database.getConnection()) { MysqlStatement stmt = connection.prepareStatement("INSERT INTO imagebase" diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java index 4ce8cc0a..0276e0cd 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java @@ -90,12 +90,12 @@ public class IncomingDataTransfer extends IncomingTransferBase { idr.setIsTemplate(publishData.isTemplate); idr.setLatestVersionId(publishData.imageVersionId); idr.setOsId(publishData.osId); - idr.setOwnerId(publishData.user.userId); + idr.setOwnerId(publishData.owner.userId); idr.setTags(publishData.tags); - idr.setUpdaterId(publishData.user.userId); + idr.setUpdaterId(publishData.uploader.userId); idr.setUpdateTime(publishData.createTime); idr.setVirtId(publishData.virtId); - this.owner = publishData.user; + this.owner = publishData.owner; this.image = idr; this.machineDescription = ThriftUtil.unwrapByteBuffer(transferInfo.machineDescription); this.masterTransferInfo = transferInfo; diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/SyncTransferHandler.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/SyncTransferHandler.java index 27e11185..36faa4bc 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/SyncTransferHandler.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/SyncTransferHandler.java @@ -4,9 +4,11 @@ import java.io.File; import java.io.FileNotFoundException; import java.nio.ByteBuffer; import java.sql.SQLException; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.WeakHashMap; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -22,6 +24,7 @@ import org.openslx.bwlp.sat.util.Formatter; import org.openslx.bwlp.sat.util.PrioThreadFactory; import org.openslx.bwlp.thrift.iface.ImageDetailsRead; import org.openslx.bwlp.thrift.iface.ImagePublishData; +import org.openslx.bwlp.thrift.iface.ImageSummaryRead; import org.openslx.bwlp.thrift.iface.InvocationError; import org.openslx.bwlp.thrift.iface.TAuthorizationException; import org.openslx.bwlp.thrift.iface.TInvocationException; @@ -46,14 +49,19 @@ public class SyncTransferHandler { Thread.NORM_PRIORITY - 3)); /** - * All currently running uploads, indexed by token + * All currently running downloads from master, indexed by token */ private static final Map<String, IncomingDataTransfer> downloads = new ConcurrentHashMap<>(); /** - * All currently running downloads, indexed by token + * All currently running uploads from master, indexed by token */ - private static final Map<String, OutgoingDataTransfer> uploads = new ConcurrentHashMap<>(); + private static final Map<String, OutgoingDataTransfer> uploadsByTransferId = new ConcurrentHashMap<>(); + + /** + * All currently running uploads to master, by image version id + */ + private static final Map<String, OutgoingDataTransfer> uploadsByVersionId = Collections.synchronizedMap(new WeakHashMap<String, OutgoingDataTransfer>()); private static Task heartBeatTask = new Task() { private final Runnable worker = new Runnable() { @@ -69,7 +77,7 @@ public class SyncTransferHandler { it.remove(); } } - for (Iterator<OutgoingDataTransfer> it = uploads.values().iterator(); it.hasNext();) { + for (Iterator<OutgoingDataTransfer> it = uploadsByTransferId.values().iterator(); it.hasNext();) { OutgoingDataTransfer upload = it.next(); if (upload.isActive()) upload.heartBeat(transferPool); @@ -95,38 +103,39 @@ public class SyncTransferHandler { QuickTimer.scheduleAtFixedDelay(heartBeatTask, 123, TimeUnit.SECONDS.toMillis(56)); } - public synchronized static String requestImageUpload(String userToken, LocalImageVersion img) - throws SQLException, TNotFoundException, TInvocationException, TAuthorizationException, - TTransferRejectedException { + public synchronized static String requestImageUpload(String userToken, ImageSummaryRead imgBase, + LocalImageVersion imgVersion) throws SQLException, TNotFoundException, TInvocationException, + TAuthorizationException, TTransferRejectedException { TransferInformation transferInfo; - OutgoingDataTransfer existing = uploads.get(img.imageVersionId); + OutgoingDataTransfer existing = uploadsByVersionId.get(imgVersion.imageVersionId); if (existing != null) return existing.getId(); - File absFile = FileSystem.composeAbsoluteImagePath(img); + File absFile = FileSystem.composeAbsoluteImagePath(imgVersion); if (!absFile.isFile() || !absFile.canRead()) { - LOGGER.error("Cannot upload " + img.imageVersionId + ": file missing: " + LOGGER.error("Cannot upload " + imgVersion.imageVersionId + ": file missing: " + absFile.getAbsolutePath()); throw new TInvocationException(InvocationError.INTERNAL_SERVER_ERROR, "Source file not readable"); } - if (absFile.length() != img.fileSize) { - LOGGER.error("Cannot upload" + img.imageVersionId + ": wrong file size - expected " - + img.fileSize + ", got " + absFile.length()); + if (absFile.length() != imgVersion.fileSize) { + LOGGER.error("Cannot upload" + imgVersion.imageVersionId + ": wrong file size - expected " + + imgVersion.fileSize + ", got " + absFile.length()); throw new TInvocationException(InvocationError.INTERNAL_SERVER_ERROR, "File corrupted on satellite server"); } checkUploadCount(); - ImageDetailsRead details = DbImage.getImageDetails(null, img.imageBaseId); - List<ByteBuffer> blockHashes = DbImage.getBlockHashes(img.imageVersionId); + ImageDetailsRead details = DbImage.getImageDetails(null, imgVersion.imageBaseId); + List<ByteBuffer> blockHashes = DbImage.getBlockHashes(imgVersion.imageVersionId); ImagePublishData publishData = new ImagePublishData(); - publishData.createTime = img.createTime; + publishData.createTime = imgVersion.createTime; publishData.description = details.description; - publishData.fileSize = img.fileSize; - publishData.imageBaseId = img.imageBaseId; + publishData.fileSize = imgVersion.fileSize; + publishData.imageBaseId = imgVersion.imageBaseId; publishData.imageName = details.imageName; - publishData.imageVersionId = img.imageVersionId; + publishData.imageVersionId = imgVersion.imageVersionId; publishData.isTemplate = details.isTemplate; publishData.osId = details.osId; - publishData.user = DbUser.getOrNull(img.uploaderId); + publishData.uploader = DbUser.getOrNull(imgVersion.uploaderId); + publishData.owner = DbUser.getOrNull(imgBase.ownerId); publishData.virtId = details.virtId; try { transferInfo = ThriftManager.getMasterClient().submitImage(userToken, publishData, blockHashes); @@ -145,7 +154,8 @@ public class SyncTransferHandler { "Communication with master server failed"); } OutgoingDataTransfer transfer = new OutgoingDataTransfer(transferInfo, absFile); - uploads.put(transfer.getId(), transfer); + uploadsByVersionId.put(imgVersion.imageVersionId, transfer); + uploadsByTransferId.put(transfer.getId(), transfer); transfer.heartBeat(transferPool); return transfer.getId(); } @@ -203,7 +213,7 @@ public class SyncTransferHandler { } activeDownloads++; } - if (activeDownloads > Constants.MAX_MASTER_DOWNLOADS) { + if (activeDownloads >= Constants.MAX_MASTER_DOWNLOADS) { throw new TInvocationException(InvocationError.INTERNAL_SERVER_ERROR, "Server busy. Too many running downloads (" + activeDownloads + "/" + Constants.MAX_MASTER_DOWNLOADS + ")."); @@ -211,7 +221,7 @@ public class SyncTransferHandler { } private static void checkUploadCount() throws TInvocationException { - Iterator<OutgoingDataTransfer> it = uploads.values().iterator(); + Iterator<OutgoingDataTransfer> it = uploadsByTransferId.values().iterator(); final long now = System.currentTimeMillis(); int activeUploads = 0; while (it.hasNext()) { @@ -223,7 +233,7 @@ public class SyncTransferHandler { } activeUploads++; } - if (activeUploads > Constants.MAX_MASTER_UPLOADS) { + if (activeUploads >= Constants.MAX_MASTER_UPLOADS) { throw new TInvocationException(InvocationError.INTERNAL_SERVER_ERROR, "Server busy. Too many running uploads (" + activeUploads + "/" + Constants.MAX_MASTER_UPLOADS + ")."); @@ -239,7 +249,7 @@ public class SyncTransferHandler { public static OutgoingDataTransfer getUploadByToken(String uploadToken) { if (uploadToken == null) return null; - return uploads.get(uploadToken); + return uploadsByTransferId.get(uploadToken); } public static IncomingDataTransfer getDownloadByToken(String downloadToken) { 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 6c252ace..bbf534e7 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 @@ -5,6 +5,7 @@ import java.sql.SQLException; import org.openslx.bwlp.sat.database.mappers.DbImage; import org.openslx.bwlp.sat.database.mappers.DbLecture; import org.openslx.bwlp.sat.database.mappers.DbOrganization; +import org.openslx.bwlp.sat.database.models.LocalImageVersion; import org.openslx.bwlp.sat.database.models.LocalOrganization; import org.openslx.bwlp.sat.database.models.LocalUser; import org.openslx.bwlp.sat.thrift.cache.OrganizationList; @@ -353,6 +354,15 @@ public class User { "Only the super user can change the expire date of images"); } + public static void canUploadToMasterOrFail(UserInfo user, ImageSummaryRead imgBase) throws TAuthorizationException { + if (isSuperUser(user)) + return; + if (imgBase.userPermissions.admin) + return; + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "You need to be image admin to upload to master server"); + } + public static void canTriggerReplicationOrFail(UserInfo user, String imageVersionId) throws TAuthorizationException, TInvocationException { if (isTutor(user)) { diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java index 2d3d2b91..df845fdc 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java @@ -76,8 +76,10 @@ public class ServerHandler implements SatelliteServer.Iface { private static final FileServer fileServer = FileServer.instance(); @Override - public long getVersion() { - return Version.VERSION; + public long getVersion(long clientVersion) { + if (clientVersion >= Version.VERSION) + return Version.VERSION; + return Math.max(clientVersion, Version.MIN_VERSION); } @Override @@ -520,11 +522,37 @@ public class ServerHandler implements SatelliteServer.Iface { } @Override + public String publishImageVersion(String userToken, String imageVersionId) + throws TAuthorizationException, TNotFoundException, TInvocationException, TTransferRejectedException { + UserInfo user = SessionManager.getOrFail(userToken); + User.canCreateImageOrFail(user); + LocalImageVersion imgVersion = null; + ImageSummaryRead imgBase = null; + try { + imgVersion = DbImage.getLocalImageData(imageVersionId); + imgBase = DbImage.getImageSummary(user, imgVersion.imageBaseId); + //img.uploaderId + } catch (SQLException e1) { + throw new TInvocationException(InvocationError.INTERNAL_SERVER_ERROR, "Database error"); + } + User.canUploadToMasterOrFail(user, imgBase); + try { + return SyncTransferHandler.requestImageUpload(userToken, imgBase, imgVersion); + } catch (TTransferRejectedException e) { + LOGGER.warn("Master server rejected upload of image version " + imgVersion.imageVersionId); + throw e; + } catch (SQLException e) { + throw new TInvocationException(InvocationError.INTERNAL_SERVER_ERROR, "Database error"); + } + } + + @Override public String createLecture(String userToken, LectureWrite lecture) throws TAuthorizationException, TInvocationException, TInvalidDateParam, TNotFoundException { if (lecture == null || lecture.defaultPermissions == null) throw new TInvocationException(InvocationError.MISSING_DATA, "Lecture data missing or incomplete"); - if (lecture.locationIds != null && lecture.locationIds.size() > RuntimeConfig.getMaxLocationsPerLecture()) + if (lecture.locationIds != null + && lecture.locationIds.size() > RuntimeConfig.getMaxLocationsPerLecture()) throw new TInvocationException(InvocationError.INVALID_DATA, "Too many locations for lecture"); UserInfo user = SessionManager.getOrFail(userToken); User.canCreateLectureOrFail(user); @@ -542,7 +570,8 @@ public class ServerHandler implements SatelliteServer.Iface { throws TAuthorizationException, TNotFoundException, TInvocationException, TInvalidDateParam { if (newLectureData == null) throw new TInvocationException(InvocationError.MISSING_DATA, "Lecture data missing or incomplete"); - if (newLectureData.locationIds != null && newLectureData.locationIds.size() > RuntimeConfig.getMaxLocationsPerLecture()) + if (newLectureData.locationIds != null + && newLectureData.locationIds.size() > RuntimeConfig.getMaxLocationsPerLecture()) throw new TInvocationException(InvocationError.INVALID_DATA, "Too many locations for lecture"); UserInfo user = SessionManager.getOrFail(userToken); LectureSummary oldLecture; @@ -580,27 +609,6 @@ public class ServerHandler implements SatelliteServer.Iface { @Override public LectureRead getLectureDetails(String userToken, String lectureId) throws TAuthorizationException, TNotFoundException, TInvocationException { - // - // TEST - // - /* - String imageVersionId = "e9de1941-b673-4711-b033-d8c37d1e2d3e"; - LocalImageVersion img; - try { - img = DbImage.getLocalImageData(imageVersionId); - SyncTransferHandler.requestImageUpload(userToken, img); - } catch (SQLException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (TTransferRejectedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - */ - // - // - // - // UserInfo user = SessionManager.getOrFail(userToken); User.canSeeLectureDetailsOrFail(user); try { |