summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/UploadInitiator.java
diff options
context:
space:
mode:
authorSimon Rettberg2015-10-01 20:00:27 +0200
committerSimon Rettberg2015-10-01 20:00:27 +0200
commit1fd45f1ec985012179b26c8136eadf0c5ae3c2c8 (patch)
tree05f2c0065d4e837f896cd3b0668125e87a211806 /dozentenmodul/src/main/java/org/openslx/dozmod/thrift/UploadInitiator.java
parent[client] Fix escape not working in message boxes (diff)
downloadtutor-module-1fd45f1ec985012179b26c8136eadf0c5ae3c2c8.tar.gz
tutor-module-1fd45f1ec985012179b26c8136eadf0c5ae3c2c8.tar.xz
tutor-module-1fd45f1ec985012179b26c8136eadf0c5ae3c2c8.zip
[client] Start upload only when finishing wizard, add final summary page to wizard
Diffstat (limited to 'dozentenmodul/src/main/java/org/openslx/dozmod/thrift/UploadInitiator.java')
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/thrift/UploadInitiator.java241
1 files changed, 241 insertions, 0 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/UploadInitiator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/UploadInitiator.java
new file mode 100644
index 00000000..b176a5cb
--- /dev/null
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/UploadInitiator.java
@@ -0,0 +1,241 @@
+package org.openslx.dozmod.thrift;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.log4j.Logger;
+import org.apache.thrift.TException;
+import org.openslx.bwlp.thrift.iface.SatelliteStatus;
+import org.openslx.bwlp.thrift.iface.TAuthorizationException;
+import org.openslx.bwlp.thrift.iface.TTransferRejectedException;
+import org.openslx.bwlp.thrift.iface.TransferInformation;
+import org.openslx.dozmod.filetransfer.AsyncHashGenerator;
+import org.openslx.dozmod.filetransfer.UploadTask;
+import org.openslx.thrifthelper.ThriftManager;
+import org.openslx.util.QuickTimer;
+
+public class UploadInitiator {
+
+ private static final Logger LOGGER = Logger.getLogger(UploadInitiator.class);
+
+ private static final long SIZE_CHECK_EXTRA_UL = 150l * 1024l * 1024l;
+
+ public enum UploadInitState {
+ IDLE,
+ REQUESTING,
+ WAITING_FOR_SLOT,
+ UPLOAD_STARTING,
+ UPLOAD_STARTED,
+ ERROR
+ }
+
+ private final File diskFile;
+ private final long fileSize;
+ private final String imageBaseId;
+ private final ByteBuffer machineDescription;
+ private final AsyncHashGenerator hashGen;
+ private TransferInformation transferInformation = null;
+ private UploadTask uploadTask;
+ private UploadInitState initState = UploadInitState.IDLE;
+ private String errorMessage = null;
+
+ /**
+ * GUI-BLOCKING Request the upload of an image version. Returns the
+ * TransferInformation received by the server or null if the request failed.
+ * Will give user feedback about failures.
+ *
+ * @param imageBaseId uuid of the image to upload a version of
+ * @param diskFile the file to upload
+ * @param machineDescription
+ * @throws TException
+ * @throws IOException
+ */
+ public UploadInitiator(final String imageBaseId, final File diskFile, final ByteBuffer machineDescription)
+ throws WrappedException, IOException {
+ if (!diskFile.canRead())
+ throw new FileNotFoundException(diskFile.getName());
+ this.fileSize = diskFile.length();
+ SatelliteStatus status;
+ try {
+ status = ThriftManager.getSatClient().getStatus();
+ } catch (TException e1) {
+ throw new WrappedException(e1, "Konnte Status des Satelliten nicht abfragen!");
+ }
+ if (status.getAvailableStorageBytes() != -1
+ && status.getAvailableStorageBytes() < fileSize + SIZE_CHECK_EXTRA_UL) {
+ throw new IOException("Nicht genügend Speicherplatz Satelliten.\n"
+ + "Löschen Sie nicht verwendete Imageversionen oder kontaktieren sie den Administrator.");
+ }
+ this.diskFile = diskFile;
+ AsyncHashGenerator hg;
+ try {
+ hg = new AsyncHashGenerator(diskFile);
+ } catch (NoSuchAlgorithmException e) {
+ LOGGER.warn("Cannot instantiate hash generator: No error correction available!");
+ hg = null;
+ }
+ this.hashGen = hg;
+ this.machineDescription = machineDescription;
+ this.imageBaseId = imageBaseId;
+ }
+
+ public synchronized void startHashing() throws IllegalThreadStateException {
+ if (hashGen == null)
+ return;
+ hashGen.start();
+ }
+
+ public interface GotUploadTokenCallback {
+ public void fire();
+ }
+ GotUploadTokenCallback gotTokenCallback = null;
+
+ public synchronized void startUpload(GotUploadTokenCallback gotTokenCallback) {
+ if (initState != UploadInitState.IDLE)
+ throw new IllegalStateException("Upload already started");
+ this.gotTokenCallback = gotTokenCallback;
+ initState = UploadInitState.REQUESTING;
+ QuickTimer.scheduleAtFixedRate(startUploadInternal, 1, TimeUnit.SECONDS.toMillis(15));
+ }
+
+ private QuickTimer.Task startUploadInternal = new QuickTimer.Task() {
+ @Override
+ public void fire() {
+ LOGGER.debug("start upload internal");
+ try {
+ transferInformation = ThriftManager.getSatClient().requestImageVersionUpload(
+ Session.getSatelliteToken(), imageBaseId, fileSize, null, // TODO remove deprecated parameter
+ machineDescription);
+ } catch (TAuthorizationException e) {
+ errorMessage = "Upload vom Server verweigert";
+ cancelError();
+ this.cancel();
+ return;
+ } catch (TTransferRejectedException e) {
+ if (e.message != null && e.message.startsWith("Server busy")) {
+ initState = UploadInitState.WAITING_FOR_SLOT;
+ } else {
+ errorMessage = "Upload-Anfrage gescheitert!";
+ cancelError();
+ this.cancel();
+ }
+ return;
+ } catch (TException e) {
+ errorMessage = "Upload-Anfrage gescheitert!";
+ cancelError();
+ this.cancel();
+ return;
+ }
+ // Everything worked out so far
+ LOGGER.info("Version upload granted, versionId: " + transferInformation.toString());
+ if (gotTokenCallback != null) {
+ gotTokenCallback.fire();
+ }
+ if (hashGen != null) {
+ hashGen.setUploadToken(transferInformation.token);
+ }
+ initState = UploadInitState.UPLOAD_STARTING;
+ QuickTimer.scheduleAtFixedRate(launchUploadTask, 1, 100);
+ this.cancel();
+ }
+ };
+
+ /**
+ * Prepare the given file for uploading
+ *
+ * @param transferInformation transfer information to use for the upload
+ * @param hashGen hash generator for this file
+ * @param diskFile the file to upload
+ * @return UploadTask if the uploading initialized, or null if uploading
+ * failed
+ */
+ private QuickTimer.Task launchUploadTask = new QuickTimer.Task() {
+ @Override
+ public void fire() {
+ LOGGER.debug("launch upload task");
+ if (initState != UploadInitState.UPLOAD_STARTING) {
+ this.cancel();
+ return;
+ }
+ if (uploadTask == null) {
+ // do actually start the upload now
+ LOGGER.debug("Starting upload for: " + diskFile.getName());
+ try {
+ uploadTask = new UploadTask(Session.getSatelliteAddress(),
+ transferInformation.getPlainPort(), transferInformation.getToken(), diskFile);
+ } catch (FileNotFoundException e) {
+ errorMessage = "Kann VM nicht hochladen: Datei nicht gefunden\n\n"
+ + diskFile.getAbsolutePath();
+ cancelError();
+ this.cancel();
+ return;
+ }
+ Thread uploadThread = new Thread(uploadTask);
+ uploadThread.setDaemon(true);
+ uploadThread.start();
+ }
+
+ if (uploadTask.getFailCount() == 0 && uploadTask.getTransferCount() == 0
+ && !uploadTask.isCanceled()) {
+ // Still initializing, wait...
+ return;
+ }
+ if (!uploadTask.isComplete() && uploadTask.getTransferCount() == 0) {
+ // Init failed
+ errorMessage = "Aufbau der Verbindung zum Hochladen fehlgeschlagen";
+ cancelError();
+ this.cancel();
+ return;
+ }
+ // Init succeeded
+ initState = UploadInitState.UPLOAD_STARTED;
+ this.cancel();
+ }
+ };
+
+ /**
+ * Set state to cancelled and clean up
+ */
+ public synchronized void cancelError() {
+ if (initState == UploadInitState.ERROR)
+ return;
+ initState = UploadInitState.ERROR;
+ if (hashGen != null) {
+ hashGen.cancel();
+ }
+ if (uploadTask != null) {
+ uploadTask.cancel();
+ }
+ if (transferInformation != null) {
+ try {
+ ThriftManager.getSatClient().cancelUpload(transferInformation.token);
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ public UploadInitState getState() {
+ return initState;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public AsyncHashGenerator getHasher() {
+ return hashGen;
+ }
+
+ public UploadTask getUploadTask() {
+ return uploadTask;
+ }
+
+ public String getToken() {
+ return transferInformation == null ? null : transferInformation.token;
+ }
+
+}