From 70959ec1408a12623e9f152899b7e0fc4a42d308 Mon Sep 17 00:00:00 2001 From: asharani-murugesh Date: Mon, 8 Feb 2016 10:47:42 +0100 Subject: [PATCH 01/14] intial commit Signed-off-by: asharani-murugesh --- .../ui/artifacts/upload/UploadHandler.java | 6 +- .../ui/artifacts/upload/UploadLayout.java | 1053 +++++++++-------- 2 files changed, 548 insertions(+), 511 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java index 834246c63..ed4e22ba0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java @@ -89,6 +89,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public final OutputStream getOutputStream() { try { + view.getDuplicateFileNamesList().clear(); return view.saveUploadedFileDetails(fileName, fileSize, mimeType); } catch (final ArtifactUploadFailedException e) { LOG.error("Atifact upload failed {} ", e); @@ -108,6 +109,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public OutputStream receiveUpload(final String fileName, final String mimeType) { this.fileName = fileName; this.mimeType = mimeType; + view.getDuplicateFileNamesList().clear(); try { if (view.validate()) { if (view.checkForDuplicate(fileName)) { @@ -167,7 +169,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene view.updateActionCount(); // display the duplicate message after streaming all files - view.displayDuplicateMessageAfterStreamingAll(); + view.displayValidationMessage(); } /** @@ -292,7 +294,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene if (view.enableProcessBtn()) { infoWindow.uploadSessionFinished(); } - view.displayDuplicateMessageAfterStreamingAll(); + view.displayValidationMessage(); LOG.info("Streaming failed due to :{}", event.getException()); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index e570c84c4..b944006ff 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -46,6 +46,7 @@ import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; +import com.google.common.base.Strings; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptAll; @@ -70,529 +71,563 @@ import com.vaadin.ui.VerticalLayout; /** * Upload files layout. * - * + * @author G Venkata Narayana (RBEI/BSO3) */ @ViewScope @SpringComponent public class UploadLayout extends VerticalLayout { - private static final long serialVersionUID = -566164756606779220L; + private static final long serialVersionUID = -566164756606779220L; - private static final Logger LOG = LoggerFactory.getLogger(UploadLayout.class); + private static final Logger LOG = LoggerFactory.getLogger(UploadLayout.class); - @Autowired - private UploadStatusInfoWindow uploadInfoWindow; + @Autowired + private UploadStatusInfoWindow uploadInfoWindow; - @Autowired - private I18N i18n; + @Autowired + private I18N i18n; - @Autowired - private transient UINotification uiNotification; + @Autowired + private transient UINotification uiNotification; - @Autowired - private transient EventBus.SessionEventBus eventBus; + @Autowired + private transient EventBus.SessionEventBus eventBus; - @Autowired - private ArtifactUploadState artifactUploadState; + @Autowired + private ArtifactUploadState artifactUploadState; - @Autowired - private transient SPInfo spInfo; + @Autowired + private transient SPInfo spInfo; - private final AtomicInteger numberOfFileUploadsExpected = new AtomicInteger(); + private final AtomicInteger numberOfFileUploadsExpected = new AtomicInteger(); - private final AtomicInteger numberOfFilesActuallyUpload = new AtomicInteger(); + private final AtomicInteger numberOfFilesActuallyUpload = new AtomicInteger(); - private final List duplicateFileNamesList = new ArrayList(); - - private Button processBtn; - - private Button discardBtn; - - private UploadConfirmationwindow currentUploadConfirmationwindow; - - private VerticalLayout dropAreaLayout; - - private UI ui; - - private HorizontalLayout fileUploadLayout; - - private DragAndDropWrapper dropAreaWrapper; - - /** - * Initialize the upload layout. - */ - @PostConstruct - void init() { - createComponents(); - buildLayout(); - updateActionCount(); - eventBus.subscribe(this); - ui = UI.getCurrent(); - } - - private void createComponents() { - - createProcessButton(); - createDiscardBtn(); - } - - private void buildLayout() { - - final Upload upload = new Upload(); - final UploadHandler uploadHandler = new UploadHandler(null, 0, this, uploadInfoWindow, - spInfo.getMaxArtifactFileSize(), upload, null); - upload.setButtonCaption(i18n.get("upload.file")); - upload.setImmediate(true); - upload.setReceiver(uploadHandler); - upload.addSucceededListener(uploadHandler); - upload.addFailedListener(uploadHandler); - upload.addFinishedListener(uploadHandler); - upload.addProgressListener(uploadHandler); - upload.addStartedListener(uploadHandler); - upload.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - - fileUploadLayout = new HorizontalLayout(); - fileUploadLayout.setSpacing(true); - fileUploadLayout.addComponent(upload); - fileUploadLayout.setComponentAlignment(upload, Alignment.MIDDLE_LEFT); - fileUploadLayout.addComponent(processBtn); - fileUploadLayout.setComponentAlignment(processBtn, Alignment.MIDDLE_RIGHT); - fileUploadLayout.addComponent(discardBtn); - fileUploadLayout.setComponentAlignment(discardBtn, Alignment.MIDDLE_RIGHT); - setMargin(false); - - /* create drag-drop wrapper for drop area */ - dropAreaWrapper = new DragAndDropWrapper(createDropAreaLayout()); - dropAreaWrapper.setDropHandler(new DropAreahandler()); - setSizeFull(); - setSpacing(true); - - } - - public DragAndDropWrapper getDropAreaWrapper() { - return dropAreaWrapper; - } - - private class DropAreahandler implements DropHandler { - - private static final long serialVersionUID = 1L; - - @Override - public AcceptCriterion getAcceptCriterion() { - return AcceptAll.get(); - } - - @Override - public void drop(final DragAndDropEvent event) { - if (validate()) { - - final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); - if (files != null) { - for (final Html5File file : files) { - if (!checkForDuplicate(file.getFileName())) { - numberOfFileUploadsExpected.incrementAndGet(); - file.setStreamVariable(createStreamVariable(file)); - } - } - if (numberOfFileUploadsExpected.get() > 0) { - processBtn.setEnabled(false); - // reset before we start - uploadInfoWindow.uploadSessionStarted(); - } - // in case if all selected files are duplicate ,then display - // message - displayDuplicateMessageAfterStreamingAll(); - } - } - } - } - - private VerticalLayout createDropAreaLayout() { - dropAreaLayout = new VerticalLayout(); - final Label dropHereLabel = new Label("Drop files to upload"); - dropHereLabel.setWidth(null); - - final Label dropIcon = new Label(FontAwesome.ARROW_DOWN.getHtml(), ContentMode.HTML); - dropIcon.addStyleName("drop-icon"); - dropIcon.setWidth(null); - - dropAreaLayout.addComponent(dropIcon); - dropAreaLayout.setComponentAlignment(dropIcon, Alignment.BOTTOM_CENTER); - dropAreaLayout.addComponent(dropHereLabel); - dropAreaLayout.setComponentAlignment(dropHereLabel, Alignment.TOP_CENTER); - dropAreaLayout.setSizeFull(); - dropAreaLayout.setStyleName("upload-drop-area-layout-info"); - dropAreaLayout.setSpacing(false); - return dropAreaLayout; - } - - private void createProcessButton() { - processBtn = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_PROCESS_BUTTON, - SPUILabelDefinitions.PROCESS, SPUILabelDefinitions.PROCESS, null, false, null, - SPUIButtonStyleSmall.class); - processBtn.setIcon(FontAwesome.BELL); - processBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - processBtn.addClickListener(event -> displayConfirmWindow(event)); - processBtn.setHtmlContentAllowed(true); - if (artifactUploadState.getFileSelected().isEmpty()) { - processBtn.setEnabled(false); - } - } - - private void createDiscardBtn() { - discardBtn = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_DISCARD_BUTTON, - SPUILabelDefinitions.DISCARD, SPUILabelDefinitions.DISCARD, null, false, null, - SPUIButtonStyleSmall.class); - discardBtn.setIcon(FontAwesome.TRASH_O); - discardBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - discardBtn.addClickListener(event -> discardUploadData(event)); - } - - private StreamVariable createStreamVariable(final Html5File file) { - return new UploadHandler(file.getFileName(), file.getFileSize(), this, uploadInfoWindow, - spInfo.getMaxArtifactFileSize(), null, file.getType()); - } - - boolean checkForDuplicate(final String filename) { - final Boolean isDuplicate = checkIfFileIsDuplicate(filename); - if (isDuplicate) { - getDuplicateFileNamesList().add(filename); - } - return isDuplicate; - } - - @EventBusListenerMethod(scope = EventScope.SESSION) - void toggleProcessButton(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.ENABLE_PROCESS_BUTTON) { - processBtn.setEnabled(true); - } else if (event == UploadArtifactUIEvent.DISABLE_PROCESS_BUTTON) { - processBtn.setEnabled(false); - } - } - - /** - * Save uploaded file details. - * - * @param stream - * read from uploaded file - * @param name - * file name - * @param size - * file size - * @param mimeType - * the mimeType of the file - * @throws IOException - * in case of upload errors - */ - OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType) { - File tempFile = null; - try { - tempFile = File.createTempFile("spUiArtifactUpload", null); - - final OutputStream out = new FileOutputStream(tempFile); - - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); - - final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), - selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion(), mimeType); - - artifactUploadState.getFileSelected().add(customFile); - processBtn.setEnabled(false); - - if (!artifactUploadState.getBaseSwModuleList().keySet().contains(currentBaseSoftwareModuleKey)) { - artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSoftwareModule); - } - return out; - } catch (final FileNotFoundException e) { - LOG.error("Upload failed {}", e); - throw new ArtifactUploadFailedException(i18n.get("message.file.not.found")); - } catch (final IOException e) { - LOG.error("Upload failed {}", e); - throw new ArtifactUploadFailedException(i18n.get("message.upload.failed")); - } - } - - Boolean validate() { - if (!isSoftwareModuleSelected()) { - uiNotification.displayValidationError(i18n.get("message.error.noSwModuleSelected")); - - return false; - } - return true; - } - - SoftwareModule getSoftwareModuleSelected() { - if (artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) { - return artifactUploadState.getSelectedBaseSoftwareModule().get(); - } - return null; - } - - Boolean isSoftwareModuleSelected() { - if (!artifactUploadState.getSelectedBaseSwModuleId().isPresent()) { - return false; - } - return true; - } - - /** - * Check if file selected is duplicate.i,e already selected for upload for - * same software module. - * - * @param name - * file name - * @return Boolean - */ - public Boolean checkIfFileIsDuplicate(final String name) { - Boolean isDuplicate = false; - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); - - for (final CustomFile customFile : artifactUploadState.getFileSelected()) { - final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { - isDuplicate = true; - break; - } - } - return isDuplicate; - } - - void decreaseNumberOfFileUploadsExpected() { - numberOfFileUploadsExpected.decrementAndGet(); - } - - List getDuplicateFileNamesList() { - return duplicateFileNamesList; - } - - /** - * Update pending action count. - */ - void updateActionCount() { - if (!artifactUploadState.getFileSelected().isEmpty()) { - processBtn.setCaption(SPUILabelDefinitions.PROCESS + "
" - + artifactUploadState.getFileSelected().size() + "
"); - } else { - processBtn.setCaption(SPUILabelDefinitions.PROCESS); - } - } - - void displayDuplicateMessageAfterStreamingAll() { - // check if streaming of all dropped files are completed - if (numberOfFilesActuallyUpload.intValue() == numberOfFileUploadsExpected.intValue()) { - showDuplicateMessage(); - } - } - - /** - * Show duplicate file selected message. - */ - public void showDuplicateMessage() { - if (!duplicateFileNamesList.isEmpty()) { - final String fileNames = StringUtils.collectionToCommaDelimitedString(duplicateFileNamesList); - if (duplicateFileNamesList.size() == 1) { - uiNotification.displayValidationError(i18n.get("message.no.duplicateFile") + fileNames); - - } else if (duplicateFileNamesList.size() > 1) { - uiNotification.displayValidationError(i18n.get("message.no.duplicateFiles")); - } - duplicateFileNamesList.clear(); - } - } - - void increaseNumberOfFileUploadsExpected() { - numberOfFileUploadsExpected.incrementAndGet(); - } - - void updateFileSize(final String name, final long size) { - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); - - for (final CustomFile customFile : artifactUploadState.getFileSelected()) { - final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { - customFile.setFileSize(size); - break; - } - } - } - - void increaseNumberOfFilesActuallyUpload() { - numberOfFilesActuallyUpload.incrementAndGet(); - } - - /** - * Enable process button once upload is completed. - */ - boolean enableProcessBtn() { - if (numberOfFilesActuallyUpload.intValue() >= numberOfFileUploadsExpected.intValue()) { - processBtn.setEnabled(true); - numberOfFileUploadsExpected.set(0); - numberOfFilesActuallyUpload.set(0); - return true; - } - return false; - } - - Set getFileSelected() { - return artifactUploadState.getFileSelected(); - } - - private void discardUploadData(final Button.ClickEvent event) { - if (event.getButton().equals(discardBtn)) { - if (artifactUploadState.getFileSelected().isEmpty()) { - uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); - - } else { - clearFileList(); - } - } - } - - /** - * Clear details. - */ - void clearFileList() { - // delete file system zombies - artifactUploadState.getFileSelected().forEach(customFile -> { - final File file = new File(customFile.getFilePath()); - file.delete(); - }); - - artifactUploadState.getFileSelected().clear(); - artifactUploadState.getBaseSwModuleList().clear(); - processBtn.setCaption(SPUILabelDefinitions.PROCESS); - /* disable when there is no files to upload. */ - processBtn.setEnabled(false); - numberOfFileUploadsExpected.set(0); - numberOfFilesActuallyUpload.set(0); - duplicateFileNamesList.clear(); - } - - private void setConfirmationPopupHeightWidth(final float newWidth, final float newHeight) { - if (currentUploadConfirmationwindow != null) { - currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth(HawkbitCommonUtil - .getArtifactUploadPopupWidth(newWidth, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), - Unit.PIXELS); - currentUploadConfirmationwindow.getUploadDetailsTable().setHeight(HawkbitCommonUtil - .getArtifactUploadPopupHeight(newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), - Unit.PIXELS); - } - } - - /** - * Set artifact upload result pop up size changes. - * - * @param newWidth - * new width of result pop up - * @param newHeight - * new height of result pop up - */ - void setResultPopupHeightWidth(final float newWidth, final float newHeight) { - if (currentUploadConfirmationwindow != null - && currentUploadConfirmationwindow.getCurrentUploadResultWindow() != null) { - final UploadResultWindow uploadResultWindow = currentUploadConfirmationwindow - .getCurrentUploadResultWindow(); - uploadResultWindow.getUploadResultsWindow().setWidth(HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, - SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); - uploadResultWindow.getUploadResultTable().setHeight(HawkbitCommonUtil.getArtifactUploadPopupHeight( - newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); - } - } - - private void displayConfirmWindow(final Button.ClickEvent event) { - if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_PROCESS_BUTTON)) { - if (artifactUploadState.getFileSelected().isEmpty()) { - uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); - } else { - currentUploadConfirmationwindow = new UploadConfirmationwindow(this, artifactUploadState); - UI.getCurrent().addWindow(currentUploadConfirmationwindow.getUploadConfrimationWindow()); - setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), - Page.getCurrent().getBrowserWindowHeight()); - } - } - } - - /** - * @return - */ - I18N getI18n() { - return i18n; - } - - /** - * @return - */ - SPInfo getSPInfo() { - return spInfo; - } - - void setCurrentUploadConfirmationwindow(final UploadConfirmationwindow currentUploadConfirmationwindow) { - this.currentUploadConfirmationwindow = currentUploadConfirmationwindow; - } - - /** - * @return - */ - - VerticalLayout getDropAreaLayout() { - return dropAreaLayout; - } - - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) { - ui.access(() -> updateActionCount()); - } - } - - @PreDestroy - void destroy() { - /* - * It's good manners to do this, even though vaadin-spring will - * automatically unsubscribe when this UI is garbage collected. - */ - eventBus.unsubscribe(this); - } - - /** - * set upload status and confirmation window. - * - * @param newWidth - * browser width - * @param newHeight - * browser height - */ - public void setUploadPopupSize(final float newWidth, final float newHeight) { - setConfirmationPopupHeightWidth(newWidth, newHeight); - setResultPopupHeightWidth(newWidth, newHeight); - } - - /** - * @param selectedBaseSoftwareModule - */ - public void refreshArtifactDetailsLayout(final SoftwareModule selectedBaseSoftwareModule) { - eventBus.publish(this, - new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, selectedBaseSoftwareModule)); - } - - /** - * @return the fileUploadLayout - */ - public HorizontalLayout getFileUploadLayout() { - return fileUploadLayout; - } - - public UINotification getUINotification() { - return uiNotification; - } + private final List duplicateFileNamesList = new ArrayList(); + + private Button processBtn; + + private Button discardBtn; + + private UploadConfirmationwindow currentUploadConfirmationwindow; + + private VerticalLayout dropAreaLayout; + + private UI ui; + + private HorizontalLayout fileUploadLayout; + + private DragAndDropWrapper dropAreaWrapper; + + private Boolean hasDirectory = Boolean.FALSE; + + /** + * Initialize the upload layout. + */ + @PostConstruct + void init() { + createComponents(); + buildLayout(); + updateActionCount(); + eventBus.subscribe(this); + ui = UI.getCurrent(); + } + + private void createComponents() { + + createProcessButton(); + createDiscardBtn(); + } + + private void buildLayout() { + + final Upload upload = new Upload(); + final UploadHandler uploadHandler = new UploadHandler(null, 0, this, uploadInfoWindow, + spInfo.getMaxArtifactFileSize(), upload, null); + upload.setButtonCaption(i18n.get("upload.file")); + upload.setImmediate(true); + upload.setReceiver(uploadHandler); + upload.addSucceededListener(uploadHandler); + upload.addFailedListener(uploadHandler); + upload.addFinishedListener(uploadHandler); + upload.addProgressListener(uploadHandler); + upload.addStartedListener(uploadHandler); + upload.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); + + fileUploadLayout = new HorizontalLayout(); + fileUploadLayout.setSpacing(true); + fileUploadLayout.addComponent(upload); + fileUploadLayout.setComponentAlignment(upload, Alignment.MIDDLE_LEFT); + fileUploadLayout.addComponent(processBtn); + fileUploadLayout.setComponentAlignment(processBtn, Alignment.MIDDLE_RIGHT); + fileUploadLayout.addComponent(discardBtn); + fileUploadLayout.setComponentAlignment(discardBtn, Alignment.MIDDLE_RIGHT); + setMargin(false); + + /* create drag-drop wrapper for drop area */ + dropAreaWrapper = new DragAndDropWrapper(createDropAreaLayout()); + dropAreaWrapper.setDropHandler(new DropAreahandler()); + setSizeFull(); + setSpacing(true); + + } + + public DragAndDropWrapper getDropAreaWrapper() { + return dropAreaWrapper; + } + + private class DropAreahandler implements DropHandler { + + private static final long serialVersionUID = 1L; + + @Override + public AcceptCriterion getAcceptCriterion() { + return AcceptAll.get(); + } + + @Override + public void drop(final DragAndDropEvent event) { + if (validate()) { + ((WrapperTransferable) event.getTransferable()).getDraggedComponent(); + final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); + if (files != null) { + for (final Html5File file : files) { + if (!isDirectory(file)) { + if (!checkForDuplicate(file.getFileName())) { + numberOfFileUploadsExpected.incrementAndGet(); + file.setStreamVariable(createStreamVariable(file)); + } + } else { + hasDirectory = Boolean.TRUE; + } + } + if (numberOfFileUploadsExpected.get() > 0) { + processBtn.setEnabled(false); + // reset before we start + uploadInfoWindow.uploadSessionStarted(); + } else { + //If the upload is not started, it signifies all dropped files as either duplicate or directory.So display message accordingly + displayCompositeMessage(hasDirectory); + } + } + } + } + } + + private static boolean isDirectory(final Html5File file) { + if (Strings.isNullOrEmpty(file.getType()) && file.getFileSize() % 4096 == 0) { + return true; + } + return false; + } + + private void displayCompositeMessage(final Boolean hasDirectory) { + final String duplicateMessage = showDuplicateMessage(); + final StringBuilder compositeMessage = new StringBuilder(); + if (null != duplicateMessage) { + // in case if all selected files are duplicate ,then display + // messag + compositeMessage.append(duplicateMessage); + } + if (hasDirectory) { + if (compositeMessage.length() > 0) { + compositeMessage.append("
"); + } + compositeMessage.append(i18n.get("message.no.directory.upload")); + } + if (!compositeMessage.toString().isEmpty()) { + uiNotification.displayValidationError(compositeMessage.toString()); + } + } + + private VerticalLayout createDropAreaLayout() { + dropAreaLayout = new VerticalLayout(); + final Label dropHereLabel = new Label("Drop files to upload"); + dropHereLabel.setWidth(null); + + final Label dropIcon = new Label(FontAwesome.ARROW_DOWN.getHtml(), ContentMode.HTML); + dropIcon.addStyleName("drop-icon"); + dropIcon.setWidth(null); + + dropAreaLayout.addComponent(dropIcon); + dropAreaLayout.setComponentAlignment(dropIcon, Alignment.BOTTOM_CENTER); + dropAreaLayout.addComponent(dropHereLabel); + dropAreaLayout.setComponentAlignment(dropHereLabel, Alignment.TOP_CENTER); + dropAreaLayout.setSizeFull(); + dropAreaLayout.setStyleName("upload-drop-area-layout-info"); + dropAreaLayout.setSpacing(false); + return dropAreaLayout; + } + + private void createProcessButton() { + processBtn = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_PROCESS_BUTTON, + SPUILabelDefinitions.PROCESS, SPUILabelDefinitions.PROCESS, null, false, null, + SPUIButtonStyleSmall.class); + processBtn.setIcon(FontAwesome.BELL); + processBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); + processBtn.addClickListener(event -> displayConfirmWindow(event)); + processBtn.setHtmlContentAllowed(true); + if (artifactUploadState.getFileSelected().isEmpty()) { + processBtn.setEnabled(false); + } + } + + private void createDiscardBtn() { + discardBtn = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_DISCARD_BUTTON, + SPUILabelDefinitions.DISCARD, SPUILabelDefinitions.DISCARD, null, false, null, + SPUIButtonStyleSmall.class); + discardBtn.setIcon(FontAwesome.TRASH_O); + discardBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); + discardBtn.addClickListener(event -> discardUploadData(event)); + } + + private StreamVariable createStreamVariable(final Html5File file) { + return new UploadHandler(file.getFileName(), file.getFileSize(), this, uploadInfoWindow, + spInfo.getMaxArtifactFileSize(), null, file.getType()); + } + + boolean checkForDuplicate(final String filename) { + final Boolean isDuplicate = checkIfFileIsDuplicate(filename); + if (isDuplicate) { + getDuplicateFileNamesList().add(filename); + } + return isDuplicate; + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void toggleProcessButton(final UploadArtifactUIEvent event) { + if (event == UploadArtifactUIEvent.ENABLE_PROCESS_BUTTON) { + processBtn.setEnabled(true); + } else if (event == UploadArtifactUIEvent.DISABLE_PROCESS_BUTTON) { + processBtn.setEnabled(false); + } + } + + /** + * Save uploaded file details. + * + * @param stream + * read from uploaded file + * @param name + * file name + * @param size + * file size + * @param mimeType + * the mimeType of the file + * @throws IOException + * in case of upload errors + */ + OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType) { + File tempFile = null; + try { + tempFile = File.createTempFile("spUiArtifactUpload", null); + + final OutputStream out = new FileOutputStream(tempFile); + + final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); + + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil + .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + + final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), + selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion(), mimeType); + + artifactUploadState.getFileSelected().add(customFile); + processBtn.setEnabled(false); + + if (!artifactUploadState.getBaseSwModuleList().keySet().contains(currentBaseSoftwareModuleKey)) { + artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSoftwareModule); + } + return out; + } catch (final FileNotFoundException e) { + LOG.error("Upload failed {}", e); + throw new ArtifactUploadFailedException(i18n.get("message.file.not.found")); + } catch (final IOException e) { + LOG.error("Upload failed {}", e); + throw new ArtifactUploadFailedException(i18n.get("message.upload.failed")); + } + } + + Boolean validate() { + if (!isSoftwareModuleSelected()) { + uiNotification.displayValidationError(i18n.get("message.error.noSwModuleSelected")); + return false; + } + return true; + } + + SoftwareModule getSoftwareModuleSelected() { + if (artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) { + return artifactUploadState.getSelectedBaseSoftwareModule().get(); + } + return null; + } + + Boolean isSoftwareModuleSelected() { + if (!artifactUploadState.getSelectedBaseSwModuleId().isPresent()) { + return false; + } + return true; + } + + /** + * Check if file selected is duplicate.i,e already selected for upload for + * same software module. + * + * @param name + * file name + * @return Boolean + */ + public Boolean checkIfFileIsDuplicate(final String name) { + Boolean isDuplicate = false; + final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil + .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + + for (final CustomFile customFile : artifactUploadState.getFileSelected()) { + final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( + customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); + if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { + isDuplicate = true; + break; + } + } + return isDuplicate; + } + + void decreaseNumberOfFileUploadsExpected() { + numberOfFileUploadsExpected.decrementAndGet(); + } + + List getDuplicateFileNamesList() { + return duplicateFileNamesList; + } + + /** + * Update pending action count. + */ + void updateActionCount() { + if (!artifactUploadState.getFileSelected().isEmpty()) { + processBtn.setCaption(SPUILabelDefinitions.PROCESS + "
" + + artifactUploadState.getFileSelected().size() + "
"); + } else { + processBtn.setCaption(SPUILabelDefinitions.PROCESS); + } + } + + void displayValidationMessage() { + // check if streaming of all dropped files are completed + if (numberOfFilesActuallyUpload.intValue() == numberOfFileUploadsExpected.intValue()) { + displayCompositeMessage(hasDirectory); + } + } + + /** + * Show duplicate file selected message. + * + * @return duplicate file names + */ + public String showDuplicateMessage() { + if (!duplicateFileNamesList.isEmpty()) { + final String fileNames = StringUtils.collectionToCommaDelimitedString(duplicateFileNamesList); + if (duplicateFileNamesList.size() == 1) { + return i18n.get("message.no.duplicateFile") + fileNames; + + } else if (duplicateFileNamesList.size() > 1) { + return i18n.get("message.no.duplicateFiles"); + } + duplicateFileNamesList.clear(); + } + return null; + } + + void increaseNumberOfFileUploadsExpected() { + numberOfFileUploadsExpected.incrementAndGet(); + } + + void updateFileSize(final String name, final long size) { + final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil + .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + + for (final CustomFile customFile : artifactUploadState.getFileSelected()) { + final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( + customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); + if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { + customFile.setFileSize(size); + break; + } + } + } + + void increaseNumberOfFilesActuallyUpload() { + numberOfFilesActuallyUpload.incrementAndGet(); + } + + /** + * Enable process button once upload is completed. + */ + boolean enableProcessBtn() { + if (numberOfFilesActuallyUpload.intValue() >= numberOfFileUploadsExpected.intValue()) { + processBtn.setEnabled(true); + numberOfFileUploadsExpected.set(0); + numberOfFilesActuallyUpload.set(0); + return true; + } + return false; + } + + Set getFileSelected() { + return artifactUploadState.getFileSelected(); + } + + private void discardUploadData(final Button.ClickEvent event) { + if (event.getButton().equals(discardBtn)) { + if (artifactUploadState.getFileSelected().isEmpty()) { + uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); + + } else { + clearFileList(); + } + } + } + + /** + * Clear details. + */ + void clearFileList() { + // delete file system zombies + artifactUploadState.getFileSelected().forEach(customFile -> { + final File file = new File(customFile.getFilePath()); + file.delete(); + }); + + artifactUploadState.getFileSelected().clear(); + artifactUploadState.getBaseSwModuleList().clear(); + processBtn.setCaption(SPUILabelDefinitions.PROCESS); + /* disable when there is no files to upload. */ + processBtn.setEnabled(false); + numberOfFileUploadsExpected.set(0); + numberOfFilesActuallyUpload.set(0); + duplicateFileNamesList.clear(); + } + + private void setConfirmationPopupHeightWidth(final float newWidth, final float newHeight) { + if (currentUploadConfirmationwindow != null) { + currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth(HawkbitCommonUtil + .getArtifactUploadPopupWidth(newWidth, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), + Unit.PIXELS); + currentUploadConfirmationwindow.getUploadDetailsTable().setHeight(HawkbitCommonUtil + .getArtifactUploadPopupHeight(newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), + Unit.PIXELS); + } + } + + /** + * Set artifact upload result pop up size changes. + * + * @param newWidth + * new width of result pop up + * @param newHeight + * new height of result pop up + */ + void setResultPopupHeightWidth(final float newWidth, final float newHeight) { + if (currentUploadConfirmationwindow != null + && currentUploadConfirmationwindow.getCurrentUploadResultWindow() != null) { + final UploadResultWindow uploadResultWindow = currentUploadConfirmationwindow + .getCurrentUploadResultWindow(); + uploadResultWindow.getUploadResultsWindow().setWidth(HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, + SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); + uploadResultWindow.getUploadResultTable().setHeight(HawkbitCommonUtil.getArtifactUploadPopupHeight( + newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); + } + } + + private void displayConfirmWindow(final Button.ClickEvent event) { + if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_PROCESS_BUTTON)) { + if (artifactUploadState.getFileSelected().isEmpty()) { + uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); + } else { + currentUploadConfirmationwindow = new UploadConfirmationwindow(this, artifactUploadState); + UI.getCurrent().addWindow(currentUploadConfirmationwindow.getUploadConfrimationWindow()); + setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), + Page.getCurrent().getBrowserWindowHeight()); + } + } + } + + /** + * @return + */ + I18N getI18n() { + return i18n; + } + + /** + * @return + */ + SPInfo getSPInfo() { + return spInfo; + } + + void setCurrentUploadConfirmationwindow(final UploadConfirmationwindow currentUploadConfirmationwindow) { + this.currentUploadConfirmationwindow = currentUploadConfirmationwindow; + } + + /** + * @return + */ + + VerticalLayout getDropAreaLayout() { + return dropAreaLayout; + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvent(final UploadArtifactUIEvent event) { + if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) { + ui.access(() -> updateActionCount()); + } + } + + @PreDestroy + void destroy() { + /* + * It's good manners to do this, even though vaadin-spring will + * automatically unsubscribe when this UI is garbage collected. + */ + eventBus.unsubscribe(this); + } + + /** + * set upload status and confirmation window. + * + * @param newWidth + * browser width + * @param newHeight + * browser height + */ + public void setUploadPopupSize(final float newWidth, final float newHeight) { + setConfirmationPopupHeightWidth(newWidth, newHeight); + setResultPopupHeightWidth(newWidth, newHeight); + } + + /** + * @param selectedBaseSoftwareModule + */ + public void refreshArtifactDetailsLayout(final SoftwareModule selectedBaseSoftwareModule) { + eventBus.publish(this, + new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, selectedBaseSoftwareModule)); + } + + /** + * @return the fileUploadLayout + */ + public HorizontalLayout getFileUploadLayout() { + return fileUploadLayout; + } + + public UINotification getUINotification() { + return uiNotification; + } } From 7237e352ff7800b2b7da8063fc1a2e7b5d686c52 Mon Sep 17 00:00:00 2001 From: asharani-murugesh Date: Mon, 8 Feb 2016 11:55:57 +0100 Subject: [PATCH 02/14] Bug fixed Signed-off-by: asharani-murugesh --- .../ui/artifacts/upload/UploadHandler.java | 7 +- .../ui/artifacts/upload/UploadLayout.java | 838 +++++++++--------- 2 files changed, 421 insertions(+), 424 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java index ed4e22ba0..3d7ce0886 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java @@ -89,7 +89,6 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public final OutputStream getOutputStream() { try { - view.getDuplicateFileNamesList().clear(); return view.saveUploadedFileDetails(fileName, fileSize, mimeType); } catch (final ArtifactUploadFailedException e) { LOG.error("Atifact upload failed {} ", e); @@ -109,7 +108,6 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public OutputStream receiveUpload(final String fileName, final String mimeType) { this.fileName = fileName; this.mimeType = mimeType; - view.getDuplicateFileNamesList().clear(); try { if (view.validate()) { if (view.checkForDuplicate(fileName)) { @@ -169,7 +167,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene view.updateActionCount(); // display the duplicate message after streaming all files - view.displayValidationMessage(); + view.displayDuplicateValidationMessage(); } /** @@ -294,7 +292,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene if (view.enableProcessBtn()) { infoWindow.uploadSessionFinished(); } - view.displayValidationMessage(); + view.displayDuplicateValidationMessage(); LOG.info("Streaming failed due to :{}", event.getException()); } @@ -318,7 +316,6 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene } view.updateActionCount(); infoWindow.uploadFailed(event.getFilename(), failureReason); - LOG.info("Upload failed for file :{}", event.getReason()); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index b944006ff..0f9bcd5cc 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -71,123 +71,123 @@ import com.vaadin.ui.VerticalLayout; /** * Upload files layout. * - * @author G Venkata Narayana (RBEI/BSO3) + * */ @ViewScope @SpringComponent public class UploadLayout extends VerticalLayout { - private static final long serialVersionUID = -566164756606779220L; + private static final long serialVersionUID = -566164756606779220L; - private static final Logger LOG = LoggerFactory.getLogger(UploadLayout.class); + private static final Logger LOG = LoggerFactory.getLogger(UploadLayout.class); - @Autowired - private UploadStatusInfoWindow uploadInfoWindow; + @Autowired + private UploadStatusInfoWindow uploadInfoWindow; - @Autowired - private I18N i18n; + @Autowired + private I18N i18n; - @Autowired - private transient UINotification uiNotification; + @Autowired + private transient UINotification uiNotification; - @Autowired - private transient EventBus.SessionEventBus eventBus; + @Autowired + private transient EventBus.SessionEventBus eventBus; - @Autowired - private ArtifactUploadState artifactUploadState; + @Autowired + private ArtifactUploadState artifactUploadState; - @Autowired - private transient SPInfo spInfo; + @Autowired + private transient SPInfo spInfo; - private final AtomicInteger numberOfFileUploadsExpected = new AtomicInteger(); + private final AtomicInteger numberOfFileUploadsExpected = new AtomicInteger(); - private final AtomicInteger numberOfFilesActuallyUpload = new AtomicInteger(); + private final AtomicInteger numberOfFilesActuallyUpload = new AtomicInteger(); - private final List duplicateFileNamesList = new ArrayList(); + private final List duplicateFileNamesList = new ArrayList(); - private Button processBtn; + private Button processBtn; - private Button discardBtn; + private Button discardBtn; - private UploadConfirmationwindow currentUploadConfirmationwindow; + private UploadConfirmationwindow currentUploadConfirmationwindow; - private VerticalLayout dropAreaLayout; + private VerticalLayout dropAreaLayout; - private UI ui; + private UI ui; - private HorizontalLayout fileUploadLayout; + private HorizontalLayout fileUploadLayout; - private DragAndDropWrapper dropAreaWrapper; + private DragAndDropWrapper dropAreaWrapper; private Boolean hasDirectory = Boolean.FALSE; - /** - * Initialize the upload layout. - */ - @PostConstruct - void init() { - createComponents(); - buildLayout(); - updateActionCount(); - eventBus.subscribe(this); - ui = UI.getCurrent(); - } + /** + * Initialize the upload layout. + */ + @PostConstruct + void init() { + createComponents(); + buildLayout(); + updateActionCount(); + eventBus.subscribe(this); + ui = UI.getCurrent(); + } - private void createComponents() { + private void createComponents() { - createProcessButton(); - createDiscardBtn(); - } + createProcessButton(); + createDiscardBtn(); + } - private void buildLayout() { + private void buildLayout() { - final Upload upload = new Upload(); - final UploadHandler uploadHandler = new UploadHandler(null, 0, this, uploadInfoWindow, - spInfo.getMaxArtifactFileSize(), upload, null); - upload.setButtonCaption(i18n.get("upload.file")); - upload.setImmediate(true); - upload.setReceiver(uploadHandler); - upload.addSucceededListener(uploadHandler); - upload.addFailedListener(uploadHandler); - upload.addFinishedListener(uploadHandler); - upload.addProgressListener(uploadHandler); - upload.addStartedListener(uploadHandler); - upload.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); + final Upload upload = new Upload(); + final UploadHandler uploadHandler = new UploadHandler(null, 0, this, uploadInfoWindow, + spInfo.getMaxArtifactFileSize(), upload, null); + upload.setButtonCaption(i18n.get("upload.file")); + upload.setImmediate(true); + upload.setReceiver(uploadHandler); + upload.addSucceededListener(uploadHandler); + upload.addFailedListener(uploadHandler); + upload.addFinishedListener(uploadHandler); + upload.addProgressListener(uploadHandler); + upload.addStartedListener(uploadHandler); + upload.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - fileUploadLayout = new HorizontalLayout(); - fileUploadLayout.setSpacing(true); - fileUploadLayout.addComponent(upload); - fileUploadLayout.setComponentAlignment(upload, Alignment.MIDDLE_LEFT); - fileUploadLayout.addComponent(processBtn); - fileUploadLayout.setComponentAlignment(processBtn, Alignment.MIDDLE_RIGHT); - fileUploadLayout.addComponent(discardBtn); - fileUploadLayout.setComponentAlignment(discardBtn, Alignment.MIDDLE_RIGHT); - setMargin(false); + fileUploadLayout = new HorizontalLayout(); + fileUploadLayout.setSpacing(true); + fileUploadLayout.addComponent(upload); + fileUploadLayout.setComponentAlignment(upload, Alignment.MIDDLE_LEFT); + fileUploadLayout.addComponent(processBtn); + fileUploadLayout.setComponentAlignment(processBtn, Alignment.MIDDLE_RIGHT); + fileUploadLayout.addComponent(discardBtn); + fileUploadLayout.setComponentAlignment(discardBtn, Alignment.MIDDLE_RIGHT); + setMargin(false); - /* create drag-drop wrapper for drop area */ - dropAreaWrapper = new DragAndDropWrapper(createDropAreaLayout()); - dropAreaWrapper.setDropHandler(new DropAreahandler()); - setSizeFull(); - setSpacing(true); + /* create drag-drop wrapper for drop area */ + dropAreaWrapper = new DragAndDropWrapper(createDropAreaLayout()); + dropAreaWrapper.setDropHandler(new DropAreahandler()); + setSizeFull(); + setSpacing(true); - } + } - public DragAndDropWrapper getDropAreaWrapper() { - return dropAreaWrapper; - } + public DragAndDropWrapper getDropAreaWrapper() { + return dropAreaWrapper; + } - private class DropAreahandler implements DropHandler { + private class DropAreahandler implements DropHandler { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - @Override - public AcceptCriterion getAcceptCriterion() { - return AcceptAll.get(); - } + @Override + public AcceptCriterion getAcceptCriterion() { + return AcceptAll.get(); + } - @Override - public void drop(final DragAndDropEvent event) { - if (validate()) { + @Override + public void drop(final DragAndDropEvent event) { + if (validate()) { ((WrapperTransferable) event.getTransferable()).getDraggedComponent(); final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); if (files != null) { @@ -207,12 +207,12 @@ public class UploadLayout extends VerticalLayout { uploadInfoWindow.uploadSessionStarted(); } else { //If the upload is not started, it signifies all dropped files as either duplicate or directory.So display message accordingly - displayCompositeMessage(hasDirectory); + displayCompositeMessage(); } } } - } - } + } + } private static boolean isDirectory(final Html5File file) { if (Strings.isNullOrEmpty(file.getType()) && file.getFileSize() % 4096 == 0) { @@ -221,12 +221,10 @@ public class UploadLayout extends VerticalLayout { return false; } - private void displayCompositeMessage(final Boolean hasDirectory) { - final String duplicateMessage = showDuplicateMessage(); + private void displayCompositeMessage() { + final String duplicateMessage = getDuplicateFileValidationMessage(); final StringBuilder compositeMessage = new StringBuilder(); - if (null != duplicateMessage) { - // in case if all selected files are duplicate ,then display - // messag + if (!Strings.isNullOrEmpty(duplicateMessage)) { compositeMessage.append(duplicateMessage); } if (hasDirectory) { @@ -239,395 +237,397 @@ public class UploadLayout extends VerticalLayout { uiNotification.displayValidationError(compositeMessage.toString()); } } + + private VerticalLayout createDropAreaLayout() { + dropAreaLayout = new VerticalLayout(); + final Label dropHereLabel = new Label("Drop files to upload"); + dropHereLabel.setWidth(null); - private VerticalLayout createDropAreaLayout() { - dropAreaLayout = new VerticalLayout(); - final Label dropHereLabel = new Label("Drop files to upload"); - dropHereLabel.setWidth(null); + final Label dropIcon = new Label(FontAwesome.ARROW_DOWN.getHtml(), ContentMode.HTML); + dropIcon.addStyleName("drop-icon"); + dropIcon.setWidth(null); - final Label dropIcon = new Label(FontAwesome.ARROW_DOWN.getHtml(), ContentMode.HTML); - dropIcon.addStyleName("drop-icon"); - dropIcon.setWidth(null); + dropAreaLayout.addComponent(dropIcon); + dropAreaLayout.setComponentAlignment(dropIcon, Alignment.BOTTOM_CENTER); + dropAreaLayout.addComponent(dropHereLabel); + dropAreaLayout.setComponentAlignment(dropHereLabel, Alignment.TOP_CENTER); + dropAreaLayout.setSizeFull(); + dropAreaLayout.setStyleName("upload-drop-area-layout-info"); + dropAreaLayout.setSpacing(false); + return dropAreaLayout; + } - dropAreaLayout.addComponent(dropIcon); - dropAreaLayout.setComponentAlignment(dropIcon, Alignment.BOTTOM_CENTER); - dropAreaLayout.addComponent(dropHereLabel); - dropAreaLayout.setComponentAlignment(dropHereLabel, Alignment.TOP_CENTER); - dropAreaLayout.setSizeFull(); - dropAreaLayout.setStyleName("upload-drop-area-layout-info"); - dropAreaLayout.setSpacing(false); - return dropAreaLayout; - } + private void createProcessButton() { + processBtn = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_PROCESS_BUTTON, + SPUILabelDefinitions.PROCESS, SPUILabelDefinitions.PROCESS, null, false, null, + SPUIButtonStyleSmall.class); + processBtn.setIcon(FontAwesome.BELL); + processBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); + processBtn.addClickListener(event -> displayConfirmWindow(event)); + processBtn.setHtmlContentAllowed(true); + if (artifactUploadState.getFileSelected().isEmpty()) { + processBtn.setEnabled(false); + } + } - private void createProcessButton() { - processBtn = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_PROCESS_BUTTON, - SPUILabelDefinitions.PROCESS, SPUILabelDefinitions.PROCESS, null, false, null, - SPUIButtonStyleSmall.class); - processBtn.setIcon(FontAwesome.BELL); - processBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - processBtn.addClickListener(event -> displayConfirmWindow(event)); - processBtn.setHtmlContentAllowed(true); - if (artifactUploadState.getFileSelected().isEmpty()) { - processBtn.setEnabled(false); - } - } + private void createDiscardBtn() { + discardBtn = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_DISCARD_BUTTON, + SPUILabelDefinitions.DISCARD, SPUILabelDefinitions.DISCARD, null, false, null, + SPUIButtonStyleSmall.class); + discardBtn.setIcon(FontAwesome.TRASH_O); + discardBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); + discardBtn.addClickListener(event -> discardUploadData(event)); + } - private void createDiscardBtn() { - discardBtn = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_DISCARD_BUTTON, - SPUILabelDefinitions.DISCARD, SPUILabelDefinitions.DISCARD, null, false, null, - SPUIButtonStyleSmall.class); - discardBtn.setIcon(FontAwesome.TRASH_O); - discardBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - discardBtn.addClickListener(event -> discardUploadData(event)); - } + private StreamVariable createStreamVariable(final Html5File file) { + return new UploadHandler(file.getFileName(), file.getFileSize(), this, uploadInfoWindow, + spInfo.getMaxArtifactFileSize(), null, file.getType()); + } - private StreamVariable createStreamVariable(final Html5File file) { - return new UploadHandler(file.getFileName(), file.getFileSize(), this, uploadInfoWindow, - spInfo.getMaxArtifactFileSize(), null, file.getType()); - } + boolean checkForDuplicate(final String filename) { + final Boolean isDuplicate = checkIfFileIsDuplicate(filename); + if (isDuplicate) { + getDuplicateFileNamesList().add(filename); + } + return isDuplicate; + } - boolean checkForDuplicate(final String filename) { - final Boolean isDuplicate = checkIfFileIsDuplicate(filename); - if (isDuplicate) { - getDuplicateFileNamesList().add(filename); - } - return isDuplicate; - } + @EventBusListenerMethod(scope = EventScope.SESSION) + void toggleProcessButton(final UploadArtifactUIEvent event) { + if (event == UploadArtifactUIEvent.ENABLE_PROCESS_BUTTON) { + processBtn.setEnabled(true); + } else if (event == UploadArtifactUIEvent.DISABLE_PROCESS_BUTTON) { + processBtn.setEnabled(false); + } + } - @EventBusListenerMethod(scope = EventScope.SESSION) - void toggleProcessButton(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.ENABLE_PROCESS_BUTTON) { - processBtn.setEnabled(true); - } else if (event == UploadArtifactUIEvent.DISABLE_PROCESS_BUTTON) { - processBtn.setEnabled(false); - } - } + /** + * Save uploaded file details. + * + * @param stream + * read from uploaded file + * @param name + * file name + * @param size + * file size + * @param mimeType + * the mimeType of the file + * @throws IOException + * in case of upload errors + */ + OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType) { + File tempFile = null; + try { + tempFile = File.createTempFile("spUiArtifactUpload", null); - /** - * Save uploaded file details. - * - * @param stream - * read from uploaded file - * @param name - * file name - * @param size - * file size - * @param mimeType - * the mimeType of the file - * @throws IOException - * in case of upload errors - */ - OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType) { - File tempFile = null; - try { - tempFile = File.createTempFile("spUiArtifactUpload", null); + final OutputStream out = new FileOutputStream(tempFile); - final OutputStream out = new FileOutputStream(tempFile); + final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil + .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), + selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion(), mimeType); - final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), - selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion(), mimeType); + artifactUploadState.getFileSelected().add(customFile); + processBtn.setEnabled(false); - artifactUploadState.getFileSelected().add(customFile); - processBtn.setEnabled(false); + if (!artifactUploadState.getBaseSwModuleList().keySet().contains(currentBaseSoftwareModuleKey)) { + artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSoftwareModule); + } + return out; + } catch (final FileNotFoundException e) { + LOG.error("Upload failed {}", e); + throw new ArtifactUploadFailedException(i18n.get("message.file.not.found")); + } catch (final IOException e) { + LOG.error("Upload failed {}", e); + throw new ArtifactUploadFailedException(i18n.get("message.upload.failed")); + } + } - if (!artifactUploadState.getBaseSwModuleList().keySet().contains(currentBaseSoftwareModuleKey)) { - artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSoftwareModule); - } - return out; - } catch (final FileNotFoundException e) { - LOG.error("Upload failed {}", e); - throw new ArtifactUploadFailedException(i18n.get("message.file.not.found")); - } catch (final IOException e) { - LOG.error("Upload failed {}", e); - throw new ArtifactUploadFailedException(i18n.get("message.upload.failed")); - } - } + Boolean validate() { + if (!isSoftwareModuleSelected()) { + uiNotification.displayValidationError(i18n.get("message.error.noSwModuleSelected")); - Boolean validate() { - if (!isSoftwareModuleSelected()) { - uiNotification.displayValidationError(i18n.get("message.error.noSwModuleSelected")); - return false; - } - return true; - } + return false; + } + return true; + } - SoftwareModule getSoftwareModuleSelected() { - if (artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) { - return artifactUploadState.getSelectedBaseSoftwareModule().get(); - } - return null; - } + SoftwareModule getSoftwareModuleSelected() { + if (artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) { + return artifactUploadState.getSelectedBaseSoftwareModule().get(); + } + return null; + } - Boolean isSoftwareModuleSelected() { - if (!artifactUploadState.getSelectedBaseSwModuleId().isPresent()) { - return false; - } - return true; - } + Boolean isSoftwareModuleSelected() { + if (!artifactUploadState.getSelectedBaseSwModuleId().isPresent()) { + return false; + } + return true; + } - /** - * Check if file selected is duplicate.i,e already selected for upload for - * same software module. - * - * @param name - * file name - * @return Boolean - */ - public Boolean checkIfFileIsDuplicate(final String name) { - Boolean isDuplicate = false; - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + /** + * Check if file selected is duplicate.i,e already selected for upload for + * same software module. + * + * @param name + * file name + * @return Boolean + */ + public Boolean checkIfFileIsDuplicate(final String name) { + Boolean isDuplicate = false; + final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil + .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); - for (final CustomFile customFile : artifactUploadState.getFileSelected()) { - final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { - isDuplicate = true; - break; - } - } - return isDuplicate; - } + for (final CustomFile customFile : artifactUploadState.getFileSelected()) { + final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( + customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); + if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { + isDuplicate = true; + break; + } + } + return isDuplicate; + } - void decreaseNumberOfFileUploadsExpected() { - numberOfFileUploadsExpected.decrementAndGet(); - } + void decreaseNumberOfFileUploadsExpected() { + numberOfFileUploadsExpected.decrementAndGet(); + } - List getDuplicateFileNamesList() { - return duplicateFileNamesList; - } + List getDuplicateFileNamesList() { + return duplicateFileNamesList; + } - /** - * Update pending action count. - */ - void updateActionCount() { - if (!artifactUploadState.getFileSelected().isEmpty()) { - processBtn.setCaption(SPUILabelDefinitions.PROCESS + "
" - + artifactUploadState.getFileSelected().size() + "
"); - } else { - processBtn.setCaption(SPUILabelDefinitions.PROCESS); - } - } + /** + * Update pending action count. + */ + void updateActionCount() { + if (!artifactUploadState.getFileSelected().isEmpty()) { + processBtn.setCaption(SPUILabelDefinitions.PROCESS + "
" + + artifactUploadState.getFileSelected().size() + "
"); + } else { + processBtn.setCaption(SPUILabelDefinitions.PROCESS); + } + } - void displayValidationMessage() { - // check if streaming of all dropped files are completed - if (numberOfFilesActuallyUpload.intValue() == numberOfFileUploadsExpected.intValue()) { - displayCompositeMessage(hasDirectory); - } - } + void displayDuplicateValidationMessage() { + // check if streaming of all dropped files are completed + if (numberOfFilesActuallyUpload.intValue() == numberOfFileUploadsExpected.intValue()) { + displayCompositeMessage(); + } + } + - /** - * Show duplicate file selected message. - * - * @return duplicate file names - */ - public String showDuplicateMessage() { + private String getDuplicateFileValidationMessage() { + StringBuilder message = new StringBuilder(); if (!duplicateFileNamesList.isEmpty()) { final String fileNames = StringUtils.collectionToCommaDelimitedString(duplicateFileNamesList); if (duplicateFileNamesList.size() == 1) { - return i18n.get("message.no.duplicateFile") + fileNames; + message.append(i18n.get("message.no.duplicateFile") + fileNames); } else if (duplicateFileNamesList.size() > 1) { - return i18n.get("message.no.duplicateFiles"); + message.append(i18n.get("message.no.duplicateFiles")); } duplicateFileNamesList.clear(); } - return null; + return message.toString(); } - void increaseNumberOfFileUploadsExpected() { - numberOfFileUploadsExpected.incrementAndGet(); + public void showDuplicateMessage() { + uiNotification.displayValidationError(getDuplicateFileValidationMessage()); } + + void increaseNumberOfFileUploadsExpected() { + numberOfFileUploadsExpected.incrementAndGet(); + } - void updateFileSize(final String name, final long size) { - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + void updateFileSize(final String name, final long size) { + final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil + .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); - for (final CustomFile customFile : artifactUploadState.getFileSelected()) { - final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { - customFile.setFileSize(size); - break; - } - } - } + for (final CustomFile customFile : artifactUploadState.getFileSelected()) { + final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( + customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); + if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { + customFile.setFileSize(size); + break; + } + } + } - void increaseNumberOfFilesActuallyUpload() { - numberOfFilesActuallyUpload.incrementAndGet(); - } + void increaseNumberOfFilesActuallyUpload() { + numberOfFilesActuallyUpload.incrementAndGet(); + } - /** - * Enable process button once upload is completed. - */ - boolean enableProcessBtn() { - if (numberOfFilesActuallyUpload.intValue() >= numberOfFileUploadsExpected.intValue()) { - processBtn.setEnabled(true); - numberOfFileUploadsExpected.set(0); - numberOfFilesActuallyUpload.set(0); - return true; - } - return false; - } + /** + * Enable process button once upload is completed. + */ + boolean enableProcessBtn() { + if (numberOfFilesActuallyUpload.intValue() >= numberOfFileUploadsExpected.intValue()) { + processBtn.setEnabled(true); + numberOfFileUploadsExpected.set(0); + numberOfFilesActuallyUpload.set(0); + return true; + } + return false; + } - Set getFileSelected() { - return artifactUploadState.getFileSelected(); - } + Set getFileSelected() { + return artifactUploadState.getFileSelected(); + } - private void discardUploadData(final Button.ClickEvent event) { - if (event.getButton().equals(discardBtn)) { - if (artifactUploadState.getFileSelected().isEmpty()) { - uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); + private void discardUploadData(final Button.ClickEvent event) { + if (event.getButton().equals(discardBtn)) { + if (artifactUploadState.getFileSelected().isEmpty()) { + uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); - } else { - clearFileList(); - } - } - } + } else { + clearFileList(); + } + } + } - /** - * Clear details. - */ - void clearFileList() { - // delete file system zombies - artifactUploadState.getFileSelected().forEach(customFile -> { - final File file = new File(customFile.getFilePath()); - file.delete(); - }); + /** + * Clear details. + */ + void clearFileList() { + // delete file system zombies + artifactUploadState.getFileSelected().forEach(customFile -> { + final File file = new File(customFile.getFilePath()); + file.delete(); + }); - artifactUploadState.getFileSelected().clear(); - artifactUploadState.getBaseSwModuleList().clear(); - processBtn.setCaption(SPUILabelDefinitions.PROCESS); - /* disable when there is no files to upload. */ - processBtn.setEnabled(false); - numberOfFileUploadsExpected.set(0); - numberOfFilesActuallyUpload.set(0); - duplicateFileNamesList.clear(); - } + artifactUploadState.getFileSelected().clear(); + artifactUploadState.getBaseSwModuleList().clear(); + processBtn.setCaption(SPUILabelDefinitions.PROCESS); + /* disable when there is no files to upload. */ + processBtn.setEnabled(false); + numberOfFileUploadsExpected.set(0); + numberOfFilesActuallyUpload.set(0); + duplicateFileNamesList.clear(); + } - private void setConfirmationPopupHeightWidth(final float newWidth, final float newHeight) { - if (currentUploadConfirmationwindow != null) { - currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth(HawkbitCommonUtil - .getArtifactUploadPopupWidth(newWidth, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), - Unit.PIXELS); - currentUploadConfirmationwindow.getUploadDetailsTable().setHeight(HawkbitCommonUtil - .getArtifactUploadPopupHeight(newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), - Unit.PIXELS); - } - } + private void setConfirmationPopupHeightWidth(final float newWidth, final float newHeight) { + if (currentUploadConfirmationwindow != null) { + currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth(HawkbitCommonUtil + .getArtifactUploadPopupWidth(newWidth, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), + Unit.PIXELS); + currentUploadConfirmationwindow.getUploadDetailsTable().setHeight(HawkbitCommonUtil + .getArtifactUploadPopupHeight(newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), + Unit.PIXELS); + } + } - /** - * Set artifact upload result pop up size changes. - * - * @param newWidth - * new width of result pop up - * @param newHeight - * new height of result pop up - */ - void setResultPopupHeightWidth(final float newWidth, final float newHeight) { - if (currentUploadConfirmationwindow != null - && currentUploadConfirmationwindow.getCurrentUploadResultWindow() != null) { - final UploadResultWindow uploadResultWindow = currentUploadConfirmationwindow - .getCurrentUploadResultWindow(); - uploadResultWindow.getUploadResultsWindow().setWidth(HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, - SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); - uploadResultWindow.getUploadResultTable().setHeight(HawkbitCommonUtil.getArtifactUploadPopupHeight( - newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); - } - } + /** + * Set artifact upload result pop up size changes. + * + * @param newWidth + * new width of result pop up + * @param newHeight + * new height of result pop up + */ + void setResultPopupHeightWidth(final float newWidth, final float newHeight) { + if (currentUploadConfirmationwindow != null + && currentUploadConfirmationwindow.getCurrentUploadResultWindow() != null) { + final UploadResultWindow uploadResultWindow = currentUploadConfirmationwindow + .getCurrentUploadResultWindow(); + uploadResultWindow.getUploadResultsWindow().setWidth(HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, + SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); + uploadResultWindow.getUploadResultTable().setHeight(HawkbitCommonUtil.getArtifactUploadPopupHeight( + newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); + } + } - private void displayConfirmWindow(final Button.ClickEvent event) { - if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_PROCESS_BUTTON)) { - if (artifactUploadState.getFileSelected().isEmpty()) { - uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); - } else { - currentUploadConfirmationwindow = new UploadConfirmationwindow(this, artifactUploadState); - UI.getCurrent().addWindow(currentUploadConfirmationwindow.getUploadConfrimationWindow()); - setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), - Page.getCurrent().getBrowserWindowHeight()); - } - } - } + private void displayConfirmWindow(final Button.ClickEvent event) { + if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_PROCESS_BUTTON)) { + if (artifactUploadState.getFileSelected().isEmpty()) { + uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); + } else { + currentUploadConfirmationwindow = new UploadConfirmationwindow(this, artifactUploadState); + UI.getCurrent().addWindow(currentUploadConfirmationwindow.getUploadConfrimationWindow()); + setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), + Page.getCurrent().getBrowserWindowHeight()); + } + } + } - /** - * @return - */ - I18N getI18n() { - return i18n; - } + /** + * @return + */ + I18N getI18n() { + return i18n; + } - /** - * @return - */ - SPInfo getSPInfo() { - return spInfo; - } + /** + * @return + */ + SPInfo getSPInfo() { + return spInfo; + } - void setCurrentUploadConfirmationwindow(final UploadConfirmationwindow currentUploadConfirmationwindow) { - this.currentUploadConfirmationwindow = currentUploadConfirmationwindow; - } + void setCurrentUploadConfirmationwindow(final UploadConfirmationwindow currentUploadConfirmationwindow) { + this.currentUploadConfirmationwindow = currentUploadConfirmationwindow; + } - /** - * @return - */ + /** + * @return + */ - VerticalLayout getDropAreaLayout() { - return dropAreaLayout; - } + VerticalLayout getDropAreaLayout() { + return dropAreaLayout; + } - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) { - ui.access(() -> updateActionCount()); - } - } + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvent(final UploadArtifactUIEvent event) { + if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) { + ui.access(() -> updateActionCount()); + } + } - @PreDestroy - void destroy() { - /* - * It's good manners to do this, even though vaadin-spring will - * automatically unsubscribe when this UI is garbage collected. - */ - eventBus.unsubscribe(this); - } + @PreDestroy + void destroy() { + /* + * It's good manners to do this, even though vaadin-spring will + * automatically unsubscribe when this UI is garbage collected. + */ + eventBus.unsubscribe(this); + } - /** - * set upload status and confirmation window. - * - * @param newWidth - * browser width - * @param newHeight - * browser height - */ - public void setUploadPopupSize(final float newWidth, final float newHeight) { - setConfirmationPopupHeightWidth(newWidth, newHeight); - setResultPopupHeightWidth(newWidth, newHeight); - } + /** + * set upload status and confirmation window. + * + * @param newWidth + * browser width + * @param newHeight + * browser height + */ + public void setUploadPopupSize(final float newWidth, final float newHeight) { + setConfirmationPopupHeightWidth(newWidth, newHeight); + setResultPopupHeightWidth(newWidth, newHeight); + } - /** - * @param selectedBaseSoftwareModule - */ - public void refreshArtifactDetailsLayout(final SoftwareModule selectedBaseSoftwareModule) { - eventBus.publish(this, - new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, selectedBaseSoftwareModule)); - } + /** + * @param selectedBaseSoftwareModule + */ + public void refreshArtifactDetailsLayout(final SoftwareModule selectedBaseSoftwareModule) { + eventBus.publish(this, + new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, selectedBaseSoftwareModule)); + } - /** - * @return the fileUploadLayout - */ - public HorizontalLayout getFileUploadLayout() { - return fileUploadLayout; - } + /** + * @return the fileUploadLayout + */ + public HorizontalLayout getFileUploadLayout() { + return fileUploadLayout; + } - public UINotification getUINotification() { - return uiNotification; - } + public UINotification getUINotification() { + return uiNotification; + } } From d3035ccebe7969b34a1552f516078ee1d6e9afb3 Mon Sep 17 00:00:00 2001 From: asharani-murugesh Date: Mon, 8 Feb 2016 13:20:50 +0100 Subject: [PATCH 03/14] modified error message Signed-off-by: asharani-murugesh --- .../org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java | 1 + hawkbit-ui/src/main/resources/messages.properties | 2 +- hawkbit-ui/src/main/resources/messages_de.properties | 2 +- hawkbit-ui/src/main/resources/messages_en.properties | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index 0f9bcd5cc..1737d0495 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -196,6 +196,7 @@ public class UploadLayout extends VerticalLayout { if (!checkForDuplicate(file.getFileName())) { numberOfFileUploadsExpected.incrementAndGet(); file.setStreamVariable(createStreamVariable(file)); + hasDirectory = Boolean.FALSE; } } else { hasDirectory = Boolean.TRUE; diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index 8e785c3db..168920f52 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -308,7 +308,7 @@ soft.module.os =OS message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name message.error.noSwModuleSelected = Please select a software module -message.no.duplicateFiles = duplicate files selected +message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name diff --git a/hawkbit-ui/src/main/resources/messages_de.properties b/hawkbit-ui/src/main/resources/messages_de.properties index 94a0df4cf..62088946a 100644 --- a/hawkbit-ui/src/main/resources/messages_de.properties +++ b/hawkbit-ui/src/main/resources/messages_de.properties @@ -305,7 +305,7 @@ soft.module.os =OS message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name message.error.noSwModuleSelected = Please select a software module -message.no.duplicateFiles = duplicate files selected +message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name diff --git a/hawkbit-ui/src/main/resources/messages_en.properties b/hawkbit-ui/src/main/resources/messages_en.properties index d31ca2af3..075347f12 100644 --- a/hawkbit-ui/src/main/resources/messages_en.properties +++ b/hawkbit-ui/src/main/resources/messages_en.properties @@ -299,7 +299,7 @@ soft.module.os =OS message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name message.error.noSwModuleSelected = Please select a software module -message.no.duplicateFiles = duplicate files selected +message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name From 1252bfe53dcdec535d917128ed1fe5582d5bc82f Mon Sep 17 00:00:00 2001 From: asharani-murugesh Date: Tue, 16 Feb 2016 09:29:17 +0100 Subject: [PATCH 04/14] Formatted Signed-off-by: asharani-murugesh --- .../ui/artifacts/upload/UploadLayout.java | 135 +++++++++--------- 1 file changed, 68 insertions(+), 67 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index 1737d0495..2e8c6a51e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -119,7 +119,7 @@ public class UploadLayout extends VerticalLayout { private DragAndDropWrapper dropAreaWrapper; - private Boolean hasDirectory = Boolean.FALSE; + private Boolean hasDirectory = Boolean.FALSE; /** * Initialize the upload layout. @@ -187,58 +187,60 @@ public class UploadLayout extends VerticalLayout { @Override public void drop(final DragAndDropEvent event) { - if (validate()) { - ((WrapperTransferable) event.getTransferable()).getDraggedComponent(); - final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); - if (files != null) { - for (final Html5File file : files) { - if (!isDirectory(file)) { - if (!checkForDuplicate(file.getFileName())) { - numberOfFileUploadsExpected.incrementAndGet(); - file.setStreamVariable(createStreamVariable(file)); - hasDirectory = Boolean.FALSE; - } - } else { - hasDirectory = Boolean.TRUE; - } - } - if (numberOfFileUploadsExpected.get() > 0) { - processBtn.setEnabled(false); - // reset before we start - uploadInfoWindow.uploadSessionStarted(); - } else { - //If the upload is not started, it signifies all dropped files as either duplicate or directory.So display message accordingly - displayCompositeMessage(); - } - } - } + if (validate()) { + ((WrapperTransferable) event.getTransferable()).getDraggedComponent(); + final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); + if (files != null) { + for (final Html5File file : files) { + if (!isDirectory(file)) { + if (!checkForDuplicate(file.getFileName())) { + numberOfFileUploadsExpected.incrementAndGet(); + file.setStreamVariable(createStreamVariable(file)); + hasDirectory = Boolean.FALSE; + } + } else { + hasDirectory = Boolean.TRUE; + } + } + if (numberOfFileUploadsExpected.get() > 0) { + processBtn.setEnabled(false); + // reset before we start + uploadInfoWindow.uploadSessionStarted(); + } else { + // If the upload is not started, it signifies all + // dropped files as either duplicate or directory.So + // display message accordingly + displayCompositeMessage(); + } + } + } } } - private static boolean isDirectory(final Html5File file) { - if (Strings.isNullOrEmpty(file.getType()) && file.getFileSize() % 4096 == 0) { - return true; - } - return false; - } + private static boolean isDirectory(final Html5File file) { + if (Strings.isNullOrEmpty(file.getType()) && file.getFileSize() % 4096 == 0) { + return true; + } + return false; + } + + private void displayCompositeMessage() { + final String duplicateMessage = getDuplicateFileValidationMessage(); + final StringBuilder compositeMessage = new StringBuilder(); + if (!Strings.isNullOrEmpty(duplicateMessage)) { + compositeMessage.append(duplicateMessage); + } + if (hasDirectory) { + if (compositeMessage.length() > 0) { + compositeMessage.append("
"); + } + compositeMessage.append(i18n.get("message.no.directory.upload")); + } + if (!compositeMessage.toString().isEmpty()) { + uiNotification.displayValidationError(compositeMessage.toString()); + } + } - private void displayCompositeMessage() { - final String duplicateMessage = getDuplicateFileValidationMessage(); - final StringBuilder compositeMessage = new StringBuilder(); - if (!Strings.isNullOrEmpty(duplicateMessage)) { - compositeMessage.append(duplicateMessage); - } - if (hasDirectory) { - if (compositeMessage.length() > 0) { - compositeMessage.append("
"); - } - compositeMessage.append(i18n.get("message.no.directory.upload")); - } - if (!compositeMessage.toString().isEmpty()) { - uiNotification.displayValidationError(compositeMessage.toString()); - } - } - private VerticalLayout createDropAreaLayout() { dropAreaLayout = new VerticalLayout(); final Label dropHereLabel = new Label("Drop files to upload"); @@ -421,27 +423,26 @@ public class UploadLayout extends VerticalLayout { displayCompositeMessage(); } } - - private String getDuplicateFileValidationMessage() { - StringBuilder message = new StringBuilder(); - if (!duplicateFileNamesList.isEmpty()) { - final String fileNames = StringUtils.collectionToCommaDelimitedString(duplicateFileNamesList); - if (duplicateFileNamesList.size() == 1) { - message.append(i18n.get("message.no.duplicateFile") + fileNames); + private String getDuplicateFileValidationMessage() { + StringBuilder message = new StringBuilder(); + if (!duplicateFileNamesList.isEmpty()) { + final String fileNames = StringUtils.collectionToCommaDelimitedString(duplicateFileNamesList); + if (duplicateFileNamesList.size() == 1) { + message.append(i18n.get("message.no.duplicateFile") + fileNames); - } else if (duplicateFileNamesList.size() > 1) { - message.append(i18n.get("message.no.duplicateFiles")); - } - duplicateFileNamesList.clear(); - } - return message.toString(); - } + } else if (duplicateFileNamesList.size() > 1) { + message.append(i18n.get("message.no.duplicateFiles")); + } + duplicateFileNamesList.clear(); + } + return message.toString(); + } + + public void showDuplicateMessage() { + uiNotification.displayValidationError(getDuplicateFileValidationMessage()); + } - public void showDuplicateMessage() { - uiNotification.displayValidationError(getDuplicateFileValidationMessage()); - } - void increaseNumberOfFileUploadsExpected() { numberOfFileUploadsExpected.incrementAndGet(); } From f969d6f4c2f06e564abf1cae66e775c493209f99 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 25 Feb 2016 14:38:25 +0100 Subject: [PATCH 05/14] clean code refactorings - add description to assertions in unit tests - make inner classes static - remove out-commented code Signed-off-by: Michael Hirsch --- .../AmqpMessageDispatcherServiceTest.java | 43 ++++++++++------ .../event/AbstractPropertyChangeEvent.java | 2 +- .../repository/ArtifactManagementTest.java | 8 +-- .../repository/SoftwareManagementTest.java | 50 +++++++++---------- .../repository/rsql/RSQLActionFieldsTest.java | 2 +- .../repository/rsql/RSQLUtilityTest.java | 16 +++--- .../rest/resource/SoftwareModuleResource.java | 46 ----------------- .../resource/model/ExceptionInfoTest.java | 13 +++-- ...ExcludePathAwareShallowETagFilterTest.java | 3 +- .../org/eclipse/hawkbit/util/IpUtilTest.java | 38 ++++++++------ 10 files changed, 99 insertions(+), 122 deletions(-) diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java index 348e8dea4..4d313dd2c 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java @@ -91,7 +91,8 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress().getHost()); final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage); - assertTrue(downloadAndUpdateRequest.getSoftwareModules().isEmpty()); + assertTrue("No softwaremmodule should be contained in the request", + downloadAndUpdateRequest.getSoftwareModules().isEmpty()); } @Test @@ -104,17 +105,22 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress().getHost()); final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage); - assertEquals(3, downloadAndUpdateRequest.getSoftwareModules().size()); + assertEquals("Expecting a size of 3 software modules in the reuqest", 3, + downloadAndUpdateRequest.getSoftwareModules().size()); for (final org.eclipse.hawkbit.dmf.json.model.SoftwareModule softwareModule : downloadAndUpdateRequest .getSoftwareModules()) { - assertTrue(softwareModule.getArtifacts().isEmpty()); + assertTrue("Artifact list for softwaremodule should be empty", softwareModule.getArtifacts().isEmpty()); for (final SoftwareModule softwareModule2 : dsA.getModules()) { - assertNotNull(softwareModule.getModuleId()); + assertNotNull("Sofware module ID should be set", softwareModule.getModuleId()); if (!softwareModule.getModuleId().equals(softwareModule2.getId())) { continue; } - assertEquals(softwareModule.getModuleType(), softwareModule2.getType().getKey()); - assertEquals(softwareModule.getModuleVersion(), softwareModule2.getVersion()); + assertEquals( + "Software module type in event should be the same as the softwaremodule in the distribution set", + softwareModule.getModuleType(), softwareModule2.getType().getKey()); + assertEquals( + "Software module version in event should be the same as the softwaremodule in the distribution set", + softwareModule.getModuleVersion(), softwareModule2.getVersion()); } } } @@ -138,13 +144,14 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress().getHost()); final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage); - assertEquals(3, downloadAndUpdateRequest.getSoftwareModules().size()); + assertEquals("DownloadAndUpdateRequest event should contains 3 software modules", 3, + downloadAndUpdateRequest.getSoftwareModules().size()); for (final org.eclipse.hawkbit.dmf.json.model.SoftwareModule softwareModule : downloadAndUpdateRequest .getSoftwareModules()) { if (!softwareModule.getModuleId().equals(module.getId())) { continue; } - assertFalse(softwareModule.getArtifacts().isEmpty()); + assertFalse("The software module artifacts should not be empty", softwareModule.getArtifacts().isEmpty()); } } @@ -164,8 +171,8 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit private void assertCancelMessage(final Message sendMessage) { assertEventMessage(sendMessage); final Long actionId = convertMessage(sendMessage, Long.class); - assertEquals(actionId, Long.valueOf(1)); - assertEquals(EventTopic.CANCEL_DOWNLOAD, + assertEquals("Action ID should be 1", actionId, Long.valueOf(1)); + assertEquals("The topc in the message should be a CANCEL_DOWNLOAD value", EventTopic.CANCEL_DOWNLOAD, sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC)); } @@ -174,8 +181,9 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit assertEventMessage(sendMessage); final DownloadAndUpdateRequest downloadAndUpdateRequest = convertMessage(sendMessage, DownloadAndUpdateRequest.class); - assertEquals(downloadAndUpdateRequest.getActionId(), Long.valueOf(1)); - assertEquals(EventTopic.DOWNLOAD_AND_INSTALL, + assertEquals("The action ID of the downloadAndUpdateRequest event shuold be 1", + downloadAndUpdateRequest.getActionId(), Long.valueOf(1)); + assertEquals("The topic of the event shuold contain DOWNLOAD_AND_INSTALL", EventTopic.DOWNLOAD_AND_INSTALL, sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC)); return downloadAndUpdateRequest; @@ -185,11 +193,14 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit * @param sendMessage */ private void assertEventMessage(final Message sendMessage) { - assertNotNull(sendMessage); + assertNotNull("The message should not be null", sendMessage); - assertEquals(CONTROLLER_ID, sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.THING_ID)); - assertEquals(MessageType.EVENT, sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TYPE)); - assertEquals(MessageProperties.CONTENT_TYPE_JSON, sendMessage.getMessageProperties().getContentType()); + assertEquals("The value of the message header THING_ID should be " + CONTROLLER_ID, CONTROLLER_ID, + sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.THING_ID)); + assertEquals("The value of the message header TYPE should be EVENT", MessageType.EVENT, + sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TYPE)); + assertEquals("The content type message should be " + MessageProperties.CONTENT_TYPE_JSON, + MessageProperties.CONTENT_TYPE_JSON, sendMessage.getMessageProperties().getContentType()); } protected Message createArgumentCapture(final String exchange) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractPropertyChangeEvent.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractPropertyChangeEvent.java index 8a596eeb5..86251e675 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractPropertyChangeEvent.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractPropertyChangeEvent.java @@ -47,7 +47,7 @@ public class AbstractPropertyChangeEvent extends AbstractB * Carries old value and new value of a property . * */ - public class Values { + public static class Values { private final Object oldValue; private final Object newValue; diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementTest.java index 5585aab95..2929110dd 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ArtifactManagementTest.java @@ -150,14 +150,14 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { ExternalArtifact result = artifactManagement.createExternalArtifact(provider, null, sm.getId()); - assertNotNull(result); + assertNotNull("The result of an external artifact should not be null", result); assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(1); assertThat(result.getSoftwareModule().getId()).isEqualTo(sm.getId()); assertThat(result.getUrl()).isEqualTo("https://fhghdfjgh/{version}/"); assertThat(result.getExternalArtifactProvider()).isEqualTo(provider); result = artifactManagement.createExternalArtifact(provider, "/test", sm2.getId()); - assertNotNull(result); + assertNotNull("The newly created external artifact should not be null", result); assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(2); assertThat(result.getUrl()).isEqualTo("https://fhghdfjgh/test"); assertThat(result.getExternalArtifactProvider()).isEqualTo(provider); @@ -176,7 +176,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { "https://fhghdfjgh", "/{version}/"); final ExternalArtifact result = artifactManagement.createExternalArtifact(provider, null, sm.getId()); - assertNotNull(result); + assertNotNull("The newly created external artifact should not be null", result); assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(1); artifactManagement.deleteExternalArtifact(result.getId()); @@ -348,7 +348,7 @@ public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB { final LocalArtifact result = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file1", false); - assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(random), + assertTrue("The stored binary matches the given binary", IOUtils.contentEquals(new ByteArrayInputStream(random), artifactManagement.loadLocalArtifactBinary(result).getFileInputStream())); } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SoftwareManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SoftwareManagementTest.java index dc9a654c7..49776e392 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SoftwareManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SoftwareManagementTest.java @@ -159,10 +159,10 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { public void hardDeleteOfNotAssignedArtifact() { // [STEP1]: Create SoftwareModuleX with Artifacts - SoftwareModule unassignedModule = createSoftwareModuleWithArtifacts(osType, "moduleX", "3.0.2", 2); - Iterator artifactsIt = unassignedModule.getArtifacts().iterator(); - Artifact artifact1 = artifactsIt.next(); - Artifact artifact2 = artifactsIt.next(); + final SoftwareModule unassignedModule = createSoftwareModuleWithArtifacts(osType, "moduleX", "3.0.2", 2); + final Iterator artifactsIt = unassignedModule.getArtifacts().iterator(); + final Artifact artifact1 = artifactsIt.next(); + final Artifact artifact2 = artifactsIt.next(); // [STEP2]: Delete unassigned SoftwareModule softwareManagement.deleteSoftwareModule(unassignedModule); @@ -185,7 +185,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { public void softDeleteOfAssignedArtifact() { // Init DistributionSet - DistributionSet disSet = distributionSetManagement + final DistributionSet disSet = distributionSetManagement .createDistributionSet(new DistributionSet("ds1", "v1.0", "test ds", standardDsType, null)); // [STEP1]: Create SoftwareModuleX with ArtifactX @@ -200,14 +200,14 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // [VERIFY EXPECTED RESULT]: // verify: assignedModule is marked as deleted assignedModule = softwareManagement.findSoftwareModuleById(assignedModule.getId()); - assertTrue(assignedModule.isDeleted()); + assertTrue("The module should be flagged as deleted", assignedModule.isDeleted()); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); assertThat(softwareModuleRepository.findAll()).hasSize(1); // verify: binary data is deleted - Iterator artifactsIt = assignedModule.getArtifacts().iterator(); - Artifact artifact1 = artifactsIt.next(); - Artifact artifact2 = artifactsIt.next(); + final Iterator artifactsIt = assignedModule.getArtifacts().iterator(); + final Artifact artifact1 = artifactsIt.next(); + final Artifact artifact2 = artifactsIt.next(); assertArtfiactNull(artifact1, artifact2); // verify: artifact meta data is still available @@ -221,7 +221,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // Init target and DistributionSet final Target target = targetManagement.createTarget(new Target("test123")); - DistributionSet disSet = distributionSetManagement + final DistributionSet disSet = distributionSetManagement .createDistributionSet(new DistributionSet("ds1", "v1.0", "test ds", standardDsType, null)); // [STEP1]: Create SoftwareModuleX and include the new ArtifactX @@ -242,14 +242,14 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // [VERIFY EXPECTED RESULT]: // verify: assignedModule is marked as deleted assignedModule = softwareManagement.findSoftwareModuleById(assignedModule.getId()); - assertTrue(assignedModule.isDeleted()); + assertTrue("The found module should be flagged deleted", assignedModule.isDeleted()); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); assertThat(softwareModuleRepository.findAll()).hasSize(1); // verify: binary data is deleted - Iterator artifactsIt = assignedModule.getArtifacts().iterator(); - Artifact artifact1 = artifactsIt.next(); - Artifact artifact2 = artifactsIt.next(); + final Iterator artifactsIt = assignedModule.getArtifacts().iterator(); + final Artifact artifact1 = artifactsIt.next(); + final Artifact artifact2 = artifactsIt.next(); assertArtfiactNull(artifact1, artifact2); // verify: artifact meta data is still available @@ -265,7 +265,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(operations.find(new Query())).hasSize(0); // Init artifact binary data, target and DistributionSets - byte[] source = RandomUtils.nextBytes(1024); + final byte[] source = RandomUtils.nextBytes(1024); // [STEP1]: Create SoftwareModuleX and add a new ArtifactX SoftwareModule moduleX = createSoftwareModuleWithArtifacts(osType, "modulex", "v1.0", 0); @@ -273,7 +273,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // [STEP2]: Create newArtifactX and add it to SoftwareModuleX artifactManagement.createLocalArtifact(new ByteArrayInputStream(source), moduleX.getId(), "artifactx", false); moduleX = softwareManagement.findSoftwareModuleWithDetails(moduleX.getId()); - Artifact artifactX = moduleX.getArtifacts().iterator().next(); + final Artifact artifactX = moduleX.getArtifacts().iterator().next(); // [STEP3]: Create SoftwareModuleY and add the same ArtifactX SoftwareModule moduleY = createSoftwareModuleWithArtifacts(osType, "moduley", "v1.0", 0); @@ -281,7 +281,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // [STEP4]: Assign the same ArtifactX to SoftwareModuleY artifactManagement.createLocalArtifact(new ByteArrayInputStream(source), moduleY.getId(), "artifactx", false); moduleY = softwareManagement.findSoftwareModuleWithDetails(moduleY.getId()); - Artifact artifactY = moduleY.getArtifacts().iterator().next(); + final Artifact artifactY = moduleY.getArtifacts().iterator().next(); // verify: that only one entry was created in mongoDB assertThat(operations.find(new Query())).hasSize(1); @@ -325,14 +325,14 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { artifactManagement.createLocalArtifact(new ByteArrayInputStream(source), moduleX.getId(), "artifactx", false); moduleX = softwareManagement.findSoftwareModuleWithDetails(moduleX.getId()); - Artifact artifactX = moduleX.getArtifacts().iterator().next(); + final Artifact artifactX = moduleX.getArtifacts().iterator().next(); // [STEP2]: Create SoftwareModuleY and add the same ArtifactX SoftwareModule moduleY = createSoftwareModuleWithArtifacts(osType, "moduley", "v1.0", 0); artifactManagement.createLocalArtifact(new ByteArrayInputStream(source), moduleY.getId(), "artifactx", false); moduleY = softwareManagement.findSoftwareModuleWithDetails(moduleY.getId()); - Artifact artifactY = moduleY.getArtifacts().iterator().next(); + final Artifact artifactY = moduleY.getArtifacts().iterator().next(); // verify: that only one entry was created in mongoDB assertThat(operations.find(new Query())).hasSize(1); @@ -358,8 +358,8 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { // verify: SoftwareModuleX and SofwtareModule are marked as deleted assertThat(moduleX).isNotNull(); assertThat(moduleY).isNotNull(); - assertTrue(moduleX.isDeleted()); - assertTrue(moduleY.isDeleted()); + assertTrue("The module should be flagged deleted", moduleX.isDeleted()); + assertTrue("The module should be flagged deleted", moduleY.isDeleted()); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); assertThat(softwareModuleRepository.findAll()).hasSize(2); @@ -370,10 +370,10 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(artifactRepository.findOne(artifactY.getId())).isNotNull(); } - private SoftwareModule createSoftwareModuleWithArtifacts(SoftwareModuleType type, String name, String version, - int numberArtifacts) { + private SoftwareModule createSoftwareModuleWithArtifacts(final SoftwareModuleType type, final String name, + final String version, final int numberArtifacts) { - long countSoftwareModule = softwareModuleRepository.count(); + final long countSoftwareModule = softwareModuleRepository.count(); // create SoftwareModule SoftwareModule softwareModule = softwareManagement @@ -388,7 +388,7 @@ public class SoftwareManagementTest extends AbstractIntegrationTestWithMongoDB { softwareModule = softwareManagement.findSoftwareModuleWithDetails(softwareModule.getId()); assertThat(softwareModuleRepository.findAll()).hasSize((int) countSoftwareModule + 1); - List artifacts = softwareModule.getArtifacts(); + final List artifacts = softwareModule.getArtifacts(); assertThat(artifacts).hasSize(numberArtifacts); if (numberArtifacts != 0) { diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLActionFieldsTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLActionFieldsTest.java index 71cf511ae..139b0a88d 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLActionFieldsTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLActionFieldsTest.java @@ -72,7 +72,7 @@ public class RSQLActionFieldsTest extends AbstractIntegrationTest { try { assertRSQLQuery(ActionFields.STATUS.name() + "==true", 5); - fail(); + fail("Missing expected RSQLParameterUnsupportedFieldException because status cannot be compared with 'true'"); } catch (final RSQLParameterUnsupportedFieldException e) { } } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLUtilityTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLUtilityTest.java index 3b923d167..bcfade8d5 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLUtilityTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLUtilityTest.java @@ -63,7 +63,7 @@ public class RSQLUtilityTest { try { RSQLUtility.parse(wrongRSQL, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - fail(); + fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax"); } catch (final RSQLParameterSyntaxException e) { } } @@ -75,7 +75,7 @@ public class RSQLUtilityTest { try { RSQLUtility.parse(wrongRSQL, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - fail(); + fail("Missing an expected RSQLParameterUnsupportedFieldException because of unknown RSQL field"); } catch (final RSQLParameterUnsupportedFieldException e) { } @@ -87,7 +87,7 @@ public class RSQLUtilityTest { try { RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - fail(); + fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax"); } catch (final RSQLParameterUnsupportedFieldException e) { } @@ -95,7 +95,7 @@ public class RSQLUtilityTest { try { RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - fail(); + fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax"); } catch (final RSQLParameterUnsupportedFieldException e) { } @@ -103,7 +103,7 @@ public class RSQLUtilityTest { try { RSQLUtility.parse(wrongRSQL, DistributionSetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - fail(); + fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax"); } catch (final RSQLParameterUnsupportedFieldException e) { } @@ -115,7 +115,7 @@ public class RSQLUtilityTest { try { RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - fail(); + fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax"); } catch (final RSQLParameterUnsupportedFieldException e) { } @@ -123,7 +123,7 @@ public class RSQLUtilityTest { try { RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - fail(); + fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax"); } catch (final RSQLParameterUnsupportedFieldException e) { } @@ -131,7 +131,7 @@ public class RSQLUtilityTest { try { RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - fail(); + fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax"); } catch (final RSQLParameterUnsupportedFieldException e) { } } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResource.java index 9ce1a2975..dfbac1a6f 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResource.java @@ -99,52 +99,6 @@ public class SoftwareModuleResource implements SoftwareModuleRestAPI { return new ResponseEntity<>(SoftwareModuleMapper.artifactsToResponse(module.getArtifacts()), HttpStatus.OK); } - /** - * Handles the GET request for downloading an artifact. - * - * @param softwareModuleId - * of the parent SoftwareModule - * @param artifactId - * of the related LocalArtifact - * @param servletResponse - * of the servlet - * @param request - * of the client - * - * @return responseEntity with status ok if successful - */ - // @RequestMapping(method = RequestMethod.GET, value = - // RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING - // + "/{softwareModuleId}/artifacts/{artifactId}/download") - // @ResponseBody - // public ResponseEntity downloadArtifact(@PathVariable final Long - // softwareModuleId, - // @PathVariable final Long artifactId, final HttpServletResponse - // servletResponse, - // final HttpServletRequest request) { - // final SoftwareModule module = - // findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId); - // - // if (null == module || !module.getLocalArtifact(artifactId).isPresent()) { - // return new ResponseEntity<>(HttpStatus.NOT_FOUND); - // } - // - // final LocalArtifact artifact = module.getLocalArtifact(artifactId).get(); - // final DbArtifact file = - // artifactManagement.loadLocalArtifactBinary(artifact); - // - // final String ifMatch = request.getHeader("If-Match"); - // if (ifMatch != null && - // !RestResourceConversionHelper.matchesHttpHeader(ifMatch, - // artifact.getSha1Hash())) { - // return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED); - // } - // - // return RestResourceConversionHelper.writeFileResponse(artifact, - // servletResponse, request, file); - // - // } - @Override public ResponseEntity getArtifact(@PathVariable final Long softwareModuleId, @PathVariable final Long artifactId) { diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/model/ExceptionInfoTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/model/ExceptionInfoTest.java index e9601d693..ab5012d73 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/model/ExceptionInfoTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/model/ExceptionInfoTest.java @@ -32,10 +32,15 @@ public class ExceptionInfoTest { underTest.setMessage(knownMessage); underTest.setParameters(knownParameters); - assertThat(underTest.getErrorCode()).isEqualTo(knownErrorCode); - assertThat(underTest.getExceptionClass()).isEqualTo(knownExceptionClass); - assertThat(underTest.getMessage()).isEqualTo(knownMessage); - assertThat(underTest.getParameters()).isEqualTo(knownParameters); + assertThat(underTest.getErrorCode()).as("The error code should match with the known error code in the test") + .isEqualTo(knownErrorCode); + assertThat(underTest.getExceptionClass()) + .as("The exception class should match with the known error code in the test") + .isEqualTo(knownExceptionClass); + assertThat(underTest.getMessage()).as("The message should match with the known error code in the test") + .isEqualTo(knownMessage); + assertThat(underTest.getParameters()).as("The parameters should match with the known error code in the test") + .isEqualTo(knownParameters); } } diff --git a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/ExcludePathAwareShallowETagFilterTest.java b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/ExcludePathAwareShallowETagFilterTest.java index ce663fbfb..d3dc066f1 100644 --- a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/ExcludePathAwareShallowETagFilterTest.java +++ b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/ExcludePathAwareShallowETagFilterTest.java @@ -56,7 +56,8 @@ public class ExcludePathAwareShallowETagFilterTest { filterUnderTest.doFilterInternal(servletRequestMock, servletResponseMock, filterChainMock); // verify no eTag header is set and response has not been changed - assertThat(servletResponseMock.getHeader("ETag")).isNull(); + assertThat(servletResponseMock.getHeader("ETag")) + .as("ETag header should not be set during downloading, too expensive").isNull(); // the servlet response must be the same mock! verify(filterChainMock, times(1)).doFilter(servletRequestMock, servletResponseMock); } diff --git a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/util/IpUtilTest.java b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/util/IpUtilTest.java index e1e809ab8..d56c59252 100644 --- a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/util/IpUtilTest.java +++ b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/util/IpUtilTest.java @@ -53,7 +53,8 @@ public class IpUtilTest { final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, "bumlux"); // verify - assertThat(remoteAddr).isEqualTo(knownRemoteClientIP); + assertThat(remoteAddr).as("The remote address should be as the known client IP address") + .isEqualTo(knownRemoteClientIP); verify(requestMock, times(1)).getHeader("bumlux"); verify(requestMock, times(1)).getRemoteAddr(); } @@ -71,7 +72,8 @@ public class IpUtilTest { final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, "X-Forwarded-For"); // verify - assertThat(remoteAddr).isEqualTo(knownRemoteClientIP); + assertThat(remoteAddr).as("The remote address should be as the known client IP address") + .isEqualTo(knownRemoteClientIP); verify(requestMock, times(1)).getHeader(HttpHeaders.X_FORWARDED_FOR); verify(requestMock, times(0)).getRemoteAddr(); } @@ -94,10 +96,10 @@ public class IpUtilTest { } private void assertHttpUri(final String host, final URI httpUri) { - assertTrue(IpUtil.isHttpUri(httpUri)); - assertFalse(IpUtil.isAmqpUri(httpUri)); - assertEquals(host, httpUri.getHost()); - assertEquals("http", httpUri.getScheme()); + assertTrue("The given URI has an http scheme", IpUtil.isHttpUri(httpUri)); + assertFalse("The given URI is not an AMQP scheme", IpUtil.isAmqpUri(httpUri)); + assertEquals("The URI hosts matches the given host", host, httpUri.getHost()); + assertEquals("The given URI scheme is http", "http", httpUri.getScheme()); } @Test @@ -117,22 +119,26 @@ public class IpUtilTest { } private void assertAmqpUri(final String host, final URI httpUri) { - assertTrue(IpUtil.isAmqpUri(httpUri)); - assertFalse(IpUtil.isHttpUri(httpUri)); - assertEquals(host, httpUri.getHost()); - assertEquals("amqp", httpUri.getScheme()); + assertTrue("The given URI is an AMQP scheme", IpUtil.isAmqpUri(httpUri)); + assertFalse("The given URI is not an HTTP scheme", IpUtil.isHttpUri(httpUri)); + assertEquals("The given host matches the URI host", host, httpUri.getHost()); + assertEquals("The given URI has an AMQP scheme", "amqp", httpUri.getScheme()); } - @Test(expected = IllegalArgumentException.class) + @Test @Description("Tests create invalid uri") public void testCreateInvalidUri() { final String host = "10.99.99.1"; final URI testUri = IpUtil.createUri("test", host); - assertFalse(IpUtil.isAmqpUri(testUri)); - assertFalse(IpUtil.isHttpUri(testUri)); - assertEquals(host, testUri.getHost()); - IpUtil.createUri(":/", host); - fail(); + assertFalse("The given URI is not an AMQP address", IpUtil.isAmqpUri(testUri)); + assertFalse("The given URI is not an HTTP address", IpUtil.isHttpUri(testUri)); + assertEquals("The given host matches the URI host", host, testUri.getHost()); + try { + IpUtil.createUri(":/", host); + fail("Missing expected IllegalArgumentException due invalid URI"); + } catch (final IllegalArgumentException e) { + // expected + } } } From 62d96a4ac67abca2d21ea715618fe9bde124febc Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 25 Feb 2016 14:51:45 +0100 Subject: [PATCH 06/14] remove static modifier from inner class Signed-off-by: Michael Hirsch --- .../hawkbit/eventbus/event/AbstractPropertyChangeEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractPropertyChangeEvent.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractPropertyChangeEvent.java index 86251e675..8a596eeb5 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractPropertyChangeEvent.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractPropertyChangeEvent.java @@ -47,7 +47,7 @@ public class AbstractPropertyChangeEvent extends AbstractB * Carries old value and new value of a property . * */ - public static class Values { + public class Values { private final Object oldValue; private final Object newValue; From 0b5c0673b1601ed838d668a4a45608bb9aa3a3ed Mon Sep 17 00:00:00 2001 From: asharani-murugesh Date: Thu, 25 Feb 2016 17:43:28 +0100 Subject: [PATCH 07/14] fix Signed-off-by: asharani-murugesh --- .../org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index 2e8c6a51e..665fbcb6f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -191,12 +191,13 @@ public class UploadLayout extends VerticalLayout { ((WrapperTransferable) event.getTransferable()).getDraggedComponent(); final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); if (files != null) { + //reset the flag + hasDirectory = Boolean.FALSE; for (final Html5File file : files) { if (!isDirectory(file)) { if (!checkForDuplicate(file.getFileName())) { numberOfFileUploadsExpected.incrementAndGet(); file.setStreamVariable(createStreamVariable(file)); - hasDirectory = Boolean.FALSE; } } else { hasDirectory = Boolean.TRUE; From b8ed510e8a5bb5dba93156779092867610f811ce Mon Sep 17 00:00:00 2001 From: asharani-murugesh Date: Thu, 25 Feb 2016 17:54:50 +0100 Subject: [PATCH 08/14] reset the has directory flag Signed-off-by: asharani-murugesh --- .../eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java | 2 ++ .../org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java index 3d7ce0886..cac4ef2f9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java @@ -108,6 +108,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public OutputStream receiveUpload(final String fileName, final String mimeType) { this.fileName = fileName; this.mimeType = mimeType; + //reset has directory flag before upload + view.setHasDirectory(false); try { if (view.validate()) { if (view.checkForDuplicate(fileName)) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index 665fbcb6f..c254a8b18 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -633,4 +633,8 @@ public class UploadLayout extends VerticalLayout { return uiNotification; } + + public void setHasDirectory(Boolean hasDirectory) { + this.hasDirectory = hasDirectory; + } } From 92811f1a22c516684a774e1feec23eebee05ad6b Mon Sep 17 00:00:00 2001 From: asharani-murugesh Date: Fri, 26 Feb 2016 08:47:21 +0100 Subject: [PATCH 09/14] review comment addressed Signed-off-by: asharani-murugesh --- .../ui/artifacts/upload/UploadLayout.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index c254a8b18..9a7969f05 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -59,6 +59,7 @@ import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; +import com.vaadin.ui.Component; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable; import com.vaadin.ui.HorizontalLayout; @@ -187,21 +188,13 @@ public class UploadLayout extends VerticalLayout { @Override public void drop(final DragAndDropEvent event) { - if (validate()) { - ((WrapperTransferable) event.getTransferable()).getDraggedComponent(); + if (event.getTransferable() instanceof WrapperTransferable && validate()) { final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); if (files != null) { - //reset the flag + // reset the flag hasDirectory = Boolean.FALSE; for (final Html5File file : files) { - if (!isDirectory(file)) { - if (!checkForDuplicate(file.getFileName())) { - numberOfFileUploadsExpected.incrementAndGet(); - file.setStreamVariable(createStreamVariable(file)); - } - } else { - hasDirectory = Boolean.TRUE; - } + processFile(file); } if (numberOfFileUploadsExpected.get() > 0) { processBtn.setEnabled(false); @@ -216,6 +209,17 @@ public class UploadLayout extends VerticalLayout { } } } + + private void processFile(final Html5File file) { + if (!isDirectory(file)) { + if (!checkForDuplicate(file.getFileName())) { + numberOfFileUploadsExpected.incrementAndGet(); + file.setStreamVariable(createStreamVariable(file)); + } + } else { + hasDirectory = Boolean.TRUE; + } + } } private static boolean isDirectory(final Html5File file) { From 80366b03be121fa4b3fc539256c15578ffa2bb9f Mon Sep 17 00:00:00 2001 From: asharani-murugesh Date: Sat, 27 Feb 2016 09:24:18 +0100 Subject: [PATCH 10/14] Review comments addresses Signed-off-by: asharani-murugesh --- .../ui/artifacts/upload/UploadHandler.java | 2 +- .../ui/artifacts/upload/UploadLayout.java | 60 ++++++++++++------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java index cac4ef2f9..8c1feeb33 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java @@ -111,7 +111,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene //reset has directory flag before upload view.setHasDirectory(false); try { - if (view.validate()) { + if (view.checkIfSoftwareModuleIsSelected()) { if (view.checkForDuplicate(fileName)) { view.showDuplicateMessage(); } else { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index 9a7969f05..994a9786f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -59,7 +59,6 @@ import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; -import com.vaadin.ui.Component; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable; import com.vaadin.ui.HorizontalLayout; @@ -188,24 +187,22 @@ public class UploadLayout extends VerticalLayout { @Override public void drop(final DragAndDropEvent event) { - if (event.getTransferable() instanceof WrapperTransferable && validate()) { + if (validate(event)) { final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); - if (files != null) { - // reset the flag - hasDirectory = Boolean.FALSE; - for (final Html5File file : files) { - processFile(file); - } - if (numberOfFileUploadsExpected.get() > 0) { - processBtn.setEnabled(false); - // reset before we start - uploadInfoWindow.uploadSessionStarted(); - } else { - // If the upload is not started, it signifies all - // dropped files as either duplicate or directory.So - // display message accordingly - displayCompositeMessage(); - } + // reset the flag + hasDirectory = Boolean.FALSE; + for (final Html5File file : files) { + processFile(file); + } + if (numberOfFileUploadsExpected.get() > 0) { + processBtn.setEnabled(false); + // reset before we start + uploadInfoWindow.uploadSessionStarted(); + } else { + // If the upload is not started, it signifies all + // dropped files as either duplicate or directory.So + // display message accordingly + displayCompositeMessage(); } } } @@ -354,10 +351,33 @@ public class UploadLayout extends VerticalLayout { } } - Boolean validate() { + Boolean validate(DragAndDropEvent event) { + // check if drop is valid.If valid ,check if software module is + // selected. + if(!isFilesDropped(event)){ + uiNotification.displayValidationError(i18n.get("message.action.not.allowed")); + return false; + } + return checkIfSoftwareModuleIsSelected(); + } + + private boolean isFilesDropped(DragAndDropEvent event) { + if (event.getTransferable() instanceof WrapperTransferable) { + final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); + // other components can also be wrapped in WrapperTransferable , so + // additional check on files + if (files == null) { + return false; + } + return true; + } else { + return false; + } + } + + Boolean checkIfSoftwareModuleIsSelected() { if (!isSoftwareModuleSelected()) { uiNotification.displayValidationError(i18n.get("message.error.noSwModuleSelected")); - return false; } return true; From c9c36ea435c2fe2da6c5710f2de794eaad78858b Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 29 Feb 2016 15:34:07 +0100 Subject: [PATCH 11/14] Add description for asserts in test cases Signed-off-by: SirWayne --- .../SoftwareModuleAssigmentBuilder.java | 2 +- .../amqp/AmqpMessageHandlerServiceTest.java | 15 +- .../PropertyBasedArtifactUrlHandlerTest.java | 20 +- .../repository/DeploymentManagementTest.java | 31 ++- .../repository/TargetManagementTest.java | 103 +++++---- .../rsql/RSQLDistributionSetFieldTest.java | 4 +- .../resource/SoftwareModuleResourceTest.java | 203 ++++++++---------- .../rest/resource/model/PagedListTest.java | 13 +- .../ui/common/tagdetails/TargetTagToken.java | 4 +- .../ManangementConfirmationWindowLayout.java | 37 +--- 10 files changed, 203 insertions(+), 229 deletions(-) diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java index 840f16182..b209dbe8b 100644 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java @@ -25,7 +25,7 @@ public class SoftwareModuleAssigmentBuilder { private final List ids; public SoftwareModuleAssigmentBuilder() { - ids = new ArrayList(); + ids = new ArrayList<>(); } /** diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 18f7b853f..cf6c26590 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -115,14 +115,16 @@ public class AmqpMessageHandlerServiceTest { } - @Test(expected = IllegalArgumentException.class) @Description("Tests not allowed content-type in message") public void testWrongContentType() { final MessageProperties messageProperties = new MessageProperties(); messageProperties.setContentType("xml"); final Message message = new Message(new byte[0], messageProperties); - amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT); - fail(); + try { + amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT); + fail("IllegalArgumentException was excepeted due to worng content type"); + } catch (final IllegalArgumentException e) { + } } @Test @@ -197,14 +199,14 @@ public class AmqpMessageHandlerServiceTest { final Message message = new Message(new byte[0], messageProperties); try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT); - fail(); + fail("IllegalArgumentException was excepeted due to unknown message type"); } catch (final IllegalArgumentException e) { } try { messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic"); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT); - fail(); + fail("IllegalArgumentException was excepeted due to unknown topic"); } catch (final IllegalArgumentException e) { } @@ -328,7 +330,8 @@ public class AmqpMessageHandlerServiceTest { assertThat(downloadResponse.getResponseCode()).as("Message body response code is wrong") .isEqualTo(HttpStatus.OK.value()); assertThat(downloadResponse.getArtifact().getSize()).as("Wrong artifact size in message body").isEqualTo(1L); - assertThat(downloadResponse.getDownloadUrl()).startsWith("http://localhost/api/v1/downloadserver/downloadId/"); + assertThat(downloadResponse.getDownloadUrl()).as("download url is wrong") + .startsWith("http://localhost/api/v1/downloadserver/downloadId/"); } @Test diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java index fcafb23e4..2f3a8e21b 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java @@ -53,18 +53,22 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest @Description("Tests generate the http download url") public void testHttpUrl() { final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTP); - assertEquals("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId - + "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/" - + localArtifact.getFilename(), url); + assertEquals("http is build incorrect", + "http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId + + "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/" + + localArtifact.getFilename(), + url); } @Test @Description("Tests generate the https download url") public void testHttpsUrl() { final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTPS); - assertEquals("https://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId - + "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/" - + localArtifact.getFilename(), url); + assertEquals("https is build incorrect", + "https://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId + + "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/" + + localArtifact.getFilename(), + url); } @Test @@ -72,7 +76,7 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest public void testCoapUrl() { final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.COAP); - assertEquals("coap://127.0.0.1:5683/fw/" + tenantAware.getCurrentTenant() + "/" + controllerId + "/sha1/" - + localArtifact.getSha1Hash(), url); + assertEquals("coap is build incorrect", "coap://127.0.0.1:5683/fw/" + tenantAware.getCurrentTenant() + "/" + + controllerId + "/sha1/" + localArtifact.getSha1Hash(), url); } } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java index 985bc6bd9..a3071d756 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java @@ -766,12 +766,13 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { distributionSetManagement.findDistributionSetByIdWithDetails(dsA.getId()).getOptLockRevision()); // verifying that the assignment is correct - assertEquals(1, deploymentManagement.findActiveActionsByTarget(targ).size()); - assertEquals(1, deploymentManagement.findActionsByTarget(targ).size()); - assertEquals(TargetUpdateStatus.PENDING, targ.getTargetInfo().getUpdateStatus()); - assertEquals(dsA, targ.getAssignedDistributionSet()); - assertEquals(dsA, deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet()); - assertNull(targ.getTargetInfo().getInstalledDistributionSet()); + assertEquals("Active target actions are wrong", 1, deploymentManagement.findActiveActionsByTarget(targ).size()); + assertEquals("Target actions are wrong", 1, deploymentManagement.findActionsByTarget(targ).size()); + assertEquals("Target status is wrong", TargetUpdateStatus.PENDING, targ.getTargetInfo().getUpdateStatus()); + assertEquals("Assigned ds is wrong", dsA, targ.getAssignedDistributionSet()); + assertEquals("Active ds is wrong", dsA, + deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet()); + assertNull("Installed ds should be null", targ.getTargetInfo().getInstalledDistributionSet()); final Page updAct = actionRepository.findByDistributionSet(pageReq, dsA); final Action action = updAct.getContent().get(0); @@ -782,12 +783,8 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { targ = targetManagement.findTargetByControllerID(targ.getControllerId()); assertEquals(0, deploymentManagement.findActiveActionsByTarget(targ).size()); - // try { assertEquals(1, deploymentManagement.findInActiveActionsByTarget(targ).size()); - // } - // catch( final LazyInitializationException ex ) { - // - // } + assertEquals(TargetUpdateStatus.IN_SYNC, targ.getTargetInfo().getUpdateStatus()); assertEquals(dsA, targ.getAssignedDistributionSet()); assertEquals(dsA, targ.getTargetInfo().getInstalledDistributionSet()); @@ -797,13 +794,15 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { targ = targs.iterator().next(); - assertEquals(1, deploymentManagement.findActiveActionsByTarget(targ).size()); - assertEquals(TargetUpdateStatus.PENDING, + assertEquals("active actions are wrong", 1, deploymentManagement.findActiveActionsByTarget(targ).size()); + assertEquals("target status is wrong", TargetUpdateStatus.PENDING, targetManagement.findTargetByControllerID(targ.getControllerId()).getTargetInfo().getUpdateStatus()); assertEquals(dsB, targ.getAssignedDistributionSet()); - assertEquals(dsA.getId(), targetManagement.findTargetByControllerIDWithDetails(targ.getControllerId()) - .getTargetInfo().getInstalledDistributionSet().getId()); - assertEquals(dsB, deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet()); + assertEquals("Installed ds is wrong", dsA.getId(), + targetManagement.findTargetByControllerIDWithDetails(targ.getControllerId()).getTargetInfo() + .getInstalledDistributionSet().getId()); + assertEquals("Active ds is wrong", dsB, + deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet()); } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java index cdcaff25e..20dffde29 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java @@ -96,24 +96,26 @@ public class TargetManagementTest extends AbstractIntegrationTest { final TargetTag targetTag = tagManagement.createTargetTag(new TargetTag("Tag1")); final List assignedTargets = targetManagement.assignTag(assignTarget, targetTag); - assertThat(assignedTargets.size()).isEqualTo(4); + assertThat(assignedTargets.size()).as("Assigned targets are wrong").isEqualTo(4); assignedTargets.forEach(target -> assertThat(target.getTags().size()).isEqualTo(1)); TargetTag findTargetTag = tagManagement.findTargetTag("Tag1"); - assertThat(assignedTargets.size()).isEqualTo(findTargetTag.getAssignedToTargets().size()); + assertThat(assignedTargets.size()).as("Assigned targets are wrong") + .isEqualTo(findTargetTag.getAssignedToTargets().size()); - assertThat(targetManagement.unAssignTag("NotExist", findTargetTag)).isNull(); + assertThat(targetManagement.unAssignTag("NotExist", findTargetTag)).as("Unassign target does not work") + .isNull(); final Target unAssignTarget = targetManagement.unAssignTag("targetId123", findTargetTag); - assertThat(unAssignTarget.getControllerId()).isEqualTo("targetId123"); - assertThat(unAssignTarget.getTags().size()).isEqualTo(0); + assertThat(unAssignTarget.getControllerId()).as("Controller id is wrong").isEqualTo("targetId123"); + assertThat(unAssignTarget.getTags()).as("Tag size is wrong").isEmpty(); findTargetTag = tagManagement.findTargetTag("Tag1"); - assertThat(findTargetTag.getAssignedToTargets().size()).isEqualTo(3); + assertThat(findTargetTag.getAssignedToTargets()).as("Assigned targets are wrong").hasSize(3); final List unAssignTargets = targetManagement.unAssignAllTargetsByTag(findTargetTag); findTargetTag = tagManagement.findTargetTag("Tag1"); - assertThat(findTargetTag.getAssignedToTargets().size()).isEqualTo(0); - assertThat(unAssignTargets.size()).isEqualTo(3); + assertThat(findTargetTag.getAssignedToTargets()).as("Unassigned targets are wrong").isEmpty(); + assertThat(unAssignTargets).as("Unassigned targets are wrong").hasSize(3); unAssignTargets.forEach(target -> assertThat(target.getTags().size()).isEqualTo(0)); } @@ -121,14 +123,14 @@ public class TargetManagementTest extends AbstractIntegrationTest { @Description("Ensures that targets can deleted e.g. test all cascades") public void deleteAndCreateTargets() { Target target = targetManagement.createTarget(new Target("targetId123")); - assertThat(targetManagement.countTargetsAll()).isEqualTo(1); + assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(1); targetManagement.deleteTargets(target.getId()); - assertThat(targetManagement.countTargetsAll()).isEqualTo(0); + assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0); target = createTargetWithAttributes("4711"); - assertThat(targetManagement.countTargetsAll()).isEqualTo(1); + assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(1); targetManagement.deleteTargets(target.getId()); - assertThat(targetManagement.countTargetsAll()).isEqualTo(0); + assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0); final List targets = new ArrayList(); for (int i = 0; i < 5; i++) { @@ -136,9 +138,9 @@ public class TargetManagementTest extends AbstractIntegrationTest { targets.add(target.getId()); targets.add(createTargetWithAttributes("" + (i * i + 1000)).getId()); } - assertThat(targetManagement.countTargetsAll()).isEqualTo(10); + assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(10); targetManagement.deleteTargets(targets.toArray(new Long[targets.size()])); - assertThat(targetManagement.countTargetsAll()).isEqualTo(0); + assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0); } private Target createTargetWithAttributes(final String controllerId) { @@ -150,7 +152,8 @@ public class TargetManagementTest extends AbstractIntegrationTest { target = controllerManagament.updateControllerAttributes(controllerId, testData); target = targetManagement.findTargetByControllerIDWithDetails(controllerId); - assertThat(target.getTargetInfo().getControllerAttributes()).isEqualTo(testData); + assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong") + .isEqualTo(testData); return target; } @@ -162,10 +165,14 @@ public class TargetManagementTest extends AbstractIntegrationTest { final DistributionSet set2 = TestDataUtil.generateDistributionSet("test2", softwareManagement, distributionSetManagement); - assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).isEqualTo(0); - assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).isEqualTo(0); - assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).isEqualTo(0); - assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).isEqualTo(0); + assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).as("Target count is wrong") + .isEqualTo(0); + assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).as("Target count is wrong") + .isEqualTo(0); + assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).as("Target count is wrong") + .isEqualTo(0); + assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).as("Target count is wrong") + .isEqualTo(0); Target target = createTargetWithAttributes("4711"); @@ -183,13 +190,19 @@ public class TargetManagementTest extends AbstractIntegrationTest { target = targetManagement.findTargetByControllerIDWithDetails("4711"); // read data - assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).isEqualTo(0); - assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).isEqualTo(1); - assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).isEqualTo(1); - assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).isEqualTo(0); - assertThat(target.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current); - assertThat(target.getAssignedDistributionSet()).isEqualTo(set2); - assertThat(target.getTargetInfo().getInstalledDistributionSet().getId()).isEqualTo(set.getId()); + assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).as("Target count is wrong") + .isEqualTo(0); + assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).as("Target count is wrong") + .isEqualTo(1); + assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).as("Target count is wrong") + .isEqualTo(1); + assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).as("Target count is wrong") + .isEqualTo(0); + assertThat(target.getTargetInfo().getLastTargetQuery()).as("Target query is not work") + .isGreaterThanOrEqualTo(current); + assertThat(target.getAssignedDistributionSet()).as("Assigned ds size is wrong").isEqualTo(set2); + assertThat(target.getTargetInfo().getInstalledDistributionSet().getId()).as("Installed ds is wrong") + .isEqualTo(set.getId()); } @@ -373,8 +386,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { assertThat(firstSaved.spliterator().getExactSizeIfKnown() - nr2Del).as("Size of splited list") .isEqualTo(allFound.spliterator().getExactSizeIfKnown()); - // verify that all undeleted are still found - assertThat(allFound).doesNotContain(deletedTargets); + assertThat(allFound).as("Not all undeleted found").doesNotContain(deletedTargets); } @Test @@ -404,7 +416,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { targetInfo = targetInfoRepository.save(targetInfo); } final Query qry = entityManager.createNativeQuery("select * from sp_target_attributes ta"); - final List result = qry.getResultList(); + final List result = qry.getResultList(); assertThat(attribs.size() * ts.spliterator().getExactSizeIfKnown()).as("Amount of all target attributes") .isEqualTo(result.size()); @@ -467,7 +479,8 @@ public class TargetManagementTest extends AbstractIntegrationTest { final Target tNoAttrib = targetManagement.findTargetByControllerID(tNoAttribl.getControllerId()); if (tNoAttrib.getControllerId().equals(target.getControllerId())) { - assertThat(target.getTargetInfo().getControllerAttributes()).isEmpty(); + assertThat(target.getTargetInfo().getControllerAttributes()) + .as("Controller attributes should be empty").isEmpty(); continue restTarget_; } } @@ -479,7 +492,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { if (tNoAttrib.getControllerId().equals(target.getControllerId())) { assertThat(target.getTargetInfo().getControllerAttributes().keySet().toArray()) - .doesNotContain(attribs2Del.toArray()); + .as("Controller attributes are wrong").doesNotContain(attribs2Del.toArray()); continue restTarget_; } } @@ -504,12 +517,14 @@ public class TargetManagementTest extends AbstractIntegrationTest { t2 = targetManagement.createTarget(t2); t1 = targetManagement.findTargetByControllerID(t1.getControllerId()); - assertThat(t1.getTags()).hasSize(noT1Tags).containsAll(t1Tags); - assertThat(t1.getTags()).hasSize(noT1Tags).doesNotContain(Iterables.toArray(t2Tags, TargetTag.class)); + assertThat(t1.getTags()).as("Tag size is wrong").hasSize(noT1Tags).containsAll(t1Tags); + assertThat(t1.getTags()).as("Tag size is wrong").hasSize(noT1Tags) + .doesNotContain(Iterables.toArray(t2Tags, TargetTag.class)); t2 = targetManagement.findTargetByControllerID(t2.getControllerId()); - assertThat(t2.getTags()).hasSize(noT2Tags).containsAll(t2Tags); - assertThat(t2.getTags()).hasSize(noT2Tags).doesNotContain(Iterables.toArray(t1Tags, TargetTag.class)); + assertThat(t2.getTags()).as("Tag size is wrong").hasSize(noT2Tags).containsAll(t2Tags); + assertThat(t2.getTags()).as("Tag size is wrong").hasSize(noT2Tags) + .doesNotContain(Iterables.toArray(t1Tags, TargetTag.class)); } @Test @@ -531,7 +546,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { final TargetTag tagA = tagManagement.createTargetTag(new TargetTag("A")); final TargetTag tagB = tagManagement.createTargetTag(new TargetTag("B")); final TargetTag tagC = tagManagement.createTargetTag(new TargetTag("C")); - final TargetTag tagX = tagManagement.createTargetTag(new TargetTag("X")); + tagManagement.createTargetTag(new TargetTag("X")); // doing different assignments targetManagement.toggleTagAssignment(tagATargets, tagA); @@ -545,7 +560,8 @@ public class TargetManagementTest extends AbstractIntegrationTest { targetManagement.toggleTagAssignment(tagABCTargets, tagB); targetManagement.toggleTagAssignment(tagABCTargets, tagC); - assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "X")).isEqualTo(0); + assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "X")) + .as("Target count is wrong").isEqualTo(0); // search for targets with tag tagA final List targetWithTagA = new ArrayList(); @@ -575,11 +591,11 @@ public class TargetManagementTest extends AbstractIntegrationTest { // check again target lists refreshed from DB assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "A")) - .isEqualTo(targetWithTagA.size()); + .as("Target count is wrong").isEqualTo(targetWithTagA.size()); assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "B")) - .isEqualTo(targetWithTagB.size()); + .as("Target count is wrong").isEqualTo(targetWithTagB.size()); assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "C")) - .isEqualTo(targetWithTagC.size()); + .as("Target count is wrong").isEqualTo(targetWithTagC.size()); } @Test @@ -656,14 +672,15 @@ public class TargetManagementTest extends AbstractIntegrationTest { targetManagement.toggleTagAssignment(targAs, targTagA); assertThat(targetManagement.findTargetsByControllerIDsWithTags( - targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()))).hasSize(25); + targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()))) + .as("Target count is wrong").hasSize(25); // no lazy loading exception and tag correctly assigned assertThat(targetManagement .findTargetsByControllerIDsWithTags( targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) .stream().map(target -> target.getTags().contains(targTagA)).collect(Collectors.toList())) - .containsOnly(true); + .as("Tags not correctly assigned").containsOnly(true); } @Test @@ -678,7 +695,7 @@ public class TargetManagementTest extends AbstractIntegrationTest { final List findAllTargetIds = findAllTargetIdNames.stream().map(TargetIdName::getControllerId) .collect(Collectors.toList()); - assertThat(findAllTargetIds).containsOnly(createdTargetIds); + assertThat(findAllTargetIds).as("Target list has wrong content").containsOnly(createdTargetIds); } @Test diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetFieldTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetFieldTest.java index 6bfdb89aa..f72c3a968 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetFieldTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLDistributionSetFieldTest.java @@ -140,7 +140,7 @@ public class RSQLDistributionSetFieldTest extends AbstractIntegrationTest { final Page find = distributionSetManagement.findDistributionSetsAll( RSQLUtility.parse(rsqlParam, DistributionSetFields.class), new PageRequest(0, 100), false); final long countAll = find.getTotalElements(); - assertThat(find).isNotNull(); - assertThat(countAll).isEqualTo(excpectedEntity); + assertThat(find).as("Founded entity is should not be null").isNotNull(); + assertThat(countAll).as("Founded entity size is wrong").isEqualTo(excpectedEntity); } } diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResourceTest.java index 8079b5d52..3a0cc3e94 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResourceTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResourceTest.java @@ -25,6 +25,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -49,6 +50,7 @@ import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactRest; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.junit.Before; import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; @@ -69,6 +71,13 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("Software Module Resource") public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongoDB { + @Before + public void assertPreparationOfRepo() { + assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("no softwaremodule should be founded") + .hasSize(0); + assertThat(artifactRepository.findAll()).as("no artifacts should be founded").hasSize(0); + } + @Test @Description("Tests the update of software module metadata. It is verfied that only the selected fields for the update are really updated and the modification values are filled (i.e. updated by and at).") @WithUser(principal = "smUpdateTester", allSpPermissions = true) @@ -81,18 +90,14 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo final String updateVendor = "newVendor1"; final String updateDescription = "newDescription1"; - final SoftwareModule ah = softwareManagement - .createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); - final SoftwareModule jvm = softwareManagement - .createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); - final SoftwareModule os = softwareManagement - .createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, "")); + softwareManagement.createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, "")); + softwareManagement.createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, "")); + softwareManagement.createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, "")); SoftwareModule sm = new SoftwareModule(osType, knownSWName, knownSWVersion, knownSWDescription, knownSWVendor); sm = softwareManagement.createSoftwareModule(sm); - assertThat(sm.getName()).isEqualTo(knownSWName); - assertThat(sm.getName()).isEqualTo(knownSWName); + assertThat(sm.getName()).as("Wrong name of the software module").isEqualTo(knownSWName); final String body = new JSONObject().put("vendor", updateVendor).put("description", updateDescription) .put("name", "nameShouldNotBeChanged").toString(); @@ -123,9 +128,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo @Test @Description("Tests the uppload of an artifact binary. The upload is executed and the content checked in the repository for completenes.") public void uploadArtifact() throws Exception { - // prepare repo - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - assertThat(artifactRepository.findAll()).hasSize(0); SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); assertThat(artifactRepository.findAll()).hasSize(0); @@ -152,36 +154,41 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo .convertArtifactResponse(mvcResult.getResponse().getContentAsString()); final Long artId = ((LocalArtifact) softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts() .get(0)).getId(); - assertThat(artResult.getArtifactId()).isEqualTo(artId); + assertThat(artResult.getArtifactId()).as("Wrong artifact id").isEqualTo(artId); assertThat(JsonPath.compile("$_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) + .as("Link contains no self url") .isEqualTo("http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId); assertThat( JsonPath.compile("$_links.download.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId - + "/download"); + .as("response contains no download url ").isEqualTo("http://localhost/rest/v1/softwaremodules/" + + sm.getId() + "/artifacts/" + artId + "/download"); + assertArtifact(sm, random); + } + + private void assertArtifact(final SoftwareModule sm, final byte[] random) throws IOException { // check result in db... // repo - assertThat(artifactRepository.findAll()).hasSize(1); + assertThat(artifactRepository.findAll()).as("Wrong artifact size").hasSize(1); // binary - assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(random), - artifactManagement - .loadLocalArtifactBinary((LocalArtifact) softwareManagement - .findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0)) - .getFileInputStream())); + assertTrue("Wrong artifact content", + IOUtils.contentEquals(new ByteArrayInputStream(random), + artifactManagement + .loadLocalArtifactBinary((LocalArtifact) softwareManagement + .findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0)) + .getFileInputStream())); // hashes assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getSha1Hash()) - .isEqualTo(HashGeneratorUtils.generateSHA1(random)); + .as("Wrong sha1 hash").isEqualTo(HashGeneratorUtils.generateSHA1(random)); assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getMd5Hash()) - .isEqualTo(HashGeneratorUtils.generateMD5(random)); + .as("Wrong md5 hash").isEqualTo(HashGeneratorUtils.generateMD5(random)); // metadata assertThat(((LocalArtifact) softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0)) - .getFilename()).isEqualTo("origFilename"); - + .getFilename()).as("wrong metadata of the filename").isEqualTo("origFilename"); } @Test @@ -203,9 +210,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo @Test @Description("Verfies that the system does not accept identical artifacts uploads for the same software module. Expected response: CONFLICT") public void duplicateUploadArtifact() throws Exception { - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - assertThat(artifactRepository.findAll()).hasSize(0); - SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); @@ -228,9 +232,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo @Test @Description("verfies that option to upload artifacts with a custom defined by metadata, i.e. not the file name of the binary itself.") public void uploadArtifactWithCustomName() throws Exception { - // prepare repo - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - assertThat(artifactRepository.findAll()).hasSize(0); SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); assertThat(artifactRepository.findAll()).hasSize(0); @@ -245,22 +246,19 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$providedFilename", equalTo("customFilename"))).andExpect(status().isCreated()); - ; // check result in db... // repo - assertThat(artifactRepository.findAll()).hasSize(1); + assertThat(artifactRepository.findAll()).as("Artifact size is wring").hasSize(1); // hashes - assertThat(artifactManagement.findLocalArtifactByFilename("customFilename")).hasSize(1); + assertThat(artifactManagement.findLocalArtifactByFilename("customFilename")).as("Local artifact is wrong") + .hasSize(1); } @Test @Description("Verfies that the system refuses upload of an artifact where the provided hash sums do not match. Expected result: BAD REQUEST") public void uploadArtifactWithHashCheck() throws Exception { - // prepare repo - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - assertThat(artifactRepository.findAll()).hasSize(0); SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); assertThat(artifactRepository.findAll()).hasSize(0); @@ -280,7 +278,8 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo // check error result ExceptionInfo exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString()); - assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_SHA1_MATCH.getKey()); + assertThat(exceptionInfo.getErrorCode()).as("Exception contains wrong error code") + .isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_SHA1_MATCH.getKey()); // wrong md5 mvcResult = mvc @@ -290,42 +289,20 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo // check error result exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString()); - assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_MD5_MATCH.getKey()); + assertThat(exceptionInfo.getErrorCode()).as("Exception contains wrong error code") + .isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_MD5_MATCH.getKey()); mvc.perform(fileUpload("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file) .param("md5sum", md5sum).param("sha1sum", sha1sum)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()); - // check result... - // repo - assertThat(artifactRepository.findAll()).hasSize(1); - - // binary - assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(random), - artifactManagement - .loadLocalArtifactBinary((LocalArtifact) softwareManagement - .findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0)) - .getFileInputStream())); - - // hashes - assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getSha1Hash()) - .isEqualTo(HashGeneratorUtils.generateSHA1(random)); - - assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getMd5Hash()) - .isEqualTo(md5sum); - - // metadata - assertThat(((LocalArtifact) softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0)) - .getFilename()).isEqualTo("origFilename"); + assertArtifact(sm, random); } @Test @Description("Tests binary download of an artifact including verfication that the downloaded binary is consistent and that the etag header is as expected identical to the SHA1 hash of the file.") public void downloadArtifact() throws Exception { - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - assertThat(artifactRepository.findAll()).hasSize(0); - SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); @@ -350,19 +327,16 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo .andExpect(header().string("ETag", artifact2.getSha1Hash())) .andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM)).andReturn(); - assertTrue(Arrays.equals(result2.getResponse().getContentAsByteArray(), random)); + assertTrue("Response has wrong response content", + Arrays.equals(result2.getResponse().getContentAsByteArray(), random)); - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1); - assertThat(artifactRepository.findAll()).hasSize(2); + assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Softwaremodule size is wrong").hasSize(1); + assertThat(artifactRepository.findAll()).as("Wrong artifact repostiory").hasSize(2); } @Test @Description("Verifies the listing of one defined artifact assigned to a given software module. That includes the artifact metadata and download links.") public void getArtifact() throws Exception { - // check baseline - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - assertThat(artifactRepository.findAll()).hasSize(0); - // prepare data for test SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); @@ -548,8 +522,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo @WithUser(principal = "uploadTester", allSpPermissions = true) @Description("Test retrieval of all software modules the user has access to.") public void getSoftwareModules() throws Exception { - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1"); os = softwareManagement.createSoftwareModule(os); @@ -612,14 +584,12 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo .andExpect(jsonPath("$content.[?(@.id==" + ah.getId() + ")][0]._links.self.href", equalTo("http://localhost/rest/v1/softwaremodules/" + ah.getId()))); - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3); + assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Softwaremodule size is wrong").hasSize(3); } @Test @Description("Test the various filter parameters, e.g. filter by name or type of the module.") public void getSoftwareModulesWithFilterParameters() throws Exception { - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - SoftwareModule os1 = new SoftwareModule(osType, "osName1", "1.0.0", "description1", "vendor1"); os1 = softwareManagement.createSoftwareModule(os1); @@ -712,8 +682,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo @WithUser(principal = "uploadTester", allSpPermissions = true) @Description("Tests GET request on /rest/v1/softwaremodules/{smId}.") public void getSoftareModule() throws Exception { - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1"); os = softwareManagement.createSoftwareModule(os); @@ -771,15 +739,13 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo .andExpect(jsonPath("$_links.artifacts.href", equalTo("http://localhost/rest/v1/softwaremodules/" + ah.getId() + "/artifacts"))); - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3); + assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Softwaremodule size is wrong").hasSize(3); } @Test @WithUser(principal = "uploadTester", allSpPermissions = true) @Description("Verfies that the create request actually results in the creation of the modules in the repository.") public void createSoftwareModules() throws JSONException, Exception { - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); - final SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1"); final SoftwareModule jvm = new SoftwareModule(runtimeType, "name2", "version1", "description1", "vendor1"); final SoftwareModule ah = new SoftwareModule(appType, "name3", "version1", "description1", "vendor1"); @@ -824,74 +790,75 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo assertThat( JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) + .as("Response contains invalid self href") .isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId()); assertThat(JsonPath.compile("[0]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString()) - .toString()).isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId() + "/artifacts"); + .toString()).as("Response contains invalid artifacts href") + .isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId() + "/artifacts"); assertThat( JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) + .as("Response contains invalid self href") .isEqualTo("http://localhost/rest/v1/softwaremodules/" + jvmCreated.getId()); assertThat(JsonPath.compile("[1]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString()) - .toString()).isEqualTo("http://localhost/rest/v1/softwaremodules/" + jvmCreated.getId() + "/artifacts"); + .toString()).as("Response contains invalid artfacts href") + .isEqualTo("http://localhost/rest/v1/softwaremodules/" + jvmCreated.getId() + "/artifacts"); assertThat( JsonPath.compile("[2]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) + .as("Response contains links self href") .isEqualTo("http://localhost/rest/v1/softwaremodules/" + ahCreated.getId()); assertThat(JsonPath.compile("[2]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString()) - .toString()).isEqualTo("http://localhost/rest/v1/softwaremodules/" + ahCreated.getId() + "/artifacts"); + .toString()).as("Response contains invalid artifacts href") + .isEqualTo("http://localhost/rest/v1/softwaremodules/" + ahCreated.getId() + "/artifacts"); - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3); + assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Wrong softwaremodule size").hasSize(3); assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getName()) - .isEqualTo(os.getName()); + .as("Softwaremoudle name is wrong").isEqualTo(os.getName()); assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getCreatedBy()) - .isEqualTo("uploadTester"); + .as("Softwaremoudle created by is wrong").isEqualTo("uploadTester"); assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getCreatedAt()) - .isGreaterThanOrEqualTo(current); + .as("Softwaremoudle created at is wrong").isGreaterThanOrEqualTo(current); assertThat(softwareManagement.findSoftwareModulesByType(pageReq, runtimeType).getContent().get(0).getName()) - .isEqualTo(jvm.getName()); + .as("Softwaremoudle name is wrong").isEqualTo(jvm.getName()); assertThat(softwareManagement.findSoftwareModulesByType(pageReq, appType).getContent().get(0).getName()) - .isEqualTo(ah.getName()); + .as("Softwaremoudle name is wrong").isEqualTo(ah.getName()); } @Test @Description("Verifies successfull deletion of software modules that are not in use, i.e. assigned to a DS.") public void deleteUnassignedSoftwareModule() throws Exception { - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).isEmpty(); - assertThat(artifactRepository.findAll()).isEmpty(); SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); final byte random[] = RandomStringUtils.random(5 * 1024).getBytes(); - final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), - "file1", false); + artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file1", false); - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1); - assertThat(artifactRepository.findAll()).hasSize(1); - assertThat(softwareModuleRepository.findAll()).hasSize(1); + assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Softwaremoudle size is wrong").hasSize(1); + assertThat(artifactRepository.findAll()).as("artifact site is wrong").hasSize(1); + assertThat(softwareModuleRepository.findAll()).as("Softwaremoudle size is wrong").hasSize(1); mvc.perform(delete("/rest/v1/softwaremodules/{smId}", sm.getId())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).isEmpty(); - assertThat(softwareModuleRepository.findAll()).isEmpty(); - assertThat(artifactRepository.findAll()).isEmpty(); + assertThat(softwareManagement.findSoftwareModulesAll(pageReq)) + .as("After delete no softwarmodule should be available").isEmpty(); + assertThat(softwareModuleRepository.findAll()).as("After delete no softwarmodule should be available") + .isEmpty(); + assertThat(artifactRepository.findAll()).as("After delete no artifact should be available").isEmpty(); } @Test @Description("Verifies successfull deletion of software modules that are in use, i.e. assigned to a DS which should result in movinf the module to the archive.") public void deleteAssignedSoftwareModule() throws Exception { - // check baseline - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).isEmpty(); - assertThat(artifactRepository.findAll()).isEmpty(); - final DistributionSet ds1 = TestDataUtil.generateDistributionSet("a", softwareManagement, distributionSetManagement); final byte random[] = RandomStringUtils.random(5 * 1024).getBytes(); - final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), + artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), ds1.findFirstModuleByType(appType).getId(), "file1", false); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3); @@ -906,17 +873,17 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); // all 3 are now marked as deleted - assertThat(softwareManagement.findSoftwareModulesAll(pageReq).getNumber()).isEqualTo(0); - assertThat(softwareModuleRepository.findAll()).hasSize(3); - assertThat(artifactRepository.findAll()).hasSize(1); + assertThat(softwareManagement.findSoftwareModulesAll(pageReq).getNumber()) + .as("After delete no softwarmodule should be available").isEqualTo(0); + assertThat(softwareModuleRepository.findAll()).as("After delete no softwarmodule should marked as deleted") + .hasSize(3); + assertThat(artifactRepository.findAll()).as("After delete artifact should available for marked as deleted sm's") + .hasSize(1); } @Test @Description("Tests the deletion of an artifact including verfication that the artifact is actually erased in the repository and removed from the software module.") public void deleteArtifact() throws Exception { - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).isEmpty(); - assertThat(artifactRepository.findAll()).isEmpty(); - // Create 1 SM SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null); sm = softwareManagement.createSoftwareModule(sm); @@ -926,8 +893,7 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo // Create 2 artifacts final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file1", false); - final LocalArtifact artifact2 = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), - sm.getId(), "file2", false); + artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file2", false); // check repo before delete assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1); @@ -940,9 +906,12 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); // check that only one artifact is still alive and still assigned - assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1); - assertThat(artifactRepository.findAll()).hasSize(1); - assertThat(softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts()).hasSize(1); + assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("After the sm should be marked as deleted") + .hasSize(1); + assertThat(artifactRepository.findAll()).as("After delete artifact should available for marked as deleted sm's") + .hasSize(1); + assertThat(softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts()) + .as("After delete artifact should available for marked as deleted sm's").hasSize(1); } @@ -972,8 +941,8 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo final SoftwareModuleMetadata metaKey1 = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey1)); final SoftwareModuleMetadata metaKey2 = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey2)); - assertThat(metaKey1.getValue()).isEqualTo(knownValue1); - assertThat(metaKey2.getValue()).isEqualTo(knownValue2); + assertThat(metaKey1.getValue()).as("Metadata key is wrong").isEqualTo(knownValue1); + assertThat(metaKey2.getValue()).as("Metadata key is wrong").isEqualTo(knownValue2); } @Test @@ -997,7 +966,7 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo .andExpect(jsonPath("key", equalTo(knownKey))).andExpect(jsonPath("value", equalTo(updateValue))); final SoftwareModuleMetadata assertDS = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey)); - assertThat(assertDS.getValue()).isEqualTo(updateValue); + assertThat(assertDS.getValue()).as("Metadata is wrong").isEqualTo(updateValue); } @Test diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/model/PagedListTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/model/PagedListTest.java index 0c47856dd..4a88bf43e 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/model/PagedListTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/model/PagedListTest.java @@ -29,10 +29,13 @@ public class PagedListTest { knownContentList.add("content1"); knownContentList.add("content2"); - final PagedList pagedList = new PagedList<>(knownContentList, knownTotal); + assertListSize(knownTotal, knownContentList); + } - assertThat(pagedList.getTotal()).isEqualTo(knownTotal); - assertThat(pagedList.getSize()).isEqualTo(knownContentList.size()); + private void assertListSize(final long knownTotal, final List knownContentList) { + final PagedList pagedList = new PagedList<>(knownContentList, knownTotal); + assertThat(pagedList.getTotal()).as("total size is wrong").isEqualTo(knownTotal); + assertThat(pagedList.getSize()).as("list size is wrong").isEqualTo(knownContentList.size()); } @Test @@ -42,9 +45,7 @@ public class PagedListTest { knownContentList.add("content1"); knownContentList.add("content2"); - final PagedList pagedList = new PagedList<>(knownContentList, knownTotal); - assertThat(pagedList.getTotal()).isEqualTo(knownTotal); - assertThat(pagedList.getSize()).isEqualTo(knownContentList.size()); + assertListSize(knownTotal, knownContentList); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java index 1610a2de8..8982be759 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java @@ -78,7 +78,7 @@ public class TargetTagToken extends AbstractTargetTagToken { } private TargetTagAssigmentResult toggleAssignment(final String tagNameSelected) { - final Set targetList = new HashSet(); + final Set targetList = new HashSet<>(); targetList.add(selectedTarget.getControllerId()); final TargetTagAssigmentResult result = targetManagement.toggleTagAssignment(targetList, tagNameSelected); uinotification.displaySuccess(HawkbitCommonUtil.getTargetTagAssigmentMsg(tagNameSelected, result, i18n)); @@ -102,7 +102,7 @@ public class TargetTagToken extends AbstractTargetTagToken { /* To Be Done : this implementation will vary in views */ private List getClickedTagList() { - return new ArrayList(); + return new ArrayList<>(); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java index 8f91bf336..c0f681c7a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java @@ -107,32 +107,15 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin super.inittialize(); } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.confirmwindow.layout. - * AbstractConfirmationWindowLayout# getConfimrationTabs() - */ @Override protected Map getConfimrationTabs() { - final Map tabs = new HashMap(); - /** - * create tab for deleted distribution. - */ - - /* Create tab for SW Module Type delete */ + final Map tabs = new HashMap<>(); if (!managementUIState.getDeletedDistributionList().isEmpty()) { tabs.put(i18n.get("caption.delete.dist.accordion.tab"), createDeletedDistributionTab()); } - /** - * create tab for deleted target. - */ if (!managementUIState.getDeletedTargetList().isEmpty()) { tabs.put(i18n.get("caption.delete.target.accordion.tab"), createDeletedTargetTab()); } - /** - * create tab for assignment. - */ if (!managementUIState.getAssignedList().isEmpty()) { tabs.put(i18n.get("caption.assign.dist.accordion.tab"), createAssignmentTab()); } @@ -196,8 +179,8 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin private void saveAllAssignments(final ConfirmationTab tab) { final Set itemIds = managementUIState.getAssignedList().keySet(); Long distId; - List targetIdSetList = null; - List tempIdList = null; + List targetIdSetList; + List tempIdList; final ActionType actionType = ((ActionTypeOptionGroupLayout.ActionTypeOption) actionTypeOptionGroupLayout .getActionTypeOptionGroup().getValue()).getActionType(); final long forcedTimeStamp = (((ActionTypeOptionGroupLayout.ActionTypeOption) actionTypeOptionGroupLayout @@ -205,7 +188,7 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin ? actionTypeOptionGroupLayout.getForcedTimeDateField().getValue().getTime() : Action.NO_FORCE_TIME; - final Map> saveAssignedList = new HashMap>(); + final Map> saveAssignedList = new HashMap<>(); int successAssignmentCount = 0; int duplicateAssignmentCount = 0; @@ -216,7 +199,7 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin if (saveAssignedList.containsKey(distId)) { targetIdSetList = saveAssignedList.get(distId); } else { - targetIdSetList = new ArrayList(); + targetIdSetList = new ArrayList<>(); } targetIdSetList.add(itemId); saveAssignedList.put(distId, (ArrayList) targetIdSetList); @@ -275,15 +258,13 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin } private String getAssigmentSuccessMessage(final int assignedCount) { - final String assignment = FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE + return FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE + i18n.get("message.target.assignment", new Object[] { assignedCount }); - return assignment; } private String getDuplicateAssignmentMessage(final int alreadyAssignedCount) { - final String alreadyAssigned = FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE + return FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE + i18n.get("message.target.alreadyAssigned", new Object[] { alreadyAssignedCount }); - return alreadyAssigned; } private void discardAllAssignments(final ConfirmationTab tab) { @@ -456,7 +437,7 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin } private void deleteAllDistributions(final ConfirmationTab tab) { - final Set deletedIds = new HashSet(); + final Set deletedIds = new HashSet<>(); managementUIState.getDeletedDistributionList().forEach(distIdName -> deletedIds.add(distIdName.getId())); distributionSetManagement.deleteDistributionSet(deletedIds.toArray(new Long[deletedIds.size()])); addToConsolitatedMsg(FontAwesome.TRASH_O.getHtml() + SPUILabelDefinitions.HTML_SPACE @@ -516,7 +497,7 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin final IndexedContainer contactContainer = new IndexedContainer(); contactContainer.addContainerProperty(TARGET_ID, String.class, ""); contactContainer.addContainerProperty(TARGET_NAME, String.class, ""); - Item item = null; + Item item; for (final TargetIdName targteId : managementUIState.getDeletedTargetList()) { item = contactContainer.addItem(targteId); item.getItemProperty(TARGET_ID).setValue(targteId.getControllerId()); From 229e7c54af239fb1b7476ec1b7dce14e63bb023d Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 2 Mar 2016 07:33:22 +0100 Subject: [PATCH 12/14] introduce a push strategy to the HawkbitUI and a delayed push implementation to avoid UI freezes when too many events are dispatched to the UI Signed-off-by: Michael Hirsch --- .../java/org/eclipse/hawkbit/app/MyUI.java | 50 +--- .../org/eclipse/hawkbit/ui/HawkbitUI.java | 82 ++---- .../ui/push/DelayedEventBusPushStrategy.java | 245 ++++++++++++++++++ .../hawkbit/ui/push/EventPushStrategy.java | 35 +++ 4 files changed, 307 insertions(+), 105 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java diff --git a/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyUI.java b/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyUI.java index cafe0749d..e55cb02d2 100644 --- a/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyUI.java +++ b/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyUI.java @@ -8,21 +8,12 @@ */ package org.eclipse.hawkbit.app; -import org.eclipse.hawkbit.eventbus.EventSubscriber; -import org.eclipse.hawkbit.eventbus.event.EntityEvent; -import org.eclipse.hawkbit.ui.DispatcherRunnable; import org.eclipse.hawkbit.ui.HawkbitUI; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.vaadin.spring.events.EventBus.SessionEventBus; +import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy; +import org.springframework.beans.factory.annotation.Autowired; -import com.google.common.eventbus.AllowConcurrentEvents; -import com.google.common.eventbus.Subscribe; +import com.google.common.eventbus.EventBus; import com.vaadin.annotations.Push; -import com.vaadin.server.VaadinSession; -import com.vaadin.server.VaadinSession.State; -import com.vaadin.server.WrappedSession; import com.vaadin.shared.communication.PushMode; import com.vaadin.shared.ui.ui.Transport; import com.vaadin.spring.annotation.SpringUI; @@ -33,45 +24,16 @@ import com.vaadin.spring.annotation.SpringUI; * A {@link SpringUI} annotated class must be present in the classpath. The * easiest way to get an hawkBit UI running is to extend the {@link HawkbitUI} * and to annotated it with {@link SpringUI} as in this example. - * - * * */ @SpringUI @Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET) -@EventSubscriber public class MyUI extends HawkbitUI { private static final long serialVersionUID = 1L; - /** - * An {@link com.google.common.eventbus.EventBus} subscriber which - * subscribes {@link EntityEvent} from the repository to dispatch these - * events to the UI {@link SessionEventBus}. - * - * @param event - * the entity event which has been published from the repository - */ - @Override - @Subscribe - @AllowConcurrentEvents - public void dispatch(final org.eclipse.hawkbit.eventbus.event.Event event) { - final VaadinSession session = getSession(); - if (session != null && session.getState() == State.OPEN) { - final WrappedSession wrappedSession = session.getSession(); - if (wrappedSession != null) { - final SecurityContext userContext = (SecurityContext) wrappedSession - .getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); - if (eventSecurityCheck(userContext, event)) { - final SecurityContext oldContext = SecurityContextHolder.getContext(); - try { - access(new DispatcherRunnable(eventBus, session, userContext, event)); - } finally { - SecurityContextHolder.setContext(oldContext); - } - } - } - } + @Autowired + public MyUI(final EventBus systemEventBus, final org.vaadin.spring.events.EventBus.SessionEventBus eventBus) { + super(new DelayedEventBusPushStrategy(eventBus, systemEventBus)); } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java index d352211f6..2be62db1d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java @@ -14,12 +14,11 @@ import java.util.Set; import javax.servlet.http.Cookie; -import org.eclipse.hawkbit.eventbus.event.EntityEvent; -import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.ui.components.SPUIErrorHandler; import org.eclipse.hawkbit.ui.menu.DashboardEvent.PostViewChangeEvent; import org.eclipse.hawkbit.ui.menu.DashboardMenu; import org.eclipse.hawkbit.ui.menu.DashboardMenuItem; +import org.eclipse.hawkbit.ui.push.EventPushStrategy; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SpringContextHelper; @@ -28,14 +27,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import org.vaadin.spring.events.EventBus; -import org.vaadin.spring.events.EventBus.SessionEventBus; -import com.google.common.eventbus.AllowConcurrentEvents; -import com.google.common.eventbus.Subscribe; import com.vaadin.annotations.Title; import com.vaadin.navigator.Navigator; import com.vaadin.navigator.View; @@ -45,9 +38,6 @@ import com.vaadin.server.ClientConnector.DetachListener; import com.vaadin.server.Responsive; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinService; -import com.vaadin.server.VaadinSession; -import com.vaadin.server.VaadinSession.State; -import com.vaadin.server.WrappedSession; import com.vaadin.spring.navigator.SpringViewProvider; import com.vaadin.ui.Component; import com.vaadin.ui.CssLayout; @@ -71,6 +61,8 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { private static final String EMPTY_VIEW = ""; + private EventPushStrategy pushStrategy; + @Autowired private SpringViewProvider viewProvider; @@ -92,69 +84,37 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { protected transient EventBus.SessionEventBus eventBus; /** - * An {@link com.google.common.eventbus.EventBus} subscriber which - * subscribes {@link EntityEvent} from the repository to dispatch these - * events to the UI {@link SessionEventBus}. - * - * @param event - * the entity event which has been published from the repository + * Default constructor. */ - @Subscribe - @AllowConcurrentEvents - public void dispatch(final org.eclipse.hawkbit.eventbus.event.Event event) { - final VaadinSession session = getSession(); - if (session == null || session.getState() != State.OPEN) { - return; - } - - final WrappedSession wrappedSession = session.getSession(); - if (wrappedSession == null) { - return; - } - - final SecurityContext userContext = (SecurityContext) wrappedSession - .getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); - if (!eventSecurityCheck(userContext, event)) { - return; - } - - final SecurityContext oldContext = SecurityContextHolder.getContext(); - try { - access(new DispatcherRunnable(eventBus, session, userContext, event)); - } finally { - SecurityContextHolder.setContext(oldContext); - } - + public HawkbitUI() { + // is empty, is ok. } - protected boolean eventSecurityCheck(final SecurityContext userContext, - final org.eclipse.hawkbit.eventbus.event.Event event) { - if (userContext != null && userContext.getAuthentication() != null) { - final Object tenantAuthenticationDetails = userContext.getAuthentication().getDetails(); - if (tenantAuthenticationDetails instanceof TenantAwareAuthenticationDetails) { - return ((TenantAwareAuthenticationDetails) tenantAuthenticationDetails).getTenant() - .equalsIgnoreCase(event.getTenant()); - } - } - return false; + /** + * Constructor taking the push strategy. + * + * @param pushStrategy + * the strategy to push events from the backend to the UI + */ + public HawkbitUI(final EventPushStrategy pushStrategy) { + this.pushStrategy = pushStrategy; } - /* - * (non-Javadoc) - * - * @see - * com.vaadin.server.ClientConnector.DetachListener#detach(com.vaadin.server - * .ClientConnector. DetachEvent) - */ @Override public void detach(final DetachEvent event) { LOG.info("ManagementUI is detached uiid - {}", getUIId()); - + eventBus.unsubscribe(this); + if (pushStrategy != null) { + pushStrategy.clean(); + } } @Override protected void init(final VaadinRequest vaadinRequest) { LOG.info("ManagementUI init starts uiid - {}", getUI().getUIId()); + if (pushStrategy != null) { + pushStrategy.init(getUI()); + } addDetachListener(this); SpringContextHelper.setContext(context); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java new file mode 100644 index 000000000..d54bce409 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java @@ -0,0 +1,245 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.push; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import org.eclipse.hawkbit.eventbus.event.DistributionSetTagCreatedBulkEvent; +import org.eclipse.hawkbit.eventbus.event.EntityEvent; +import org.eclipse.hawkbit.eventbus.event.RolloutChangeEvent; +import org.eclipse.hawkbit.eventbus.event.RolloutGroupChangeEvent; +import org.eclipse.hawkbit.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; +import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.eventbus.event.TargetTagCreatedBulkEvent; +import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.vaadin.spring.events.EventBus; +import org.vaadin.spring.events.EventBus.SessionEventBus; + +import com.google.common.collect.Sets; +import com.google.common.eventbus.AllowConcurrentEvents; +import com.google.common.eventbus.Subscribe; +import com.vaadin.server.VaadinSession; +import com.vaadin.server.VaadinSession.State; +import com.vaadin.server.WrappedSession; +import com.vaadin.ui.UI; + +/** + * A {@link EventPushStrategy} implementation which retrieves events from + * {@link com.google.common.eventbus.EventBus} and store them first in an queue + * where they will dispatched every 2 seconds to the {@link EventBus} in a + * Vaadin access thread {@link UI#access(Runnable)}. + * + * This strategy avoids blocking UIs when too many events are fired and + * dispatched to the UI thread. The UI will freeze in the time. To avoid that + * all events are collected first and same events are merged to a list of events + * before they dispatched to the UI thread. + * + * The strategy also verifies the current tenant in the session with the tenant + * in the event and only forwards event from the right tenant to the UI. + * + * @author Michael Hirsch + * + */ +public class DelayedEventBusPushStrategy implements EventPushStrategy { + + private static final Logger LOG = LoggerFactory.getLogger(DelayedEventBusPushStrategy.class); + + private static final int BLOCK_SIZE = 10_000; + private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + private final BlockingDeque queue = new LinkedBlockingDeque<>(BLOCK_SIZE); + private final EventBus.SessionEventBus eventBus; + private final com.google.common.eventbus.EventBus systemEventBus; + + private ScheduledFuture jobHandle; + + /** + * only events defined in the set are dispatched to the session event bus. + */ + private static final Set> UI_EVENTS = Sets.newHashSet(TargetInfoUpdateEvent.class, + TargetCreatedEvent.class, TargetDeletedEvent.class, RolloutChangeEvent.class, RolloutGroupChangeEvent.class, + TargetTagCreatedBulkEvent.class, DistributionSetTagCreatedBulkEvent.class); + + /** + * Constructor. + * + * @param eventBus + * the session event bus to where the events should be dispatched + * @param systemEventBus + * the system event bus where to retrieve the events from the + * back-end + */ + public DelayedEventBusPushStrategy(final SessionEventBus eventBus, + final com.google.common.eventbus.EventBus systemEventBus) { + this.eventBus = eventBus; + this.systemEventBus = systemEventBus; + } + + /** + * An {@link com.google.common.eventbus.EventBus} subscriber which + * subscribes {@link EntityEvent} from the repository to dispatch these + * events to the UI {@link SessionEventBus}. + * + * @param event + * the entity event which has been published from the repository + */ + @Subscribe + @AllowConcurrentEvents + public void dispatch(final org.eclipse.hawkbit.eventbus.event.Event event) { + // to dispatch too many events which are not interested on the UI + if (UI_EVENTS.contains(event.getClass()) && !queue.offer(event)) { + LOG.warn("Deque limit is reached, cannot add more events!!! Dropped event is {}", event); + return; + } + } + + @Override + public void init(final UI vaadinUI) { + LOG.debug("Initialize delayed event push strategy"); + jobHandle = executorService.scheduleWithFixedDelay(new DispatchRunnable(vaadinUI, vaadinUI.getSession()), 500, + 2000, TimeUnit.MILLISECONDS); + systemEventBus.register(this); + } + + @Override + public void clean() { + LOG.debug("Cleanup resources"); + jobHandle.cancel(true); + systemEventBus.unregister(this); + executorService.shutdownNow(); + queue.clear(); + } + + /** + * Checks if the tenant within the event is equal with the current tenant in + * the context. + * + * @param userContext + * the security context of the current session + * @param event + * the event to dispatch to the UI + * @return {@code true} if the event can be dispatched to the UI otherwise + * {@code false} + */ + protected boolean eventSecurityCheck(final SecurityContext userContext, + final org.eclipse.hawkbit.eventbus.event.Event event) { + if (userContext != null && userContext.getAuthentication() != null) { + final Object tenantAuthenticationDetails = userContext.getAuthentication().getDetails(); + if (tenantAuthenticationDetails instanceof TenantAwareAuthenticationDetails) { + return ((TenantAwareAuthenticationDetails) tenantAuthenticationDetails).getTenant() + .equalsIgnoreCase(event.getTenant()); + } + } + return false; + } + + private final class DispatchRunnable implements Runnable { + + private final UI vaadinUI; + private final VaadinSession vaadinSession; + + private DispatchRunnable(final UI ui, final VaadinSession session) { + vaadinUI = ui; + vaadinSession = session; + } + + @Override + public void run() { + LOG.debug("UI EventBus aggregator started"); + final long timestamp = System.currentTimeMillis(); + final List events = new LinkedList<>(); + for (int i = 0; i < BLOCK_SIZE; i++) { + final org.eclipse.hawkbit.eventbus.event.Event pollEvent = queue.poll(); + if (pollEvent == null) { + continue; + } + events.add(pollEvent); + } + + if (events.isEmpty()) { + return; + } + + if (vaadinSession == null) { + return; + } + + LOG.debug("UI EventBus aggregator session: {}", vaadinSession); + + final WrappedSession wrappedSession = vaadinSession.getSession(); + if (wrappedSession == null) { + return; + } + + final int eventsSize = events.size(); + + doDispatch(events, wrappedSession); + + LOG.debug("UI EventBus aggregator done with sending {} events in {} ms", eventsSize, + System.currentTimeMillis() - timestamp); + + } + + private void doDispatch(final List events, + final WrappedSession wrappedSession) { + final SecurityContext userContext = (SecurityContext) wrappedSession + .getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); + final SecurityContext oldContext = SecurityContextHolder.getContext(); + try { + SecurityContextHolder.setContext(userContext); + vaadinUI.access(() -> { + if (vaadinSession.getState() != State.OPEN) { + return; + } + fowardEvents(events, userContext); + + // send a list of events, because ui performance issues + publishEventAsList(events, userContext, TargetInfoUpdateEvent.class); + publishEventAsList(events, userContext, TargetCreatedEvent.class); + publishEventAsList(events, userContext, TargetDeletedEvent.class); + }); + } finally { + SecurityContextHolder.setContext(oldContext); + } + } + + private void publishEventAsList(final List events, + final SecurityContext userContext, final Class eventType) { + final List bulkEvents = events.stream() + .filter(event -> DelayedEventBusPushStrategy.this.eventSecurityCheck(userContext, event) + && eventType.isInstance(event)) + .collect(Collectors.toList()); + if (bulkEvents.isEmpty()) { + return; + } + eventBus.publish(vaadinUI, bulkEvents); + } + + private void fowardEvents(final List events, + final SecurityContext userContext) { + events.stream().filter(event -> DelayedEventBusPushStrategy.this.eventSecurityCheck(userContext, event)) + .forEach(event -> eventBus.publish(vaadinUI, event)); + } + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java new file mode 100644 index 000000000..55e3b367d --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.push; + +import com.vaadin.ui.UI; + +/** + * Interface declaring a strategy to push events from the back-end to the UI. + * + * @author Michael Hirsch + * + */ +public interface EventPushStrategy { + + /** + * Initialize the event push strategy, this is bound to the life-cycle of + * the {@link UI} so the strategy can be initialized based a {@link UI}. + * + * @param vaadinUI + * the {@link UI} + */ + void init(UI vaadinUI); + + /** + * Cleans up resources when the strategy is not be used anymore e.g. + * {@link UI#detach()}. + */ + void clean(); +} From 5efcc295bce4fa8720bea7387374a019584d45b2 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 2 Mar 2016 09:00:10 +0100 Subject: [PATCH 13/14] clean code do early return. Signed-off-by: Michael Hirsch --- .../ui/push/DelayedEventBusPushStrategy.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java index d54bce409..9ebfcdefd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java @@ -143,12 +143,13 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy { */ protected boolean eventSecurityCheck(final SecurityContext userContext, final org.eclipse.hawkbit.eventbus.event.Event event) { - if (userContext != null && userContext.getAuthentication() != null) { - final Object tenantAuthenticationDetails = userContext.getAuthentication().getDetails(); - if (tenantAuthenticationDetails instanceof TenantAwareAuthenticationDetails) { - return ((TenantAwareAuthenticationDetails) tenantAuthenticationDetails).getTenant() - .equalsIgnoreCase(event.getTenant()); - } + if (userContext == null || userContext.getAuthentication() == null) { + return false; + } + final Object tenantAuthenticationDetails = userContext.getAuthentication().getDetails(); + if (tenantAuthenticationDetails instanceof TenantAwareAuthenticationDetails) { + return ((TenantAwareAuthenticationDetails) tenantAuthenticationDetails).getTenant() + .equalsIgnoreCase(event.getTenant()); } return false; } From d28ea67e89ff34dca8748575a853c60625c9bc13 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 2 Mar 2016 11:25:43 +0100 Subject: [PATCH 14/14] remove author tag from javadoc Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java | 2 -- .../java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java index 9ebfcdefd..87fcbe922 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/DelayedEventBusPushStrategy.java @@ -58,8 +58,6 @@ import com.vaadin.ui.UI; * The strategy also verifies the current tenant in the session with the tenant * in the event and only forwards event from the right tenant to the UI. * - * @author Michael Hirsch - * */ public class DelayedEventBusPushStrategy implements EventPushStrategy { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java index 55e3b367d..504dece60 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/push/EventPushStrategy.java @@ -12,8 +12,6 @@ import com.vaadin.ui.UI; /** * Interface declaring a strategy to push events from the back-end to the UI. - * - * @author Michael Hirsch * */ public interface EventPushStrategy {