summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2016-04-18 15:18:59 +0200
committerSimon Rettberg2016-04-18 15:18:59 +0200
commita183af9133e033dac3d1be3d3a141296713cb36e (patch)
treebc11129b87b1d40d67cf9ddf20e01066f97213e7
parent(WiP) Global image sync (diff)
downloadtutor-module-a183af9133e033dac3d1be3d3a141296713cb36e.tar.gz
tutor-module-a183af9133e033dac3d1be3d3a141296713cb36e.tar.xz
tutor-module-a183af9133e033dac3d1be3d3a141296713cb36e.zip
[*] Make uploading images to central server work
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java34
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java3
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java6
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java2
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/IncomingDataTransfer.java6
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/SyncTransferHandler.java60
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java10
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java58
8 files changed, 121 insertions, 58 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java
index 20f84b29..a3541c0a 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java
@@ -60,6 +60,9 @@ import org.openslx.dozmod.thrift.cache.MetaDataCache;
import org.openslx.dozmod.thrift.cache.UserCache;
import org.openslx.dozmod.util.FormatHelper;
import org.openslx.dozmod.util.MapHelper;
+import org.openslx.thrifthelper.ThriftManager;
+import org.openslx.util.QuickTimer;
+import org.openslx.util.QuickTimer.Task;
/**
* Window for displaying and editing the details of an image.
@@ -155,6 +158,12 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout implements UiFe
refresh(true);
}
});
+ btnUploadToMaster.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ uploadToMaster();
+ }
+ });
btnShowLinkingLectures.addActionListener(new ActionListener() {
@@ -398,7 +407,30 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout implements UiFe
} else {
btnSaveChanges.setEnabled(true);
}
+ }
+ private void uploadToMaster() {
+ QuickTimer.scheduleOnce(new Task() {
+ @Override
+ public void fire() {
+ try {
+ String transferId = ThriftManager.getSatClient().publishImageVersion(
+ Session.getSatelliteToken(), image.latestVersionId);
+ /*
+ Gui.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ MainWindow.addUpload(transferId, );
+ }
+ });
+ */
+ Gui.asyncMessageBox("Läuft: " + transferId, MessageType.INFO, null, null);
+ } catch (TException e1) {
+ ThriftError.showMessage(me, LOGGER, e1,
+ "Upload der VM auf den Master-Server fehlgeschlagen");
+ }
+ }
+ });
}
/**
@@ -597,7 +629,7 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout implements UiFe
lblLinkedLectureCount.setText(Integer.toString(lectureCount));
lblLinkedLectureCount.setForeground(lectureCount > 0 ? null : Color.RED);
btnShowLinkingLectures.setEnabled(lectureCount > 0);
-
+
// set the versions of the image to the table
tblVersions.setData(image.getVersions(), true);
mnuDelete.setEnabled(ImagePerms.canAdmin(image));
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java
index 1fca5e07..5e84ea98 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java
@@ -61,6 +61,7 @@ public abstract class ImageDetailsWindowLayout extends JDialog {
protected final JButton btnSaveChanges;
protected final JButton btnUpdateImage;
+ protected final JButton btnUploadToMaster;
protected final JButton btnClose;
protected final JButton btnShowLinkingLectures;
@@ -208,6 +209,8 @@ public abstract class ImageDetailsWindowLayout extends JDialog {
btnClose = new JButton("Schließen");
btnUpdateImage = new JButton("Neue VM-Version hochladen", Gui.getScaledIconResource("/img/upload-icon.png", "New VM", ICON_SIZE_Y, buttonPanel));
buttonPanel.add(btnUpdateImage);
+ btnUploadToMaster = new JButton("Landesweit veröffentlichen" /* TODO: Button image */);
+ buttonPanel.add(btnUploadToMaster);
buttonPanel.add(Box.createGlue());
// user feedback slot
lblError = new QLabel("");
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java
index 36486b8a..a6584bad 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java
@@ -157,7 +157,7 @@ public class ThriftActions {
long remoteVersion = -1;
if (client != null) {
try {
- remoteVersion = client.getVersion();
+ remoteVersion = client.getVersion(Version.VERSION);
} catch (TTransportException e) {
} catch (TException e) {
remoteVersion = 1; // Assume something old
@@ -799,8 +799,8 @@ public class ThriftActions {
questionText += "\nWollen Sie diese Version samt Veranstaltungen löschen?\n";
}
if (!matches)
- questionText = "Wollen Sie die VM-Image-Version vom " + FormatHelper.shortDate(version.createTime)
- + " Uhr wirklich löschen?";
+ questionText = "Wollen Sie die VM-Image-Version vom "
+ + FormatHelper.shortDate(version.createTime) + " Uhr wirklich löschen?";
if (!userConfirmed(frame, questionText))
return;
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 {