diff options
| author | Jonathan Bauer | 2015-08-20 16:45:50 +0200 |
|---|---|---|
| committer | Jonathan Bauer | 2015-08-20 16:45:50 +0200 |
| commit | 375a020f81996cf993d7e2b40bff92cf6298a297 (patch) | |
| tree | 701a2b70f17c1e11dbd769e7fbdda22b29050e38 /dozentenmodul/src/main/java | |
| parent | [client] cancel has generator if cancel is clicked (diff) | |
| download | tutor-module-375a020f81996cf993d7e2b40bff92cf6298a297.tar.gz tutor-module-375a020f81996cf993d7e2b40bff92cf6298a297.tar.xz tutor-module-375a020f81996cf993d7e2b40bff92cf6298a297.zip | |
[client] Upload stuff ThriftActions'ed [WIP]
Diffstat (limited to 'dozentenmodul/src/main/java')
4 files changed, 239 insertions, 93 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/UpdateWizard.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/UpdateWizard.java index 46eb1de7..c534df63 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/UpdateWizard.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/UpdateWizard.java @@ -2,26 +2,36 @@ package org.openslx.dozmod.gui.wizard; import java.awt.Window; +import javax.swing.JOptionPane; + import org.apache.log4j.Logger; import org.openslx.bwlp.thrift.iface.ImageDetailsRead; +import org.openslx.bwlp.thrift.iface.ImageVersionWrite; import org.openslx.dozmod.gui.helper.UiFeedback; import org.openslx.dozmod.gui.wizard.page.ImageUploadPage; import org.openslx.dozmod.state.UploadWizardState; +import org.openslx.dozmod.thrift.ThriftActions; @SuppressWarnings("serial") public class UpdateWizard extends Wizard implements UiFeedback { private final static Logger LOGGER = Logger.getLogger(ImageWizard.class); - + private final UploadWizardState uploadWizardState = new UploadWizardState(); + protected ImageUploadPage imageUploadPage; public UpdateWizard(final Window parent, final ImageDetailsRead image) { super(parent); - UploadWizardState uploadWizardState = new UploadWizardState(); imageUploadPage = new ImageUploadPage(this, uploadWizardState, true); addPage(imageUploadPage); } @Override + public void performFinish() { + ThriftActions.updateImageVersion(JOptionPane.getFrameForComponent(this), + uploadWizardState.transferInformation, + new ImageVersionWrite(uploadWizardState.isRestricted)); + } + @Override public boolean wantConfirmQuit() { // TODO Auto-generated method stub return false; @@ -35,7 +45,7 @@ public class UpdateWizard extends Wizard implements UiFeedback { @Override public String getWindowTitle() { // TODO Auto-generated method stub - return "Neue Image-Version hochladen"; + return "Neue Image-Version"; } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java index 32b127a6..937cae43 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/layout/ImageUploadPageLayout.java @@ -19,6 +19,7 @@ public abstract class ImageUploadPageLayout extends WizardPage { protected JButton imageFileBrowseButton; protected JTextField imageFileTextField; protected JCheckBox softwareLicenseBox; + protected JLabel imageNameCaption; /** * Page for uploading an imagefile @@ -39,8 +40,7 @@ public abstract class ImageUploadPageLayout extends WizardPage { grid.add(imageFileBrowseButton); grid.nextRow(); - // -- Name -- - JLabel imageNameCaption = new JLabel("Name des Images"); + imageNameCaption = new JLabel("Name des Images"); imageNameTextField = new JTextField(); grid.add(imageNameCaption); grid.add(imageNameTextField, 2, 1).fill(true, false).expand(true, false); @@ -48,6 +48,7 @@ public abstract class ImageUploadPageLayout extends WizardPage { // -- Software license changed - shown only in UploadWizard -- softwareLicenseBox = new JCheckBox("Lizensierte Software enthalten"); + softwareLicenseBox.setVisible(false); grid.skip(); grid.add(softwareLicenseBox, 2, 1).fill(false, false).expand(true, false); grid.nextRow(); 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 84a9da10..18e61fd5 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 @@ -5,20 +5,16 @@ import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.List; import javax.swing.JFileChooser; +import javax.swing.JOptionPane; import javax.swing.filechooser.FileNameExtensionFilter; import org.apache.log4j.Logger; -import org.apache.thrift.TException; -import org.openslx.bwlp.thrift.iface.TImageDataException; import org.openslx.dozmod.Config; -import org.openslx.dozmod.filetransfer.AsyncHashGenerator; -import org.openslx.dozmod.filetransfer.UploadTask; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.MainWindow; import org.openslx.dozmod.gui.helper.MessageType; @@ -26,11 +22,8 @@ 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.Session; -import org.openslx.dozmod.thrift.ThriftError; +import org.openslx.dozmod.thrift.ThriftActions; import org.openslx.dozmod.thrift.cache.MetaDataCache; -import org.openslx.thrifthelper.ThriftManager; -import org.openslx.util.Util; import org.openslx.util.vm.VmMetaData.HardDisk; import org.openslx.util.vm.VmwareMetaData; @@ -50,8 +43,11 @@ public class ImageUploadPage extends ImageUploadPageLayout { this.state = uploadWizardState; this.updateExisting = updateExisting; - // hide software license checkbox if we are only uploading an image version + imageNameCaption.setVisible(!updateExisting); + imageNameTextField.setVisible(!updateExisting); + // show the licenced software checkbox since we are uploading new version softwareLicenseBox.setVisible(updateExisting); + softwareLicenseBox.setSelected(updateExisting); // TODO selected by default? // Browse for *.vmx imageFileBrowseButton.addActionListener(new ActionListener() { @@ -131,13 +127,14 @@ public class ImageUploadPage extends ImageUploadPageLayout { // vmx ok, set it as our description file state.descriptionFile = file; - // User didn't enter a name yet or didn't change it -> set - String txtName = imageNameTextField.getText(); - if (txtName.isEmpty() || txtName.equals(lastDetectedName)) { - imageNameTextField.setText(state.meta.getDisplayName()); + if (!updateExisting) { + // User didn't enter a name yet or didn't change it -> set + String imageName = imageNameTextField.getText(); + if (imageName.isEmpty() || imageName.equals(lastDetectedName)) { + imageNameTextField.setText(state.meta.getDisplayName()); + } } lastDetectedName = state.meta.getDisplayName(); - state.detectedOs = state.meta.getOs(); imageFileTextField.setText(file.getAbsolutePath()); // let the user know the upload is ready @@ -161,75 +158,42 @@ public class ImageUploadPage extends ImageUploadPageLayout { */ @Override protected boolean wantNextOrFinish() { - // first get the image name from the field - // (either auto filled by VmwareMetaData or by user) - state.name = imageNameTextField.getText(); - // and to request the upload once we received that UUID. + // are we creating a new image? + if (!updateExisting) { + // get the image name either auto filled by VmwareMetaData or by user + state.name = imageNameTextField.getText(); + } else { + // get the image name from the image we are uploading a new version of + state.name = "HAX"; + } - // -- create image -- + + // -- create image to get uuid -- if (state.uuid == null) { - LOGGER.debug("Creating image..."); - try { - state.uuid = ThriftManager.getSatClient() - .createImage(Session.getSatelliteToken(), state.name); - } catch (TImageDataException e) { - Gui.showMessageBox(this, "Ungültige Angaben (" + e.getNumber() + ")\n" + e.getMessage(), - MessageType.ERROR, null, null); - return false; - } catch (Exception e) { - Gui.showMessageBox(this, "Unbekannter Fehler beim Erstellen der VM", MessageType.ERROR, - LOGGER, e); + state.uuid = ThriftActions.createImage(JOptionPane.getFrameForComponent(this), state.name); + if (state.uuid == null) return false; - } + imageNameTextField.setEnabled(false); imageFileBrowseButton.setEnabled(false); imageFileTextField.setEnabled(false); } - // -- request upload -- + // -- request upload for that uuid -- if (state.transferInformation == null) { - LOGGER.debug("Requesting upload..."); - try { - state.transferInformation = ThriftManager.getSatClient().requestImageVersionUpload( - Session.getSatelliteToken(), state.uuid, state.diskFile.length(), null, - state.meta.getFilteredDefinition()); - } catch (TException e) { - ThriftError.showMessage(this, LOGGER, e, "Fehler beim Aushandeln des Uploads"); - } catch (Exception e) { - Gui.showMessageBox(this, "Fehler beim Aushandeln des Uploads", MessageType.ERROR, LOGGER, e); + state.transferInformation = ThriftActions.requestVersionUpload(JOptionPane.getFrameForComponent(this), + state.uuid, state.diskFile.length(), null, state.meta.getFilteredDefinition()); + if (state.transferInformation == null) return false; - } } + // -- start uploading our diskFile with the transfer information we just received -- if (state.uploadTask == null) { - // do actually start the upload now - LOGGER.debug("Starting upload for: " + state.diskFile.toPath()); - try { - state.uploadTask = new UploadTask(Session.getSatelliteAddress(), - state.transferInformation.getPlainPort(), state.transferInformation.getToken(), - state.diskFile); - } catch (FileNotFoundException e) { - Gui.showMessageBox(getTopLevelAncestor(), "Kann VM nicht hochladen: Datei nicht gefunden\n\n" - + state.diskFile.getAbsolutePath(), MessageType.ERROR, LOGGER, e); + state.uploadTask = ThriftActions.initUpload(JOptionPane.getFrameForComponent(this), + state.transferInformation, state.hashGen, state.diskFile); + if (state.uploadTask == null) return false; - } - state.hashGen = new AsyncHashGenerator(state.transferInformation.token, state.diskFile); - new Thread(state.hashGen).start(); - Util.sleep(50); // A little ugly... Give the hash generator a head start - new Thread(state.uploadTask).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 (state.uploadTask.getFailCount() == 0 && state.uploadTask.getTransferCount() == 0 - && !state.uploadTask.isCanceled()); - } - - if (state.uploadTask.getTransferCount() == 0) { - Gui.showMessageBox(this, "Aufbau der Verbindung zum Hochladen fehlgeschlagen", MessageType.ERROR, - LOGGER, null); - state.hashGen.cancel(); - state.uploadTask.cancel(); - state.uploadTask = null; - return false; } MainWindow.addUpload(state); return true; + } } 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 e57a9310..68eb935b 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java @@ -4,14 +4,21 @@ import java.awt.Frame; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.List; import javax.swing.JFileChooser; import org.apache.log4j.Logger; import org.apache.thrift.TException; +import org.openslx.bwlp.thrift.iface.ImageVersionWrite; +import org.openslx.bwlp.thrift.iface.TAuthorizationException; +import org.openslx.bwlp.thrift.iface.TImageDataException; import org.openslx.bwlp.thrift.iface.TransferInformation; import org.openslx.dozmod.Config; +import org.openslx.dozmod.filetransfer.AsyncHashGenerator; import org.openslx.dozmod.filetransfer.DownloadTask; +import org.openslx.dozmod.filetransfer.UploadTask; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.Gui.GuiCallable; import org.openslx.dozmod.gui.MainWindow; @@ -19,15 +26,16 @@ import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.gui.helper.QFileChooser; import org.openslx.thrifthelper.ThriftManager; import org.openslx.util.QuickTimer; +import org.openslx.util.Util; import org.openslx.util.QuickTimer.Task; public class ThriftActions { private static final Logger LOGGER = Logger.getLogger(ThriftActions.class); - /******************************************************************************** + /* ******************************************************************************* * - * DOWNLOAD ACTION + * IMAGE VERSION DOWNLOAD * * Download image version action composed of the interface 'DownloadCallback' * and the actual static method 'initDownload' to start the download. @@ -77,23 +85,31 @@ public class ThriftActions { try { file.getAbsoluteFile().mkdirs(); df = new File(file.getAbsolutePath(), generateFilename(imageName, virtualizerId)); + final File ff = df; + if (df.exists()) { + if (!Gui.syncExec(new GuiCallable<Boolean>() { + @Override + public Boolean run() { + return Gui.showMessageBox(frame, + "Datei '" + ff.getAbsolutePath() + "' existiert bereits, wollen Sie sie überschreiben?", MessageType.QUESTION_YESNO, LOGGER, null); + } + })) { + // user aborted + return; + } else { + // delete it + if (!df.delete()) { + // TODO what? + Gui.showMessageBox(frame, "Datei konnte nicht überschrieben werden!", MessageType.ERROR, LOGGER, null); + return; + } + } + } df.createNewFile(); } catch (IOException e) { LOGGER.warn("Cannot prepare download destination", e); } final File destFile = df; - if (destFile.exists()) { - Boolean confirmed = Gui.syncExec(new GuiCallable<Boolean>() { - @Override - public Boolean run() { - return Gui.showMessageBox(frame, "Datei existiert bereits, wollen Sie sie überschreiben?", MessageType.QUESTION_YESNO, LOGGER, null); - } - }); - if (!confirmed) { - // TODO potentially ask him a new path? - return; - } - } final DownloadTask dlTask; try { dlTask = new DownloadTask(Session.getSatelliteAddress(), transInf.getPlainPort(), transInf @@ -142,17 +158,172 @@ public class ThriftActions { return fileName; } - public interface DeleteCallback { - void isDeleted(boolean success); + /* ******************************************************************************* + * + * IMAGE CREATION + * + * Creates a base image with the given name + * + ********************************************************************************/ + /** + * GUI-BLOCKING + * Creates the image with the given name. Returns the uuid returned by the server + * + * @param frame calling this action + * @return uuid as String, or null if the creation failed + */ + public static String createImage(final Frame frame, final String name) { + String uuid = null; + try { + uuid = ThriftManager.getSatClient().createImage(Session.getSatelliteToken(), name); + } catch (TAuthorizationException e) { + Gui.showMessageBox(frame, "Sie sind nicht Berechtigt ein Image zu estellen.", + MessageType.ERROR, LOGGER, e); + } catch (TImageDataException e) { + Gui.showMessageBox(frame, "Ungültige Angaben (" + e.getNumber() + ")\n" + e.getMessage(), + MessageType.ERROR, LOGGER, e); + } catch (Exception e) { + Gui.showMessageBox(frame, "Unbekannter Fehler beim Erstellen der VM", MessageType.ERROR, + LOGGER, e); + } + return uuid; + } + + /* ******************************************************************************* + * + * IMAGE VERSION UPLOAD + * + * Methods to upload an image version. This is compromised of two distinct 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) { + 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 UploadTask initUpload(final Frame frame, final TransferInformation transferInformation, + AsyncHashGenerator hashGen, 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; + } + hashGen = new AsyncHashGenerator(transferInformation.token, diskFile); + Thread hashThread = new Thread(hashGen); + hashThread.setDaemon(true); + hashThread.start(); + 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 uploadTask; } - /******************************************************************************** + /** + * TODO + * @param frame + * @param transferInformation + * @param versionInfo + */ + public static void updateImageVersion(final Frame frame, final TransferInformation transferInformation, final ImageVersionWrite versionInfo) { + try { + ThriftManager.getSatClient().updateImageVersion(Session.getSatelliteToken(), + transferInformation.getToken(), + versionInfo); + } catch (TException e) { + Gui.asyncMessageBox("Could not set active/restricted flags to satellite: ", + MessageType.ERROR, LOGGER, e); + return; + } + } + + /* ******************************************************************************* * - * DELETE ACTION + * IMAGE VERSION DELETION * * Deletes a specific image version * ********************************************************************************/ + /** + * Delete callback interface to be implemented by callers of + * ThriftActions.deleteImageVersion(..) + */ + public interface DeleteCallback { + /** + * Called once the status of a delete operation is determined + * + * @param success true if deleted successfully, false otherwise + */ + void isDeleted(boolean success); + } + /** + * NON-BLOCKING + * Deletes the given imageVersionId of the image imageBaseId and calls the given + * callback method to inform about the outcome of the operation. + * + * @param frame next parent frame of the caller of this method + * @param imageBaseId uuid of the image that belongs to the version + * @param imageVersionId id of the image version to be deleted + * @param callback called to inform the GUI about the deletion status (see DeleteCallback interface) + */ public static void deleteImageVersion(final Frame frame, final String imageBaseId, final String imageVersionId, final DeleteCallback callback) { // requires confirmation of the user |
