summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src
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
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')
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/AsyncHashGenerator.java57
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java23
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java1
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java17
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ImageDetailsWindow.java28
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ImageDetailsWindowLayout.java2
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java159
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageUpdateWizard.java74
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java86
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java2
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadSummaryPageLayout.java46
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureRestrictionPageLayout.java15
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java41
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadSummaryPage.java138
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java16
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/thrift/GuiErrorCallback.java15
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java196
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/thrift/UploadInitiator.java241
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/thrift/WrappedException.java15
19 files changed, 810 insertions, 362 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/AsyncHashGenerator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/AsyncHashGenerator.java
index f53d5d0b..83fbb212 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/AsyncHashGenerator.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/AsyncHashGenerator.java
@@ -23,7 +23,7 @@ public class AsyncHashGenerator extends Thread {
private static final Logger LOGGER = Logger.getLogger(AsyncHashGenerator.class);
- private final String uploadToken;
+ private String uploadToken = null;
private final RandomAccessFile file;
private final List<ByteBuffer> blockHashes;
private final MessageDigest digester;
@@ -32,9 +32,7 @@ public class AsyncHashGenerator extends Thread {
private volatile boolean isCanceled = false;
- public AsyncHashGenerator(String uploadToken, File uploadFile) throws FileNotFoundException,
- NoSuchAlgorithmException {
- this.uploadToken = uploadToken;
+ public AsyncHashGenerator(File uploadFile) throws FileNotFoundException, NoSuchAlgorithmException {
try {
digester = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e1) {
@@ -54,6 +52,13 @@ public class AsyncHashGenerator extends Thread {
setName("HashGenerator");
}
+ public void setUploadToken(String token) {
+ if (!isCanceled && this.uploadToken == null) {
+ this.uploadToken = token;
+ submitHashes();
+ }
+ }
+
@Override
public void run() {
Checker checker = new Checker();
@@ -92,7 +97,6 @@ public class AsyncHashGenerator extends Thread {
}
} finally {
Util.safeClose(file);
- LOGGER.debug("AsyncHashGenerator done");
}
}
@@ -147,20 +151,16 @@ public class AsyncHashGenerator extends Thread {
isCanceled = true;
break;
}
- blockHashes.add(ByteBuffer.wrap(hash));
- LOGGER.debug("blockIndex=" + blockIndex + ", list.size()=" + list.size());
- if (blockIndex <= 5 || blockIndex % 20 == 0 || blockIndex + 1 == list.size()) {
- try {
- ThriftManager.getSatClient().updateBlockHashes(uploadToken, blockHashes);
- } catch (TInvalidTokenException e) {
- LOGGER.warn("Cannot send hashList to satellite: Sat claims uploadToken is invalid!");
- isCanceled = true;
+ synchronized (blockHashes) {
+ blockHashes.add(ByteBuffer.wrap(hash));
+ }
+ if (blockIndex % 20 == 0 || blockIndex + 1 == list.size()) {
+ if (!submitHashes())
break;
- } catch (TException e) {
- LOGGER.warn("Unknown exception when submitting hashList to sat", e);
- }
- if (blockIndex + 1 == list.size())
+ if (blockIndex + 1 == list.size()) {
+ LOGGER.debug("Hashing done");
break;
+ }
}
}
} catch (InterruptedException e) {
@@ -168,9 +168,30 @@ public class AsyncHashGenerator extends Thread {
interrupt();
} finally {
thisGenerator.interrupt();
- LOGGER.debug("Hasher done");
}
}
}
+ /**
+ * Submit current list of hashes.
+ *
+ * @return false if the token is not known to the server
+ */
+ private boolean submitHashes() {
+ synchronized (blockHashes) {
+ if (uploadToken == null) // No token yet, cannot submit
+ return true;
+ try {
+ ThriftManager.getSatClient().updateBlockHashes(uploadToken, blockHashes);
+ } catch (TInvalidTokenException e) {
+ LOGGER.warn("Cannot send hashList to satellite: Sat claims uploadToken is invalid!");
+ isCanceled = true;
+ return false;
+ } catch (TException e) {
+ LOGGER.warn("Unknown exception when submitting hashList to sat", e);
+ }
+ return true;
+ }
+ }
+
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
index b5844630..66e2fa60 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
@@ -257,7 +257,8 @@ public class Gui {
* Generic helper to show a message box to the user, and optionally log the
* message to the log file.
*
- * @param parent partent window (used for positioning)
+ * @param parent partent window (used for positioning/modality). If null,
+ * the active window will be used
* @param message Message to display. Can be multi line.
* @param messageType Type of message (warning, information)
* @param logger Logger instance to log to. Can be null.
@@ -278,9 +279,10 @@ public class Gui {
}
}
- if (exception != null)
+ if (exception != null) {
message += "\n\n" + exception.getClass().getSimpleName() + "\n" + exception.getMessage() + "\n"
- + " (Siehe Logdatei)";
+ + " (Für Stack-Trace siehe Logdatei)";
+ }
if (messageType.buttons == -1) {
JOptionPane.showMessageDialog(parent, message, messageType.title, messageType.optionPaneId);
return true;
@@ -292,6 +294,21 @@ public class Gui {
}
/**
+ * Generic helper to show a message box to the user, and optionally log the
+ * message to the log file.
+ *
+ * @param message Message to display. Can be multi line.
+ * @param messageType Type of message (warning, information)
+ * @param logger Logger instance to log to. Can be null.
+ * @param exception Exception related to this message. Can be null.
+ * @return true if OK or YES was clicked, false for CANCEL/NO/(X)
+ */
+ public static boolean showMessageBox(String message, MessageType messageType, Logger logger,
+ Throwable exception) {
+ return showMessageBox(null, message, messageType, logger, exception);
+ }
+
+ /**
* Show a message box to the user asynchronously, and optionally log the
* message to the log file. This is most useful when working from another
* thread.
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
index 3577d1ba..b396b35a 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
@@ -82,6 +82,7 @@ public abstract class MainWindow {
*
* @param clazz
*/
+ @SuppressWarnings("unchecked")
public static <T extends CompositePage> T showPage(Class<T> clazz) {
if (currentPage != null) {
if (!currentPage.requestHide()) {
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java
index 0c588656..e8313120 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java
@@ -7,7 +7,6 @@ import org.apache.log4j.Logger;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.state.UploadWizardState;
-import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;
@@ -21,33 +20,27 @@ public class UploadPanel extends TransferPanel {
private final UploadPanel panel = this;
public UploadPanel(UploadWizardState state) {
- super(state.uploadTask, state.name, state.diskFile.getName());
+ super(state.upload.getUploadTask(), state.name, state.diskFile.getName());
btnClose.addActionListener(new ButtonAction());
this.state = state;
- state.uploadTask.addListener(this);
+ state.upload.getUploadTask().addListener(this);
}
private class ButtonAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
- if (!state.uploadTask.isCanceled()) {
+ if (!state.upload.getUploadTask().isCanceled()) {
if (!Gui.showMessageBox(panel, "Wollen Sie diesen Transfer wirklich abbrechen?",
MessageType.QUESTION_YESNO, null, null))
return;
- state.uploadTask.cancel();
- state.hashGen.cancel();
QuickTimer.scheduleOnce(new Task() {
@Override
public void fire() {
- try {
- ThriftManager.getSatClient().cancelUpload(state.transferInformation.getToken());
- } catch (Exception ex) {
- LOGGER.debug("Remote error while canceling upload for " + state.uuid, ex);
- }
+ state.upload.cancelError();
}
});
}
- state.uploadTask.removeListener(panel);
+ state.upload.getUploadTask().removeListener(panel);
close();
}
}
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 33c51111..e5bd99ad 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
@@ -19,11 +19,11 @@ import java.util.Map.Entry;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
-import javax.swing.RowFilter;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.apache.log4j.Logger;
+import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.ImageBaseWrite;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.ImagePermissions;
@@ -36,7 +36,6 @@ import org.openslx.bwlp.thrift.iface.UserInfo;
import org.openslx.bwlp.thrift.iface.Virtualizer;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.MainWindow;
-import org.openslx.dozmod.gui.control.table.ListTable.ListModel;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.PopupMenu;
import org.openslx.dozmod.gui.helper.UiFeedback;
@@ -49,6 +48,7 @@ import org.openslx.dozmod.thrift.Session;
import org.openslx.dozmod.thrift.ThriftActions;
import org.openslx.dozmod.thrift.ThriftActions.DeleteCallback;
import org.openslx.dozmod.thrift.ThriftActions.ImageMetaCallback;
+import org.openslx.dozmod.thrift.ThriftError;
import org.openslx.dozmod.thrift.cache.LectureCache;
import org.openslx.dozmod.thrift.cache.MetaDataCache;
import org.openslx.dozmod.thrift.cache.UserCache;
@@ -393,22 +393,26 @@ public class ImageDetailsWindow extends ImageDetailsWindowLayout implements UiFe
cboShareMode.getItemAt(cboShareMode.getSelectedIndex()));
// now trigger the actual action
if (metadataChanged) {
- if (ThriftActions.updateImageBase(JOptionPane.getFrameForComponent(me), image.getImageBaseId(),
- ibw)) {
- LOGGER.info("Successfully saved new metadata");
- metadataChanged = false;
- } else {
+ try {
+ ThriftActions.updateImageBase(image.getImageBaseId(), ibw);
+ } catch (TException e) {
+ ThriftError.showMessage(me, LOGGER, e,
+ "Konnte aktualisierte Metadaten nicht an den Server übermitteln");
return false;
}
+ LOGGER.info("Successfully saved new metadata");
+ metadataChanged = false;
}
if (permissionsChanged) {
- if (ThriftActions.writeImagePermissions(JOptionPane.getFrameForComponent(me),
- image.getImageBaseId(), customPermissions)) {
- LOGGER.info("Successfully saved new permissions");
- permissionsChanged = false;
- } else {
+ try {
+ ThriftActions.writeImagePermissions(image.getImageBaseId(), customPermissions);
+ } catch (TException e) {
+ ThriftError.showMessage(me, LOGGER, e,
+ "Konnte geänderte Berechtigungen nicht an den Server übermitteln");
return false;
}
+ LOGGER.info("Successfully saved new permissions");
+ permissionsChanged = false;
}
return true;
}
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 72670b83..3c7892c2 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
@@ -44,7 +44,7 @@ public abstract class ImageDetailsWindowLayout extends JDialog {
protected final PersonLabel lblUpdater;
protected final QLabel lblUpdateTime;
- protected final JComboBox<OperatingSystem> cboOperatingSystem;
+ protected final ComboBox<OperatingSystem> cboOperatingSystem;
protected final QLabel lblVirtualizer;
protected final JTextField txtTags;
protected final JCheckBox chkIsTemplate;
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java
index 971c0471..ed6e30da 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageCreationWizard.java
@@ -14,9 +14,12 @@ import org.openslx.dozmod.gui.helper.UiFeedback;
import org.openslx.dozmod.gui.wizard.page.ImageCustomPermissionPage;
import org.openslx.dozmod.gui.wizard.page.ImageMetaDataPage;
import org.openslx.dozmod.gui.wizard.page.ImageUploadPage;
+import org.openslx.dozmod.gui.wizard.page.ImageUploadSummaryPage;
import org.openslx.dozmod.state.UploadWizardState;
import org.openslx.dozmod.thrift.Session;
import org.openslx.dozmod.thrift.ThriftActions;
+import org.openslx.dozmod.thrift.ThriftError;
+import org.openslx.dozmod.thrift.UploadInitiator.GotUploadTokenCallback;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;
@@ -26,10 +29,12 @@ public class ImageCreationWizard extends Wizard implements UiFeedback {
private final static Logger LOGGER = Logger.getLogger(ImageCreationWizard.class);
- private final UploadWizardState uploadWizardState = new UploadWizardState();
+ private final UploadWizardState state = new UploadWizardState();
protected ImageUploadPage imageUploadPage;
protected ImageMetaDataPage imageMetaDataPage;
protected ImageCustomPermissionPage imageCustomPermissionPage;
+ private boolean baseWritten = false;
+ private boolean permissionsWritten = false;
/**
* Wizard for creating or editing an image
@@ -38,11 +43,11 @@ public class ImageCreationWizard extends Wizard implements UiFeedback {
*/
public ImageCreationWizard(Window parent) {
super(parent);
- uploadWizardState.defaultPermissions = Session.getSatelliteConfig().defaultImagePermissions;
+ state.defaultPermissions = Session.getSatelliteConfig().defaultImagePermissions;
- imageUploadPage = new ImageUploadPage(this, uploadWizardState, null);
- imageMetaDataPage = new ImageMetaDataPage(this, uploadWizardState);
- imageCustomPermissionPage = new ImageCustomPermissionPage(this, uploadWizardState);
+ imageUploadPage = new ImageUploadPage(this, state, null);
+ imageMetaDataPage = new ImageMetaDataPage(this, state);
+ imageCustomPermissionPage = new ImageCustomPermissionPage(this, state);
addPage(imageUploadPage);
addPage(imageMetaDataPage);
addPage(imageCustomPermissionPage);
@@ -59,54 +64,60 @@ public class ImageCreationWizard extends Wizard implements UiFeedback {
// we can here do all the sanity checks on the fields of UploadWizardState
// and react accordingly.
// check state
- return isStateValid();
- }
-
- @Override
- public void performFinish() {
- // push image base to satellite
- boolean pushedBase = ThriftActions.updateImageBase(JOptionPane.getFrameForComponent(this),
- uploadWizardState.uuid, imageBaseWriteFromState());
- if (!pushedBase) {
- Gui.showMessageBox(this, "Konnte die Metadaten des Images nicht auf dem Satelliten speichern!",
+ if (!isStateValid()) {
+ // TODO: Show what went wrong
+ Gui.showMessageBox(this, "Ein interner Fehler ist aufgetreten.\n\nDetails in der Logdatei.",
MessageType.ERROR, null, null);
- return;
+ return false;
}
- // push permissions to satellite if we have custom permissions
- boolean pushedPerms = false;
- if (uploadWizardState.permissionMap != null) {
- pushedPerms = ThriftActions.writeImagePermissions(JOptionPane.getFrameForComponent(this),
- uploadWizardState.uuid, uploadWizardState.permissionMap);
- if (!pushedPerms) {
- Gui.showMessageBox(this, "Konnte die Berechtigungen nicht auf dem Satelliten speichern!",
- MessageType.ERROR, null, null);
- ThriftActions.deleteImageBase(JOptionPane.getFrameForComponent(this), uploadWizardState.uuid,
- null);
- return;
+ // push image base to satellite
+ if (!baseWritten) {
+ try {
+ ThriftActions.updateImageBase(state.uuid, imageBaseWriteFromState());
+ } catch (TException e) {
+ ThriftError.showMessage(null, LOGGER, e,
+ "Konnte die Metadaten des Images nicht auf dem Satelliten speichern!");
+ return false;
}
+ baseWritten = true;
}
- // push version metadata to satellite
- boolean pushedVersion = ThriftActions.updateImageVersion(JOptionPane.getFrameForComponent(this),
- uploadWizardState.transferInformation.getToken(),
- new ImageVersionWrite(uploadWizardState.isRestricted));
- if (!pushedVersion) {
- Gui.showMessageBox(this, "Konnte die Metadaten der Version nicht auf dem Satelliten speichern!",
- MessageType.ERROR, null, null);
- ThriftActions.deleteImageBase(JOptionPane.getFrameForComponent(this), uploadWizardState.uuid,
- null);
- return;
+ // push permissions to satellite if we have custom permissions
+ if (!permissionsWritten) {
+ if (state.permissionMap != null && !state.permissionMap.isEmpty()) {
+ try {
+ ThriftActions.writeImagePermissions(state.uuid, state.permissionMap);
+ } catch (TException e) {
+ Gui.showMessageBox(this, "Konnte die Berechtigungen nicht auf dem Satelliten speichern!",
+ MessageType.ERROR, null, null);
+ ThriftActions.deleteImageBase(JOptionPane.getFrameForComponent(this), state.uuid, null);
+ return false;
+ }
+ }
+ permissionsWritten = true;
}
- // check upload state
- String successMessage = "Image erfolgreich erstellt!";
- if (!uploadWizardState.uploadTask.isComplete()) {
- // still running and all of the above worked, so success message
- if (!uploadWizardState.uploadTask.isCanceled())
- successMessage += " Der Upload läuft im Hintergrund... Verlassen Sie das Programm nicht solange es läuft.";
- } else {
- successMessage += " Der Upload ist fertig. Sie können nun eine Veranstaltung anlegen.";
- }
- Gui.showMessageBox(JOptionPane.getFrameForComponent(this), successMessage, MessageType.INFO, null, null);
+ state.upload.startUpload(new GotUploadTokenCallback() {
+ @Override
+ public void fire() {
+ // push version data
+ try {
+ ThriftActions.updateImageVersion(state.upload.getToken(), new ImageVersionWrite(
+ state.isRestricted));
+ } catch (TException e) {
+ if (state.isRestricted) {
+ Gui.showMessageBox(null, "Unerwarteter Fehler beim Setzen der Option"
+ + " 'Enthält lizenzpflichtige Software' für diese Virtuelle Maschine.",
+ MessageType.WARNING, LOGGER, e);
+ }
+ }
+ }
+ });
+ return true;
+ }
+
+ @Override
+ public WizardPage performFinish() {
+ return new ImageUploadSummaryPage(this, state, true);
}
/**
@@ -117,53 +128,53 @@ public class ImageCreationWizard extends Wizard implements UiFeedback {
*/
private boolean isStateValid() {
// debug purposes
- if (uploadWizardState.name == null || uploadWizardState.name.isEmpty()) {
+ if (state.name == null || state.name.isEmpty()) {
LOGGER.error("No name set in state!");
return false;
}
- if (uploadWizardState.description == null || uploadWizardState.description.isEmpty()) {
+ if (state.description == null || state.description.isEmpty()) {
LOGGER.error("No description set in state!");
return false;
}
- if (uploadWizardState.descriptionFile == null) {
+ if (state.descriptionFile == null) {
LOGGER.error("No description file set in state!");
return false;
} else {
- if (!uploadWizardState.descriptionFile.canRead()) {
- LOGGER.error(uploadWizardState.descriptionFile.getAbsolutePath() + " cannot be read!");
+ if (!state.descriptionFile.canRead()) {
+ LOGGER.error(state.descriptionFile.getAbsolutePath() + " cannot be read!");
return false;
}
}
- if (uploadWizardState.diskFile == null) {
+ if (state.diskFile == null) {
LOGGER.error("No disk file set in state!");
return false;
} else {
- if (!uploadWizardState.diskFile.canRead()) {
- LOGGER.error(uploadWizardState.diskFile.getAbsolutePath() + " cannot be read!");
+ if (!state.diskFile.canRead()) {
+ LOGGER.error(state.diskFile.getAbsolutePath() + " cannot be read!");
return false;
}
}
- if (uploadWizardState.selectedOs == null) {
+ if (state.selectedOs == null) {
LOGGER.error("No OS set in state!");
return false;
}
- if (!uploadWizardState.selectedOs.isSetOsId()) {
- LOGGER.error("OS has no id: " + uploadWizardState.selectedOs.toString());
+ if (!state.selectedOs.isSetOsId()) {
+ LOGGER.error("OS has no id: " + state.selectedOs.toString());
return false;
}
- if (uploadWizardState.meta == null) {
+ if (state.meta == null) {
LOGGER.error("No vm meta data set in state!");
return false;
}
- if (uploadWizardState.defaultPermissions == null) {
+ if (state.defaultPermissions == null) {
LOGGER.error("No permissions set in state!");
return false;
}
- if (uploadWizardState.shareMode == null) {
+ if (state.shareMode == null) {
LOGGER.error("No share mode set in state!");
return false;
}
- if (uploadWizardState.uuid == null) {
+ if (state.uuid == null) {
LOGGER.error("No uuid set in state!");
return false;
}
@@ -172,15 +183,14 @@ public class ImageCreationWizard extends Wizard implements UiFeedback {
private ImageBaseWrite imageBaseWriteFromState() {
// build imageBaseWrite
- return new ImageBaseWrite(uploadWizardState.name, uploadWizardState.description,
- uploadWizardState.selectedOs.getOsId(), uploadWizardState.meta.getVirtualizer().getVirtId(),
- uploadWizardState.isTemplate, uploadWizardState.defaultPermissions,
- uploadWizardState.shareMode);
+ return new ImageBaseWrite(state.name, state.description, state.selectedOs.getOsId(),
+ state.meta.getVirtualizer().getVirtId(), state.isTemplate, state.defaultPermissions,
+ state.shareMode);
}
@Override
protected boolean onCancelRequest() {
- if (uploadWizardState.uuid == null)
+ if (state.uuid == null)
return true;
boolean confirmed = Gui.showMessageBox(this, "Möchten Sie den Vorgang wirklich abbrechen?",
MessageType.QUESTION_YESNO, null, null);
@@ -188,18 +198,15 @@ public class ImageCreationWizard extends Wizard implements UiFeedback {
QuickTimer.scheduleOnce(new Task() {
@Override
public void fire() {
+ if (state.upload != null) {
+ state.upload.cancelError();
+ }
+ // As we're creating a new VM, delete base image aswell
try {
- ThriftManager.getSatClient().deleteImageBase(Session.getSatelliteToken(),
- uploadWizardState.uuid);
+ ThriftManager.getSatClient().deleteImageBase(Session.getSatelliteToken(), state.uuid);
} catch (TException e) {
LOGGER.debug("Error canceling upload on sat: ", e);
}
- if (uploadWizardState.uploadTask != null) {
- uploadWizardState.uploadTask.cancel();
- }
- if (uploadWizardState.hashGen != null) {
- uploadWizardState.hashGen.cancel();
- }
}
});
}
@@ -208,7 +215,7 @@ public class ImageCreationWizard extends Wizard implements UiFeedback {
@Override
public boolean wantConfirmQuit() {
- return uploadWizardState.uuid != null;
+ return state.uuid != null;
}
@Override
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageUpdateWizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageUpdateWizard.java
index 54b3af39..dc526f12 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageUpdateWizard.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/ImageUpdateWizard.java
@@ -2,49 +2,95 @@ package org.openslx.dozmod.gui.wizard;
import java.awt.Window;
-import javax.swing.JOptionPane;
-
import org.apache.log4j.Logger;
+import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.ImageVersionWrite;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.UiFeedback;
import org.openslx.dozmod.gui.wizard.page.ImageUploadPage;
+import org.openslx.dozmod.gui.wizard.page.ImageUploadSummaryPage;
import org.openslx.dozmod.state.UploadWizardState;
import org.openslx.dozmod.thrift.ThriftActions;
+import org.openslx.dozmod.thrift.ThriftError;
+import org.openslx.dozmod.thrift.UploadInitiator.GotUploadTokenCallback;
+import org.openslx.util.QuickTimer;
+import org.openslx.util.QuickTimer.Task;
@SuppressWarnings("serial")
public class ImageUpdateWizard extends Wizard implements UiFeedback {
private final static Logger LOGGER = Logger.getLogger(ImageCreationWizard.class);
- private final UploadWizardState uploadWizardState = new UploadWizardState();
-
+ private final UploadWizardState state = new UploadWizardState();
+
protected ImageUploadPage imageUploadPage;
+
public ImageUpdateWizard(final Window parent, final ImageDetailsRead image) {
super(parent);
-
- imageUploadPage = new ImageUploadPage(this, uploadWizardState, image);
+
+ imageUploadPage = new ImageUploadPage(this, state, image);
addPage(imageUploadPage);
}
@Override
- public void performFinish() {
- boolean ret = ThriftActions.updateImageVersion(JOptionPane.getFrameForComponent(this),
- uploadWizardState.transferInformation.getToken(),
- new ImageVersionWrite(uploadWizardState.isRestricted));
- if (!ret) {
- Gui.showMessageBox(this, "Konnte Metadaten der Version nicht am Satelliten speichern!", MessageType.INFO, null, null);
+ protected boolean wantFinish() {
+ try {
+ ThriftActions.updateImageVersion(state.upload.getToken(), new ImageVersionWrite(
+ state.isRestricted));
+ } catch (TException e) {
+ ThriftError.showMessage(null, LOGGER, e, "Serverseitiger Fehler beim Speichern der Image-Daten.");
+ return false;
+ }
+ state.upload.startUpload(new GotUploadTokenCallback() {
+ @Override
+ public void fire() {
+ // push version data
+ try {
+ ThriftActions.updateImageVersion(state.upload.getToken(), new ImageVersionWrite(
+ state.isRestricted));
+ } catch (TException e) {
+ if (state.isRestricted) {
+ Gui.showMessageBox(null, "Unerwarteter Fehler beim Setzen der Option"
+ + " 'Enthält lizenzpflichtige Software' für diese Virtuelle Maschine.",
+ MessageType.WARNING, LOGGER, e);
+ }
+ }
+ }
+ });
+ return true;
+ }
+
+ @Override
+ public WizardPage performFinish() {
+ return new ImageUploadSummaryPage(this, state, false);
+ }
+
+ @Override
+ protected boolean onCancelRequest() {
+ if (state.uuid == null)
+ return true;
+ boolean confirmed = Gui.showMessageBox(this, "Möchten Sie den Vorgang wirklich abbrechen?",
+ MessageType.QUESTION_YESNO, null, null);
+ if (confirmed && state.upload != null) {
+ QuickTimer.scheduleOnce(new Task() {
+ @Override
+ public void fire() {
+ state.upload.cancelError();
+ }
+ });
}
+ return confirmed;
}
+
@Override
public boolean wantConfirmQuit() {
- return uploadWizardState.transferInformation != null;
+ return state.upload != null;
}
@Override
public void escapePressed() {
- dispose();
+ doCancel();
}
@Override
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java
index 17aa9617..ebf82642 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/Wizard.java
@@ -22,7 +22,6 @@ import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
-import org.apache.log4j.Logger;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.control.QLabel;
import org.openslx.dozmod.gui.helper.GridManager;
@@ -30,11 +29,11 @@ import org.openslx.dozmod.gui.helper.GridManager;
@SuppressWarnings("serial")
public abstract class Wizard extends JDialog {
- private static final Logger LOGGER = Logger.getLogger(Wizard.class);
-
private final QLabel titleLabel;
private final QLabel messageLabel;
private final List<WizardPage> pages = new ArrayList<>();
+ private WizardPage postFinishPage = null;
+ private boolean isPostFinish = false;
private final JPanel contentPanel;
private int currentPage = -1;
private boolean needsLayout = true;
@@ -90,7 +89,7 @@ public abstract class Wizard extends JDialog {
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));
contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
add(contentPanel, BorderLayout.CENTER);
-
+
// Scale window with font size
setPreferredSize(Gui.getScaledDimension(550, 420));
setResizable(false);
@@ -147,22 +146,21 @@ public abstract class Wizard extends JDialog {
private void showPage(int index) {
if (currentPage != -1) {
- WizardPage old = pages.get(currentPage);
+ WizardPage old = getPage(currentPage);
old.onPageLeave();
old.setVisible(false);
}
- WizardPage page = pages.get(index);
+ WizardPage page = getPage(index);
page.onPageEnter();
page.setVisible(true);
currentPage = index;
updateHeader(page);
updateButtons(page);
validate();
-
}
void updateHeader(WizardPage page) {
- if (currentPage == -1 || pages.get(currentPage) != page)
+ if (!isPostFinish && (currentPage == -1 || getPage(currentPage) != page))
return;
String pageTitle = page.getTitle();
String pageDesc = page.getMessage();
@@ -172,7 +170,7 @@ public abstract class Wizard extends JDialog {
pageDesc = "";
titleLabel.setText(pageTitle);
messageLabel.setText(pageDesc);
- messageLabel.setIcon(page.getMessageIcon());
+ messageLabel.setIcon(page.getMessageIcon()); // TODO: Scale
messageLabel.setForeground(page.getMessageColor());
messageLabel.validate();
setTitle(getWindowTitle() + " - " + pageTitle);
@@ -188,7 +186,15 @@ public abstract class Wizard extends JDialog {
pages.add(page);
}
+ protected void addSummaryPage(WizardPage page) {
+ postFinishPage = page;
+ }
+
void updateButtons(WizardPage page) {
+ if (isPostFinish) {
+ btnFinish.setEnabled(postFinishPage.isComplete());
+ return;
+ }
// State of finish button
boolean canFinish = true;
for (WizardPage p : pages) {
@@ -199,24 +205,28 @@ public abstract class Wizard extends JDialog {
}
btnFinish.setEnabled(canFinish);
// State of next button
- if (currentPage != -1 && pages.get(currentPage) == page) {
+ if (currentPage != -1 && getPage(currentPage) == page) {
btnNext.setEnabled(currentPage + 1 < pages.size() && page.isComplete());
- btnPrev.setEnabled(currentPage > 0 && pages.get(currentPage - 1).canComeBack);
+ btnPrev.setEnabled(currentPage > 0 && getPage(currentPage - 1).canComeBack);
}
}
+ protected final boolean isSummaryPage() {
+ return isPostFinish;
+ }
+
protected final void doNext() {
- if (!btnNext.isEnabled())
+ if (isPostFinish || !btnNext.isEnabled())
return;
if (currentPage + 1 < pages.size()) {
- if (!pages.get(currentPage).wantNextOrFinish())
+ if (!getPage(currentPage).wantNextOrFinish())
return; // Page canceled the operation
showPage(currentPage + 1);
}
}
protected final void doPrevious() {
- if (!btnPrev.isEnabled())
+ if (isPostFinish || !btnPrev.isEnabled())
return;
if (currentPage > 0) {
showPage(currentPage - 1);
@@ -224,26 +234,54 @@ public abstract class Wizard extends JDialog {
}
protected final void doCancel() {
- if (onCancelRequest())
+ if (onCancelRequest()) {
+ if (currentPage != -1) {
+ getPage(currentPage).onPageLeave();
+ }
+ if (isPostFinish) {
+ postFinishPage.onPageLeave();
+ }
dispose();
+ }
}
protected final void doFinish() {
+ if (isPostFinish) {
+ postFinishPage.onPageLeave();
+ dispose();
+ return;
+ }
if (!btnFinish.isEnabled())
return;
if (currentPage != -1) {
- if (!pages.get(currentPage).wantNextOrFinish())
+ if (!getPage(currentPage).wantNextOrFinish())
return;
}
if (wantFinish()) {
if (currentPage != -1) {
- pages.get(currentPage).onPageLeave();
+ getPage(currentPage).onPageLeave();
+ }
+ postFinishPage = performFinish();
+ if (postFinishPage == null) {
+ dispose();
+ } else {
+ isPostFinish = true;
+ btnPrev.setVisible(false);
+ btnNext.setVisible(false);
+ btnFinish.setText("Schließen");
+ postFinishPage.setVisible(false);
+ contentPanel.add(postFinishPage);
+ showPage(-1);
}
- performFinish();
- dispose();
}
}
+ private WizardPage getPage(int index) {
+ if (isPostFinish && index == -1)
+ return postFinishPage;
+ return pages.get(index);
+ }
+
/*
* Callback to wizard implementation
*/
@@ -273,9 +311,15 @@ public abstract class Wizard extends JDialog {
* Called so the wizard can perform finishing steps. This is called after
* wantFinish() returned true and onPageLeave was called on the currently
* visible wizard step.
+ * If a wizard page is returned, it will serve as a summary page shown to
+ * the user within the wizard frame. The prev and next buttons will
+ * disappear, and the finish button will change to a close button.
+ *
+ * @return A wizard page that serves as a summary page, or null if the
+ * wizard should just close
*/
- protected void performFinish() {
- // void
+ protected WizardPage performFinish() {
+ return null;
}
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java
index ec77de90..9c5044f4 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/WizardPage.java
@@ -101,6 +101,8 @@ public abstract class WizardPage extends JPanel {
*/
protected void setPageComplete(boolean b) {
+ if (isComplete == b)
+ return;
isComplete = b;
if (wizard != null)
wizard.updateButtons(this);
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadSummaryPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadSummaryPageLayout.java
new file mode 100644
index 00000000..930d5e16
--- /dev/null
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadSummaryPageLayout.java
@@ -0,0 +1,46 @@
+package org.openslx.dozmod.gui.wizard.layout;
+
+import javax.swing.Box;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+
+import org.openslx.dozmod.gui.control.BlockProgressBar;
+import org.openslx.dozmod.gui.helper.GridManager;
+import org.openslx.dozmod.gui.wizard.Wizard;
+import org.openslx.dozmod.gui.wizard.WizardPage;
+
+@SuppressWarnings("serial")
+public class ImageUploadSummaryPageLayout extends WizardPage {
+
+ protected final BlockProgressBar progressBar;
+ protected final JCheckBox chkCreateLecture;
+ protected final JLabel infoText;
+
+ public ImageUploadSummaryPageLayout(Wizard wizard, boolean allowCreateLecture) {
+ super(wizard, "Fertig!");
+ setDescription("Assistent abgeschlossen");
+ GridManager grid = new GridManager(this, 1);
+
+ progressBar = new BlockProgressBar(null);
+ grid.add(progressBar).expand(true, false).fill(true, false);
+ grid.nextRow();
+
+ grid.add(Box.createVerticalStrut(16));
+ grid.nextRow();
+
+ infoText = new JLabel();
+ grid.add(infoText).expand(true, false).fill(true, false);
+ grid.nextRow();
+
+ grid.add(Box.createVerticalGlue()).expand(true, true);
+ grid.nextRow();
+
+ chkCreateLecture = new JCheckBox("Veranstaltung zu dieser VM erstellen");
+ chkCreateLecture.setVisible(allowCreateLecture);
+ grid.add(chkCreateLecture);
+ grid.nextRow();
+
+ grid.finish(false);
+ }
+
+}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureRestrictionPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureRestrictionPageLayout.java
new file mode 100644
index 00000000..431d20e3
--- /dev/null
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/LectureRestrictionPageLayout.java
@@ -0,0 +1,15 @@
+package org.openslx.dozmod.gui.wizard.layout;
+
+import org.openslx.dozmod.gui.wizard.Wizard;
+import org.openslx.dozmod.gui.wizard.WizardPage;
+
+@SuppressWarnings("serial")
+public class LectureRestrictionPageLayout extends WizardPage {
+
+ public LectureRestrictionPageLayout(Wizard wizard) {
+ super(wizard, "Beschränkungen");
+
+
+ }
+
+}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
index a32656b4..d6f8c6aa 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
@@ -17,14 +17,15 @@ import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.gui.Gui;
-import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.QFileChooser;
import org.openslx.dozmod.gui.wizard.Wizard;
import org.openslx.dozmod.gui.wizard.layout.ImageUploadPageLayout;
import org.openslx.dozmod.state.UploadWizardState;
import org.openslx.dozmod.thrift.ThriftActions;
-import org.openslx.dozmod.thrift.ThriftActions.InitUploadStatus;
+import org.openslx.dozmod.thrift.ThriftError;
+import org.openslx.dozmod.thrift.UploadInitiator;
+import org.openslx.dozmod.thrift.WrappedException;
import org.openslx.dozmod.thrift.cache.MetaDataCache;
import org.openslx.util.vm.VmMetaData.HardDisk;
import org.openslx.util.vm.VmwareMetaData;
@@ -183,32 +184,22 @@ public class ImageUploadPage extends ImageUploadPageLayout {
} else {
state.uuid = existingImage.getImageBaseId();
}
- // -- request upload for that uuid --
- if (state.transferInformation == null) {
- state.transferInformation = ThriftActions.requestVersionUpload(
- JOptionPane.getFrameForComponent(this), state.uuid, state.diskFile.length(), null,
- state.meta.getFilteredDefinition());
- if (state.transferInformation == null)
+ // Create upload initiator that will manage requesting a token, hashing the file, connecting for upload...
+ if (state.upload == null) {
+ try {
+ state.upload = new UploadInitiator(state.uuid, state.diskFile,
+ state.meta.getFilteredDefinition());
+ } catch (WrappedException e) {
+ ThriftError.showMessage(this, LOGGER, e.exception, e.displayMessage);
+ return false;
+ } catch (IOException e) {
+ Gui.showMessageBox(this, "Upload-Initialisierung fehlgeschlagen", MessageType.ERROR, LOGGER,
+ e);
return false;
- }
- // -- start uploading our diskFile with the transfer information we just received --
- if (state.uploadTask == null) {
- InitUploadStatus ret = ThriftActions.initUpload(JOptionPane.getFrameForComponent(this),
- state.transferInformation, state.diskFile);
- if (ret != null) {
- if (ret.task == null) {
- return false;
- } else {
- state.uploadTask = ret.task;
- }
- if (ret.hasher == null) {
- return false;
- } else {
- state.hashGen = ret.hasher;
- }
}
}
- MainWindow.addUpload(state);
+ // Start the hash check now
+ state.upload.startHashing();
return true;
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadSummaryPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadSummaryPage.java
new file mode 100644
index 00000000..8c7d653d
--- /dev/null
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadSummaryPage.java
@@ -0,0 +1,138 @@
+package org.openslx.dozmod.gui.wizard.page;
+
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.thrift.iface.TransferState;
+import org.openslx.dozmod.filetransfer.TransferEvent;
+import org.openslx.dozmod.filetransfer.TransferEventListener;
+import org.openslx.dozmod.gui.Gui;
+import org.openslx.dozmod.gui.MainWindow;
+import org.openslx.dozmod.gui.wizard.Wizard;
+import org.openslx.dozmod.gui.wizard.layout.ImageUploadSummaryPageLayout;
+import org.openslx.dozmod.state.UploadWizardState;
+import org.openslx.dozmod.thrift.UploadInitiator.UploadInitState;
+import org.openslx.util.QuickTimer;
+
+@SuppressWarnings("serial")
+public class ImageUploadSummaryPage extends ImageUploadSummaryPageLayout {
+
+ private static final Logger LOGGER = Logger.getLogger(ImageUploadSummaryPage.class);
+
+ private boolean pageIsVisible = false;
+ private boolean uploadListenerAdded = false;
+ private final UploadWizardState state;
+
+ private final TransferEventListener uploadListener = new TransferEventListener() {
+ @Override
+ public void update(TransferEvent event) {
+ LOGGER.debug("update transfer event");
+ if (!pageIsVisible)
+ return;
+ if (event.progress != null) {
+ progressBar.setStatus(event.progress);
+ if (event.state == TransferState.FINISHED) {
+ updateInfoText(null);
+ state.upload.getUploadTask().removeListener(uploadListener);
+ }
+ }
+ }
+ };
+
+ private final QuickTimer.Task updateHelpText = new QuickTimer.Task() {
+ private UploadInitState lastInitState = null;
+
+ @Override
+ public void fire() {
+ LOGGER.debug("update help text");
+ if (!pageIsVisible) {
+ this.cancel();
+ return;
+ }
+ if (!uploadListenerAdded && state.upload.getUploadTask() != null) {
+ uploadListenerAdded = true;
+ state.upload.getUploadTask().addListener(uploadListener);
+ }
+ UploadInitState initState = state.upload.getState();
+ if (initState != lastInitState) {
+ lastInitState = initState;
+ updateInfoText(initState);
+ }
+ if (lastInitState == UploadInitState.UPLOAD_STARTED || lastInitState == UploadInitState.ERROR) {
+ this.cancel();
+ }
+ }
+ };
+
+ private void updateInfoText(final UploadInitState initState) {
+ String text;
+ if (state.upload.getUploadTask() != null && state.upload.getUploadTask().isComplete()) {
+ text = "Die Virtuelle Maschine wurde erfolgreich auf den Server hochgeladen.";
+ } else if (initState == null) {
+ return;
+ } else {
+ switch (initState) {
+ case ERROR:
+ text = "Die Initialisierung des Uploads auf den Server ist fehlgeschlagen."
+ + " Sie können versuchen, den Vorgang erneut zu starten."
+ + " Falls das Problem weiterhin besteht,"
+ + " kontaktieren Sie den bwLehrpool-Support Ihrer Einrichtung.";
+ if (state.upload.getErrorMessage() != null) {
+ text += "<br><br>Weitere Informationen:<br>" + state.upload.getErrorMessage();
+ }
+ break;
+ case REQUESTING:
+ text = "Der Upload-Vorgang wird mit dem Server ausgehandelt...";
+ break;
+ case UPLOAD_STARTED:
+ text = "Der Upload Ihrer Virtuellen Maschine wurde gestartet."
+ + " Wenn Sie möchten, können Sie diesen Assistenten schließen,"
+ + " und die Anwendung weiterverwenden."
+ + " Die Übertragung läuft dabei im Hintergrund weiter.";
+ break;
+ case UPLOAD_STARTING:
+ text = "Die Verbindung zur Übertragung der VM wird aufgebaut...";
+ break;
+ case WAITING_FOR_SLOT:
+ text = "Der Server ist zur Zeit überlastet, da zu viele Uploads gleichzeitig laufen."
+ + " Es wird gewartet, bis der Server wieder Kapazitäten frei hat."
+ + " Bitte schließen Sie dieses Fenster nicht.";
+ break;
+ default:
+ return;
+ }
+ }
+ final String t = text;
+ Gui.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ infoText.setText("<html><body style ='width:100%'>" + t + "</body></html>");
+ setPageComplete(initState == UploadInitState.UPLOAD_STARTED);
+ }
+ });
+ }
+
+ public ImageUploadSummaryPage(Wizard wizard, UploadWizardState state, boolean allowCreateLecture) {
+ super(wizard, allowCreateLecture);
+ this.state = state;
+ setPageComplete(false);
+ }
+
+ @Override
+ protected void onPageEnter() {
+ if (pageIsVisible)
+ return;
+ pageIsVisible = true;
+ QuickTimer.scheduleAtFixedDelay(updateHelpText, 1, 3000);
+ }
+
+ @Override
+ protected void onPageLeave() {
+ if (!pageIsVisible)
+ return;
+ pageIsVisible = false;
+ state.upload.getUploadTask().removeListener(uploadListener);
+ if (!state.upload.getUploadTask().isCanceled()) {
+ MainWindow.addUpload(state);
+ }
+ }
+
+}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java b/dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java
index c340f562..3cb6f2f3 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/state/UploadWizardState.java
@@ -6,10 +6,8 @@ import java.util.Map;
import org.openslx.bwlp.thrift.iface.ImagePermissions;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.bwlp.thrift.iface.ShareMode;
-import org.openslx.bwlp.thrift.iface.TransferInformation;
-import org.openslx.dozmod.filetransfer.AsyncHashGenerator;
-import org.openslx.dozmod.filetransfer.UploadTask;
import org.openslx.dozmod.thrift.Session;
+import org.openslx.dozmod.thrift.UploadInitiator;
import org.openslx.util.vm.VmMetaData;
public class UploadWizardState {
@@ -42,20 +40,12 @@ public class UploadWizardState {
// -- Objects returned by thrift calls --
// UUID given returned by the satellite after creating the image
public String uuid = null;
- // transfer information for upload received if the upload request was granted
- public TransferInformation transferInformation = null;
- /**
- * The upload task representing this new VM
- */
- public UploadTask uploadTask = null;
+
+ public UploadInitiator upload = null;
/**
* Meta data (description file content) of this VM
*/
public VmMetaData meta = null;
- /**
- * Hash calculator
- */
- public AsyncHashGenerator hashGen;
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/GuiErrorCallback.java b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/GuiErrorCallback.java
index 11c3c3da..26e11504 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/GuiErrorCallback.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/GuiErrorCallback.java
@@ -25,23 +25,26 @@ public class GuiErrorCallback implements ErrorCallback {
@Override
public boolean thriftError(int failCount, final String method, final Throwable t) {
// if it's not a transport exception, do not retry
- if (!(t instanceof TTransportException))
+ if (t != null && !(t instanceof TTransportException))
return false;
- final TTransportException tex = (TTransportException) t;
// if it's the first fail, retry immediately
if (failCount == 1)
return true;
// Some methods are non-critical, so don't show a pop-up
if (ThriftError.failSilently(method))
- return false;
+ return failCount == 2; // As it's silent, give it a second try...
// Otherwise, ask user if we should retry
+ final TTransportException tex = (TTransportException) t;
return Gui.syncExec(new GuiCallable<Boolean>() {
@Override
public Boolean run() {
+ String errMsg = null;
+ if (tex != null) {
+ errMsg = " (Fehler " + tex.getType() + ")";
+ }
return Gui.showMessageBox(parent, "Die Kommunikation mit " + serverString + " ist"
- + " gestört. Der Aufruf der Funktion " + method + " ist fehlgeschlagen (Fehler "
- + tex.getType() + ").\n\n" + "Möchten Sie den Aufruf wiederholen?",
- MessageType.ERROR_RETRY, LOGGER, t);
+ + " gestört. Der Aufruf der Funktion " + method + " ist fehlgeschlagen" + errMsg
+ + ".\n\n" + "Möchten Sie den Aufruf wiederholen?", MessageType.ERROR_RETRY, LOGGER, t);
}
});
}
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 a1711990..d22bf39c 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java
@@ -5,8 +5,6 @@ import java.awt.Window;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -28,6 +26,7 @@ import org.openslx.bwlp.thrift.iface.Satellite;
import org.openslx.bwlp.thrift.iface.SatelliteServer.Client;
import org.openslx.bwlp.thrift.iface.TAuthorizationException;
import org.openslx.bwlp.thrift.iface.TInvocationException;
+import org.openslx.bwlp.thrift.iface.TNotFoundException;
import org.openslx.bwlp.thrift.iface.TransferInformation;
import org.openslx.bwlp.thrift.iface.TransferState;
import org.openslx.bwlp.thrift.iface.UserInfo;
@@ -36,11 +35,9 @@ import org.openslx.dozmod.App;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.Config.SavedSession;
import org.openslx.dozmod.authentication.Authenticator.AuthenticationData;
-import org.openslx.dozmod.filetransfer.AsyncHashGenerator;
import org.openslx.dozmod.filetransfer.DownloadTask;
import org.openslx.dozmod.filetransfer.TransferEvent;
import org.openslx.dozmod.filetransfer.TransferEventListener;
-import org.openslx.dozmod.filetransfer.UploadTask;
import org.openslx.dozmod.gui.GraphicalCertHandler;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.MainWindow;
@@ -58,7 +55,6 @@ import org.openslx.sat.thrift.version.Version;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;
-import org.openslx.util.Util;
import org.openslx.util.vm.DiskImage;
import org.openslx.util.vm.DiskImage.UnknownImageFormatException;
@@ -66,7 +62,6 @@ public class ThriftActions {
private static final Logger LOGGER = Logger.getLogger(ThriftActions.class);
private static final long SIZE_CHECK_EXTRA_DL = 50l * 1024l * 1024l;
- private static final long SIZE_CHECK_EXTRA_UL = 150l * 1024l * 1024l;
/* *******************************************************************************
*
@@ -74,8 +69,7 @@ public class ThriftActions {
*
* Login methods
*
- * **************************************************************************
- * ****
+ * *******************************************************************************
*/
/**
* @param window the parentWindow
@@ -108,7 +102,9 @@ public class ThriftActions {
} else {
if (data.satellites.isEmpty()) {
Gui.asyncMessageBox("Login erfolgreich, aber es wurde kein Satellit-Server gefunden.\n"
- + " Bitte geben Sie die Adresse Ihres Satelliten an.", MessageType.ERROR, LOGGER, null);}
+ + " Bitte geben Sie die Adresse Ihres Satelliten an.", MessageType.ERROR, LOGGER,
+ null);
+ }
sat = SatelliteListWindow.open(window, data.satellites);
}
@@ -137,7 +133,7 @@ public class ThriftActions {
Gui.asyncMessageBox(
"Authentifizierung erfolgreich, die Verbindung zum Satelliten-Server ist jedoch nicht möglich.\n\n"
+ "Möglicherweise ist der Server nicht verfügbar, oder die Netzwerkverbindung gestört.",
- MessageType.ERROR, null, null);
+ MessageType.ERROR, null, null);
}
return false;
}
@@ -167,7 +163,7 @@ public class ThriftActions {
Gui.asyncMessageBox(
"Authentifizierung erfolgreich, der Satellit verweigert jedoch die Verbindung.\n\n"
+ "Grund: " + e.number.toString() + " (" + e.message + ")",
- MessageType.ERROR, null, null);
+ MessageType.ERROR, null, null);
}
return false;
} catch (TInvocationException e) {
@@ -213,8 +209,7 @@ public class ThriftActions {
*
* Creates a base image with the given name
*
- * **************************************************************************
- * ****
+ * *******************************************************************************
*/
/**
* GUI-BLOCKING Creates the image with the given name. Returns the uuid
@@ -240,39 +235,34 @@ public class ThriftActions {
* GUI-BLOCKING Pushes a new image base to the server with the given
* imageBaseId and the meta information in meta
*
- * @param frame to show user feedback on
* @param imageBaseId image's id we are writing meta information of
* @param meta actual meta information as ImageBaseWrite
+ * @throws TException
+ * @throws TInvocationException
+ * @throws TNotFoundException
+ * @throws TAuthorizationException
*/
- public static boolean updateImageBase(final Frame frame, final String imageBaseId,
- final ImageBaseWrite meta) {
- try {
- ThriftManager.getSatClient().updateImageBase(Session.getSatelliteToken(), imageBaseId, meta);
- } catch (TException e) {
- ThriftError.showMessage(frame, LOGGER, e, "Konnte Metadaten des Images nicht übertragen");
- return false;
- }
- return true;
+ public static void updateImageBase(final String imageBaseId, final ImageBaseWrite meta)
+ throws TAuthorizationException, TNotFoundException, TInvocationException, TException {
+ ThriftManager.getSatClient().updateImageBase(Session.getSatelliteToken(), imageBaseId, meta);
}
/**
* GUI-BLOCKING Pushes the given permission map as custom permission for the
* given imageBaseId
*
- * @param frame to show user feedback on
* @param imageBaseId image's id we are writing permissions of
* @param permissions actual permissions map to write
+ * @throws TException
+ * @throws TInvocationException
+ * @throws TNotFoundException
+ * @throws TAuthorizationException
*/
- public static boolean writeImagePermissions(final Frame frame, final String imageBaseId,
- final Map<String, ImagePermissions> permissions) {
- try {
- ThriftManager.getSatClient().writeImagePermissions(Session.getSatelliteToken(), imageBaseId,
- permissions);
- } catch (TException e) {
- ThriftError.showMessage(frame, LOGGER, e, "Konnte Berechtigungen nicht übertragen");
- return false;
- }
- return true;
+ public static void writeImagePermissions(final String imageBaseId,
+ final Map<String, ImagePermissions> permissions) throws TAuthorizationException,
+ TNotFoundException, TInvocationException, TException {
+ ThriftManager.getSatClient().writeImagePermissions(Session.getSatelliteToken(), imageBaseId,
+ permissions);
}
/* *******************************************************************************
@@ -283,124 +273,23 @@ public class ThriftActions {
* steps: - requestVersionUpload(..) to request the upload at the server -
* initUpload(..) to actually start the upload of the file
*
- * **************************************************************************
- * ****
+ * ******************************************************************************
*/
- /**
- * 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 frame caller of this method
- * @param imageBaseId uuid of the image to upload a version of
- * @param fileSize size in bytes(?) of the uploaded file
- * @param blockHashes
- * @param machineDescription
- * @param callback
- * @return TransferInformation received by the server, null if the request
- * failed.
- */
- public static TransferInformation requestVersionUpload(final Frame frame, final String imageBaseId,
- final long fileSize, final List<ByteBuffer> blockHashes, final ByteBuffer machineDescription) {
- try {
- if (ThriftManager.getSatClient().getStatus().getAvailableStorageBytes() < fileSize
- + SIZE_CHECK_EXTRA_UL) {
- Gui.showMessageBox(
- frame,
- "Nicht genügend Speicherplatz Satelliten. Löschen Sie nicht verwendete Imageversionen oder kontaktieren sie den Administrator.",
- MessageType.ERROR, LOGGER, null);
- return null;
- }
- } catch (TException e1) {
- ThriftError.showMessage(frame, LOGGER, e1, "Konnte Status des Satelliten nicht abfragen!");
- return null;
- }
- TransferInformation ti = null;
- try {
- ti = ThriftManager.getSatClient().requestImageVersionUpload(Session.getSatelliteToken(),
- imageBaseId, fileSize, null, // TODO remove deprecated parameter
- machineDescription);
- LOGGER.info("Version upload granted, versionId: '" + ti.toString());
- } catch (TAuthorizationException e) {
- ThriftError.showMessage(frame, LOGGER, e, "Upload einer neuen Version nicht erlaubt!");
- } catch (TException e) {
- ThriftError.showMessage(frame, LOGGER, e, "Upload-Anfrage gescheitert!");
- }
- return ti;
- }
/**
- * GUI-BLOCKING Starts uploading the given diskFile using the
- * transferInformation and hashGen
- *
- * @param frame caller of this method
- * @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
- */
- public static InitUploadStatus initUpload(final Frame frame,
- final TransferInformation transferInformation, final File diskFile) {
- UploadTask uploadTask = null;
- // do actually start the upload now
- LOGGER.debug("Starting upload for: " + diskFile.toPath());
- try {
- uploadTask = new UploadTask(Session.getSatelliteAddress(), transferInformation.getPlainPort(),
- transferInformation.getToken(), diskFile);
- } catch (FileNotFoundException e) {
- Gui.asyncMessageBox(
- "Kann VM nicht hochladen: Datei nicht gefunden\n\n" + diskFile.getAbsolutePath(),
- MessageType.ERROR, LOGGER, e);
- return null;
- }
- AsyncHashGenerator hashGen = null;
- try {
- hashGen = new AsyncHashGenerator(transferInformation.token, diskFile);
- hashGen.start();
- Util.sleep(50);// A little ugly... Give the hash generator a head
- // start
- } catch (FileNotFoundException | NoSuchAlgorithmException e) {
- Gui.showMessageBox(frame, "Kann keine Block-Hashes für den Upload berechnen, "
- + "automatische Fehlerkorrektur deaktiviert.", MessageType.WARNING, LOGGER, e);
- }
- Util.sleep(50); // A little ugly... Give the hash generator a head start
- Thread uploadThread = new Thread(uploadTask);
- uploadThread.setDaemon(true);
- uploadThread.start();
- do { // Even more ugly - block the GUI thread so we know whether the
- // upload started, and only then switch to the next page
- Util.sleep(5);
- } while (uploadTask.getFailCount() == 0 && uploadTask.getTransferCount() == 0
- && !uploadTask.isCanceled());
-
- if (uploadTask.getTransferCount() == 0) {
- Gui.asyncMessageBox("Aufbau der Verbindung zum Hochladen fehlgeschlagen", MessageType.ERROR,
- LOGGER, null);
- hashGen.cancel();
- uploadTask.cancel();
- uploadTask = null;
- }
- return new InitUploadStatus(uploadTask, hashGen);
- }
-
- /**
- * GUI-BLOCKING Gives user feedback TODO
+ * GUI-BLOCKING
*
* @param frame
* @param transferInformation
* @param versionInfo
+ * @throws TException
+ * @throws TInvocationException
+ * @throws TNotFoundException
+ * @throws TAuthorizationException
*/
- public static boolean updateImageVersion(final Frame frame, final String versionId,
- final ImageVersionWrite versionInfo) {
- try {
- ThriftManager.getSatClient().updateImageVersion(Session.getSatelliteToken(), versionId,
- versionInfo);
- } catch (TException e) {
- Gui.showMessageBox(frame, "Konnte neue Version nicht erstellen!", MessageType.ERROR, LOGGER, e);
- return false;
- }
- return true;
+ public static void updateImageVersion(final String versionId, final ImageVersionWrite versionInfo)
+ throws TAuthorizationException, TNotFoundException, TInvocationException, TException {
+ ThriftManager.getSatClient().updateImageVersion(Session.getSatelliteToken(), versionId, versionInfo);
}
/* *******************************************************************************
@@ -411,8 +300,7 @@ public class ThriftActions {
* 'DownloadCallback' and the actual static method 'initDownload' to start
* the download.
*
- * **************************************************************************
- * ****
+ * *******************************************************************************
*/
/**
* The callback interface to inform the GUI about the status of the
@@ -548,7 +436,7 @@ public class ThriftActions {
Gui.asyncMessageBox(
"Zur heruntergeladenen VM konnte keine vmx-Datei angelegt werden."
+ "\nSie können versuchen, das Abbild manuell in den VMWare-Player zu importieren.",
- MessageType.WARNING, LOGGER, e);
+ MessageType.WARNING, LOGGER, e);
}
}
});
@@ -1140,18 +1028,4 @@ public class ThriftActions {
return Gui.showMessageBox(frame, message, MessageType.QUESTION_YESNO, null, null);
}
- /**
- * Wrapper class for UploadTask & AsyncHashGenerator
- *
- */
- public static class InitUploadStatus {
- public final UploadTask task;
- public final AsyncHashGenerator hasher;
-
- public InitUploadStatus(final UploadTask task, final AsyncHashGenerator hasher) {
- this.task = task;
- this.hasher = hasher;
- }
- }
-
}
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;
+ }
+
+}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/WrappedException.java b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/WrappedException.java
new file mode 100644
index 00000000..1eb9783a
--- /dev/null
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/WrappedException.java
@@ -0,0 +1,15 @@
+package org.openslx.dozmod.thrift;
+
+import org.apache.thrift.TException;
+
+
+public class WrappedException extends Exception {
+ private static final long serialVersionUID = 989657721513312675L;
+ public final TException exception;
+ public final String displayMessage;
+
+ public WrappedException(TException e, String msg) {
+ this.exception = e;
+ this.displayMessage = msg;
+ }
+}