diff options
Diffstat (limited to 'dozentenmodulserver/src/main/java/org/openslx')
4 files changed, 87 insertions, 33 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 adf0f26c..9b6b7966 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 @@ -160,10 +160,7 @@ public class DbImage { stmt.setString("imagebaseid", imageBaseId); ResultSet rs = stmt.executeQuery(); if (!rs.next()) { - LOGGER.info("Image " + imageBaseId + " not found"); throw new TNotFoundException(); - } else { - LOGGER.info("Image " + imageBaseId + " found"); } return resultSetToSummary(rs); } @@ -211,7 +208,6 @@ public class DbImage { stmt.setString("userid", user.userId); stmt.executeUpdate(); connection.commit(); - LOGGER.info("Created image '" + imageUuid + "'"); return imageUuid; } catch (SQLException e) { LOGGER.error("Query failed in DbImage.createImage()", e); @@ -317,19 +313,29 @@ public class DbImage { * @param imageVersionId UUID of image version * @param image meta data to set * @throws SQLException + * @throws TNotFoundException */ public static void updateImageVersion(UserInfo user, String imageVersionId, ImageVersionWrite image) - throws SQLException { + throws SQLException, TNotFoundException { try (MysqlConnection connection = Database.getConnection()) { - MysqlStatement stmt = connection.prepareStatement("UPDATE imageversion v, imagebase b SET" - + " v.isenabled = :isenabled, v.isrestricted = :isrestricted," + String baseId = getBaseIdForVersionId(connection, imageVersionId); + if (baseId == null) + throw new TNotFoundException(); + // First update version table + MysqlStatement stmtVersion = connection.prepareStatement("UPDATE imageversion v SET" + + " v.isenabled = :isenabled, v.isrestricted = :isrestricted" + + " WHERE v.imageversionid = :versionid"); + stmtVersion.setString("versionid", imageVersionId); + stmtVersion.setBoolean("isenabled", image.isEnabled); + stmtVersion.setBoolean("isrestricted", image.isRestricted); + stmtVersion.executeUpdate(); + // Then base table + MysqlStatement stmtBase = connection.prepareStatement("UPDATE imagebase b SET" + " b.updaterid = :userid, b.updatetime = UNIX_TIMESTAMP()" - + " WHERE v.imageversionid = :versionid AND v.imagebaseid = b.imagebaseid"); - stmt.setString("versionid", imageVersionId); - stmt.setString("userid", user.userId); - stmt.setBoolean("isenabled", image.isEnabled); - stmt.setBoolean("isrestricted", image.isRestricted); - stmt.executeUpdate(); + + " WHERE b.imagebaseid = :baseid"); + stmtBase.setString("userid", user.userId); + stmtBase.setString("baseid", baseId); + stmtBase.executeUpdate(); connection.commit(); } catch (SQLException e) { LOGGER.error("Query failed in DbImage.updateImageVersion()", e); @@ -374,7 +380,9 @@ public class DbImage { } } - public static void createImageVersion(String imageBaseId, String imageVersionId, UserInfo owner, long fileSize, String filePath, ImageVersionWrite versionSettings, ChunkList chunks) throws SQLException { + public static void createImageVersion(String imageBaseId, String imageVersionId, UserInfo owner, + long fileSize, String filePath, ImageVersionWrite versionSettings, ChunkList chunks, + byte[] machineDescription) throws SQLException { try (MysqlConnection connection = Database.getConnection()) { final long nowSecs = System.currentTimeMillis() / 1000; MysqlStatement stmt = connection.prepareStatement("INSERT INTO imageversion" @@ -395,7 +403,7 @@ public class DbImage { stmt.setBoolean("isvalid", true); // TODO stmt.setBoolean("isprocessed", false); stmt.setBinary("mastersha1", null); // TODO - stmt.setString("virtualizerconfig", null); // TODO + stmt.setBinary("virtualizerconfig", machineDescription); stmt.executeUpdate(); // TODO: Write chunk hashes to DB connection.commit(); diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java index 08d0d30f..92c2b2d7 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java @@ -8,6 +8,7 @@ import java.nio.ByteBuffer; import java.sql.SQLException; import java.util.List; import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.log4j.Logger; import org.openslx.bwlp.sat.database.mappers.DbImage; @@ -68,10 +69,21 @@ public class ActiveUpload { */ private final String uploadId; + /** + * Description of this VM - binary dump of e.g. the *.vmx file (VMware) + */ + private final byte[] machineDescription; + + /** + * Indicated whether the version information was written to db already. + * Disallow setVersionData in that case. + */ + private final AtomicBoolean versionWrittenToDb = new AtomicBoolean(); + // TODO: Use HashList for verification public ActiveUpload(String uploadId, UserInfo owner, ImageDetailsRead image, File destinationFile, - long fileSize, List<ByteBuffer> sha1Sums) throws FileNotFoundException { + long fileSize, List<ByteBuffer> sha1Sums, byte[] machineDescription) throws FileNotFoundException { this.destinationFile = destinationFile; this.outFile = new RandomAccessFile(destinationFile, "rw"); this.chunks = new ChunkList(fileSize, sha1Sums); @@ -79,15 +91,27 @@ public class ActiveUpload { this.image = image; this.fileSize = fileSize; this.uploadId = uploadId; + this.machineDescription = machineDescription; } /** * Set meta data for this image version. * + * @param user + * * @param data */ - public synchronized void setVersionData(ImageVersionWrite data) { - versionSettings = data; + public boolean setVersionData(UserInfo user, ImageVersionWrite data) { + synchronized (versionWrittenToDb) { + if (versionWrittenToDb.get()) { + return false; + } + if (!user.userId.equals(owner.userId)) { + return false; + } + versionSettings = data; + return true; + } } /** @@ -155,9 +179,9 @@ public class ActiveUpload { * Called when the upload finished. */ private synchronized void finishUpload() { - if (state != TransferState.WORKING) - return; synchronized (outFile) { + if (state != TransferState.WORKING) + return; Util.safeClose(outFile); state = TransferState.FINISHED; } @@ -193,8 +217,11 @@ public class ActiveUpload { // Now insert meta data into DB try { - DbImage.createImageVersion(image.imageBaseId, uploadId, owner, fileSize, relPath, - versionSettings, chunks); + synchronized (versionWrittenToDb) { + DbImage.createImageVersion(image.imageBaseId, uploadId, owner, fileSize, relPath, + versionSettings, chunks, machineDescription); + versionWrittenToDb.set(true); + } } catch (SQLException e) { LOGGER.error("Error finishing upload: Inserting version to DB failed", e); state = TransferState.ERROR; @@ -271,10 +298,14 @@ public class ActiveUpload { } } - public TransferStatus getStatus() { + public synchronized TransferStatus getStatus() { return new TransferStatus(chunks.getStatusArray(), state); } + public String getId() { + return uploadId; + } + // TODO: Clean up old stale uploads } 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 3abc5f98..0869612f 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 @@ -32,8 +32,9 @@ public class FileServer implements IncomingEvent { * Listener for incoming unencrypted connections */ private final Listener plainListener = new Listener(this, null, 9092, Constants.TRANSFER_TIMEOUT); // TODO: Config - - private final ThreadPoolExecutor transferPool = new ThreadPoolExecutor(2, Constants.MAX_UPLOADS + Constants.MAX_DOWNLOADS, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(1)); + + private final ThreadPoolExecutor transferPool = new ThreadPoolExecutor(2, Constants.MAX_UPLOADS + + Constants.MAX_DOWNLOADS, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(1)); /** * All currently running uploads, indexed by token @@ -84,8 +85,8 @@ public class FileServer implements IncomingEvent { return uploads.get(uploadToken); } - public String createNewUserUpload(UserInfo owner, ImageDetailsRead image, long fileSize, List<ByteBuffer> sha1Sums) - throws TTransferRejectedException { + public ActiveUpload createNewUserUpload(UserInfo owner, ImageDetailsRead image, long fileSize, + List<ByteBuffer> sha1Sums, byte[] machineDescription) throws TTransferRejectedException { Iterator<ActiveUpload> it = uploads.values().iterator(); int activeUploads = 0; while (it.hasNext()) { @@ -109,14 +110,14 @@ public class FileServer implements IncomingEvent { String key = UUID.randomUUID().toString(); ActiveUpload upload; try { - upload = new ActiveUpload(key, owner, image, destinationFile, fileSize, sha1Sums); + upload = new ActiveUpload(key, owner, image, destinationFile, fileSize, sha1Sums, machineDescription); } catch (FileNotFoundException e) { LOGGER.error("Could not open destination file for writing", e); throw new TTransferRejectedException("Destination file not writable!"); } uploads.put(key, upload); - return key; + return upload; } public int getPlainPort() { 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 45373ae4..0c26081b 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 @@ -68,8 +68,8 @@ public class ServerHandler implements SatelliteServer.Iface { @Override public TransferInformation requestImageVersionUpload(String userToken, String imageBaseId, long fileSize, - List<ByteBuffer> blockHashes) throws TTransferRejectedException, TAuthorizationException, - TInternalServerError, TNotFoundException { + List<ByteBuffer> blockHashes, ByteBuffer machineDescription) throws TTransferRejectedException, + TAuthorizationException, TInternalServerError, TNotFoundException, TException { UserInfo user = SessionManager.getOrFail(userToken); User.canEditBaseImageOrFail(user, imageBaseId); ImageDetailsRead image; @@ -78,8 +78,16 @@ public class ServerHandler implements SatelliteServer.Iface { } catch (SQLException e) { throw new TInternalServerError(); } - String transferId = fileServer.createNewUserUpload(user, image, fileSize, blockHashes); - return new TransferInformation(transferId, fileServer.getPlainPort(), fileServer.getSslPort()); + byte[] mDesc = machineDescription == null ? null : machineDescription.array(); + ActiveUpload transfer = fileServer.createNewUserUpload(user, image, fileSize, blockHashes, mDesc); + return new TransferInformation(transfer.getId(), fileServer.getPlainPort(), fileServer.getSslPort()); + } + + @Override + public ByteBuffer getMachineDescription(String userToken, String imageVersionId) + throws TAuthorizationException, TInternalServerError, TNotFoundException, TException { + // TODO Auto-generated method stub + return null; } @Override @@ -225,6 +233,12 @@ public class ServerHandler implements SatelliteServer.Iface { public void updateImageVersion(String userToken, String imageVersionId, ImageVersionWrite image) throws TAuthorizationException, TInternalServerError, TNotFoundException { UserInfo user = SessionManager.getOrFail(userToken); + // Special case: Version is still being uploaded, so there's no entry yet - remember for later + ActiveUpload upload = fileServer.getUploadByToken(imageVersionId); + if (upload != null && upload.setVersionData(user, image)) { + return; + } + // Normal case - version already exists User.canEditImageVersionOrFail(user, imageVersionId); try { // Do not allow editing remote images |